diff --git a/Data/Scripts/002_Save data/005_Game_SaveConversions.rb b/Data/Scripts/002_Save data/005_Game_SaveConversions.rb index b0649ea5d..10fa0e720 100644 --- a/Data/Scripts/002_Save data/005_Game_SaveConversions.rb +++ b/Data/Scripts/002_Save data/005_Game_SaveConversions.rb @@ -2,7 +2,7 @@ SaveData.register_conversion(:v19_2_fix_berry_plants) do essentials_version 19.2 - display_title 'Fixing berry plant data' + display_title 'Fixing berry plant IDs data' to_value :global_metadata do |global| berry_conversion = { 389 => :CHERIBERRY, @@ -76,8 +76,8 @@ SaveData.register_conversion(:v19_2_fix_berry_plants) do 61 => :STABLEMULCH, 62 => :GOOEYMULCH } - global.eventvars.each do |var| - next if !var || !var.ia_a?(Array) + global.eventvars.each_value do |var| + next if !var || !var.is_a?(Array) next if var.length < 6 || var.length > 8 # Neither old nor new berry plant if !var[1].is_a?(Symbol) # Planted berry item var[1] = berry_conversion[var[1]] || :ORANBERRY @@ -89,6 +89,47 @@ SaveData.register_conversion(:v19_2_fix_berry_plants) do end end +SaveData.register_conversion(:v20_berry_plant_data) do + essentials_version 20 + display_title 'Updating berry plant data format' + to_value :global_metadata do |global| + if global.eventvars + global.eventvars.each_pair do |key, value| + next if !value || !value.is_a?(Array) + if value.length == 6 # Old berry plant data + data = BerryPlantData.new + if value[1]&.is_a?(Symbol) + plant_data = GameData::DerryPlant.get(value[1]) + data.new_mechanics = false + data.berry_id = value[1] + data.time_alive = value[0] * plant_data.hours_per_stage * 3600 + data.time_last_updated = value[3] + data.growth_stage = value[0] + data.replant_count = value[5] + data.watered_this_stage = value[2] + data.watering_count = value[4] + end + global.eventvars[key] = data + elsif value.length == 7 || value.length == 8 # New berry plant data + data = BerryPlantData.new + if value[1]&.is_a?(Symbol) + data.new_mechanics = true + data.berry_id = value[1] + data.mulch_id = value[7] if value[7]&.is_a?(Symbol) + data.time_alive = value[2] + data.time_last_updated = value[3] + data.growth_stage = value[0] + data.replant_count = value[5] + data.moisture_level = value[4] + data.yield_penalty = value[6] + end + global.eventvars[key] = data + end + end + end + end +end + SaveData.register_conversion(:v20_add_battled_counts) do essentials_version 20 display_title 'Adding Pokédex battle counts' diff --git a/Data/Scripts/003_Game processing/002_Scene_Map.rb b/Data/Scripts/003_Game processing/002_Scene_Map.rb index 097f25e1a..03021569b 100644 --- a/Data/Scripts/003_Game processing/002_Scene_Map.rb +++ b/Data/Scripts/003_Game processing/002_Scene_Map.rb @@ -7,7 +7,8 @@ class Scene_Map attr_reader :spritesetGlobal attr_reader :map_renderer - def spriteset + def spriteset(map_id = -1) + return @spritesets[map_id] if map_id > 0 && @spritesets[map_id] for i in @spritesets.values return i if i.map==$game_map end diff --git a/Data/Scripts/005_Sprites/008_Sprite_AnimationSprite.rb b/Data/Scripts/005_Sprites/008_Sprite_AnimationSprite.rb index 8d904f0f5..0713535b5 100644 --- a/Data/Scripts/005_Sprites/008_Sprite_AnimationSprite.rb +++ b/Data/Scripts/005_Sprites/008_Sprite_AnimationSprite.rb @@ -51,7 +51,7 @@ class Spriteset_Map end def addUserAnimation(animID,x,y,tinting=false,height=3) - sprite=AnimationSprite.new(animID,$game_map,x,y,@@viewport1,tinting,height) + sprite=AnimationSprite.new(animID,self.map,x,y,@@viewport1,tinting,height) addUserSprite(sprite) return sprite end diff --git a/Data/Scripts/010_Data/002_PBS data/007_BerryPlant.rb b/Data/Scripts/010_Data/002_PBS data/007_BerryPlant.rb index d7b43bfd3..c0cb001bd 100644 --- a/Data/Scripts/010_Data/002_PBS data/007_BerryPlant.rb +++ b/Data/Scripts/010_Data/002_PBS data/007_BerryPlant.rb @@ -9,7 +9,10 @@ module GameData DATA = {} DATA_FILENAME = "berry_plants.dat" - NUMBER_OF_REPLANTS = 9 + NUMBER_OF_REPLANTS = 9 + NUMBER_OF_GROWTH_STAGES = 4 + NUMBER_OF_FULLY_GROWN_STAGES = 4 + WATERING_CANS = [:SPRAYDUCK, :SQUIRTBOTTLE, :WAILMERPAIL, :SPRINKLOTAD] extend ClassMethodsSymbols include InstanceMethods diff --git a/Data/Scripts/012_Overworld/006_Overworld_BerryPlants.rb b/Data/Scripts/012_Overworld/006_Overworld_BerryPlants.rb index 48a0c45d0..4a75ca442 100644 --- a/Data/Scripts/012_Overworld/006_Overworld_BerryPlants.rb +++ b/Data/Scripts/012_Overworld/006_Overworld_BerryPlants.rb @@ -1,544 +1,461 @@ -Events.onSpritesetCreate += proc { |_sender,e| - spriteset = e[0] - viewport = e[1] - map = spriteset.map - for i in map.events.keys - if map.events[i].name[/berryplant/i] - spriteset.addUserSprite(BerryPlantMoistureSprite.new(map.events[i],map,viewport)) - spriteset.addUserSprite(BerryPlantSprite.new(map.events[i],map,viewport)) +#=============================================================================== +# Represents a planted berry. Stored in $PokemonGlobal.eventvars. +#=============================================================================== +class BerryPlantData + attr_accessor :new_mechanics # false for Gen 3, true for Gen 4 + attr_accessor :berry_id + attr_accessor :mulch_id # Gen 4 mechanics + attr_accessor :time_alive + attr_accessor :time_last_updated + attr_accessor :growth_stage + attr_accessor :replant_count + attr_accessor :watered_this_stage # Gen 3 mechanics + attr_accessor :watering_count # Gen 3 mechanics + attr_accessor :moisture_level # Gen 4 mechanics + attr_accessor :yield_penalty # Gen 4 mechanics + + def initialize + reset + end + + def reset(planting = false) + @new_mechanics = Settings::NEW_BERRY_PLANTS + @berry_id = nil + @mulch_id = nil if !planting + @time_alive = 0 + @time_last_updated = 0 + @growth_stage = 0 + @replant_count = 0 + @watered_this_stage = false + @watering_count = 0 + @moisture_level = 100 + @yield_penalty = 0 + end + + def plant(berry_id) + reset(true) + @berry_id = berry_id + @growth_stage = 1 + @time_last_updated = pbGetTimeNow.to_i + end + + def replant + @time_alive = 0 + @growth_stage = 2 + @replant_count += 1 + @watered_this_stage = false + @watering_count = 0 + @moisture_level = 100 + @yield_penalty = 0 + end + + def planted? + return @growth_stage > 0 + end + + def growing? + return @growth_stage > 0 && @growth_stage < 5 + end + + def grown? + return @growth_stage >= 5 + end + + def replanted? + return @replant_count > 0 + end + + def moisture_stage + return 0 if !@new_mechanics + return 2 if @moisture_level > 50 + return 1 if @moisture_level > 0 + return 0 + end + + def water + @moisture_level = 100 + if !@watered_this_stage + @watered_this_stage = true + @watering_count += 1 end end -} + def berry_yield + data = GameData::BerryPlant.get(@berry_id) + if @new_mechanics + return [data.maximum_yield * (5 - @yield_penalty) / 5, data.minimum_yield].max + else + if @watering_count > 0 + ret = (data.maximum_yield - data.minimum_yield) * (@watering_count - 1) + ret += rand(1 + data.maximum_yield - data.minimum_yield) + return (ret / 4) + data.minimum_yield + else + return data.minimum_yield + end + end + end + # Old mechanics only update a plant when its map is loaded. New mechanics + # update it every frame while its map is loaded. + def update + return if !planted? + time_now = pbGetTimeNow + time_delta = time_now.to_i - @time_last_updated + return if time_delta <= 0 + new_time_alive = @time_alive + time_delta + # Get all growth data + plant_data = GameData::BerryPlant.get(@berry_id) + time_per_stage = plant_data.hours_per_stage * 3600 # In seconds + drying_per_hour = plant_data.drying_per_hour + max_replants = GameData::BerryPlant::NUMBER_OF_REPLANTS + stages_growing = GameData::BerryPlant::NUMBER_OF_GROWTH_STAGES + stages_fully_grown = GameData::BerryPlant::NUMBER_OF_FULLY_GROWN_STAGES + case @mulch_id + when :GROWTHMULCH + time_per_stage = (time_per_stage * 0.75).to_i + drying_per_hour = (drying_per_hour * 1.5).ceil + when :DAMPMULCH + time_per_stage = (time_per_stage * 1.25).to_i + drying_per_hour /= 2 + when :GOOEYMULCH + max_replants = (max_replants * 1.5).ceil + when :STABLEMULCH + stages_fully_grown = (stages_fully_grown * 1.5).ceil + end + # Do replants + done_replant = false + loop do + stages_this_life = stages_growing + stages_fully_grown - (replanted? ? 1 : 0) + break if new_time_alive < stages_this_life * time_per_stage + if @replant_count >= max_replants + reset + return + end + replant + done_replant = true + new_time_alive -= stages_this_life * time_per_stage + end + # Update how long plant has been alive for + old_growth_stage = @growth_stage + @time_alive = new_time_alive + @growth_stage = 1 + @time_alive / time_per_stage + @growth_stage += 1 if replanted? # Replants start at stage 2 + @time_last_updated = time_now.to_i + # Record watering (old mechanics), and apply drying out per hour (new mechanics) + if @new_mechanics + old_growth_hour = (done_replant) ? 0 : (@time_alive - time_delta) / 3600 + new_growth_hour = @time_alive / 3600 + if new_growth_hour > old_growth_hour + (new_growth_hour - old_growth_hour).times do + if @moisture_level > 0 + @moisture_level -= drying_per_hour + else + @yield_penalty += 1 + end + end + end + else + old_growth_stage = (done_replant) ? 0 : old_growth_stage + new_growth_stage = [@growth_stage, stages_growing + 1].min + @watered_this_stage = false if new_growth_stage > old_growth_stage + water if $game_screen && GameData::Weather.get($game_screen.weather_type).category == :Rain + end + end +end +#=============================================================================== +# +#=============================================================================== class BerryPlantMoistureSprite - def initialize(event,map,viewport=nil) - @event=event - @map=map - @light = IconSprite.new(0,0,viewport) - @light.ox=16 - @light.oy=24 - @oldmoisture=-1 # -1=none, 0=dry, 1=damp, 2=wet - updateGraphic - @disposed=false + def initialize(event, map, viewport = nil) + @event = event + @map = map + @sprite = IconSprite.new(0, 0, viewport) + @sprite.ox = 16 + @sprite.oy = 24 + @moisture_stage = -1 # -1 = none, 0 = dry, 1 = damp, 2 = wet + @disposed = false + update_graphic + end + + def dispose + @sprite.dispose + @map = nil + @event = nil + @disposed = true end def disposed? return @disposed end - def dispose - @light.dispose - @map=nil - @event=nil - @disposed=true - end - - def updateGraphic - case @oldmoisture - when -1 then @light.setBitmap("") - when 0 then @light.setBitmap("Graphics/Characters/berrytreeDry") - when 1 then @light.setBitmap("Graphics/Characters/berrytreeDamp") - when 2 then @light.setBitmap("Graphics/Characters/berrytreeWet") + def update_graphic + case @moisture_stage + when -1 then @sprite.setBitmap("") + when 0 then @sprite.setBitmap("Graphics/Characters/berrytreeDry") + when 1 then @sprite.setBitmap("Graphics/Characters/berrytreeDamp") + when 2 then @sprite.setBitmap("Graphics/Characters/berrytreeWet") end end def update - return if !@light || !@event - newmoisture=-1 - if @event.variable && @event.variable.length>6 && @event.variable[1] - # Berry was planted, show moisture patch - newmoisture=(@event.variable[4]>50) ? 2 : (@event.variable[4]>0) ? 1 : 0 + return if !@sprite || !@event + new_moisture = -1 + berry_plant = @event.variable + if berry_plant&.is_a?(BerryPlantData) && berry_plant.planted? + new_moisture = berry_plant.moisture_stage end - if @oldmoisture!=newmoisture - @oldmoisture=newmoisture - updateGraphic + if new_moisture != @moisture_stage + @moisture_stage = new_moisture + update_graphic end - @light.update - if (Object.const_defined?(:ScreenPosHelper) rescue false) - @light.x = ScreenPosHelper.pbScreenX(@event) - @light.y = ScreenPosHelper.pbScreenY(@event) - @light.zoom_x = ScreenPosHelper.pbScreenZoomX(@event) - else - @light.x = @event.screen_x - @light.y = @event.screen_y - @light.zoom_x = 1.0 - end - @light.zoom_y = @light.zoom_x - pbDayNightTint(@light) + @sprite.update + @sprite.x = ScreenPosHelper.pbScreenX(@event) + @sprite.y = ScreenPosHelper.pbScreenY(@event) + @sprite.zoom_x = ScreenPosHelper.pbScreenZoomX(@event) + @sprite.zoom_y = @sprite.zoom_x + pbDayNightTint(@sprite) end end - - +#=============================================================================== +# +#=============================================================================== class BerryPlantSprite - def initialize(event,map,_viewport) - @event=event - @map=map - @oldstage=0 - @disposed=false - berryData=event.variable - return if !berryData - @oldstage=berryData[0] - @event.character_name="" - berryData=updatePlantDetails(berryData) - setGraphic(berryData,true) # Set the event's graphic - @event.setVariable(berryData) # Set new berry data + def initialize(event, map, _viewport) + @event = event + @map = map + @old_stage = 0 + @disposed = false + berry_plant = event.variable + return if !berry_plant + @old_stage = berry_plant.growth_stage + @event.character_name = "" + update_plant(berry_plant) + set_event_graphic(berry_plant, true) # Set the event's graphic end def dispose - @event=nil - @map=nil - @disposed=true + @event = nil + @map = nil + @disposed = true end def disposed? @disposed end - def update # Constantly updates, used only to immediately - berryData=@event.variable # change sprite when planting/picking berries - if berryData - berryData=updatePlantDetails(berryData) if berryData.length>6 - setGraphic(berryData) - @event.setVariable(berryData) - end - end - - def updatePlantDetails(berryData) - return berryData if berryData[0]==0 - berryvalues = GameData::BerryPlant.get(berryData[1]) - timeperstage = berryvalues.hours_per_stage * 3600 - timenow=pbGetTimeNow - if berryData.length>6 - # Gen 4 growth mechanisms - # Check time elapsed since last check - timeDiff=(timenow.to_i-berryData[3]) # in seconds - return berryData if timeDiff<=0 - berryData[3]=timenow.to_i # last updated now - # Mulch modifiers - dryingrate = berryvalues.drying_per_hour - maxreplants = GameData::BerryPlant::NUMBER_OF_REPLANTS - ripestages = 4 - case berryData[7] - when :GROWTHMULCH - timeperstage = (timeperstage * 0.75).to_i - dryingrate = (dryingrate * 1.5).ceil - when :DAMPMULCH - timeperstage = (timeperstage * 1.25).to_i - dryingrate = (dryingrate * 0.5).floor - when :GOOEYMULCH - maxreplants = (maxreplants * 1.5).ceil - when :STABLEMULCH - ripestages = 6 - end - # Cycle through all replants since last check - loop do - secondsalive=berryData[2] - growinglife=(berryData[5]>0) ? 3 : 4 # number of growing stages - numlifestages=growinglife+ripestages # number of growing + ripe stages - # Should replant itself? - if secondsalive+timeDiff>=timeperstage*numlifestages - # Should replant - if berryData[5]>=maxreplants # Too many replants - return [0,nil,0,0,0,0,0,nil] - end - # Replant - berryData[0]=2 # replants start in sprouting stage - berryData[2]=0 # seconds alive - berryData[5]+=1 # add to replant count - berryData[6]=0 # yield penalty - timeDiff-=(timeperstage*numlifestages-secondsalive) - else - break - end - end - # Update current stage and dampness - if berryData[0]>0 - # Advance growth stage - oldlifetime=berryData[2] - newlifetime=oldlifetime+timeDiff - if berryData[0]<5 - berryData[0]=1+(newlifetime/timeperstage).floor - berryData[0]+=1 if berryData[5]>0 # replants start at stage 2 - berryData[0]=5 if berryData[0]>5 - end - # Update the "seconds alive" counter - berryData[2]=newlifetime - # Reduce dampness, apply yield penalty if dry - growinglife=(berryData[5]>0) ? 3 : 4 # number of growing stages - oldhourtick=(oldlifetime/3600).floor - newhourtick=(([newlifetime,timeperstage*growinglife].min)/3600).floor - (newhourtick-oldhourtick).times do - if berryData[4]>0 - berryData[4]=[berryData[4]-dryingrate,0].max - else - berryData[6]+=1 - end - end - end - else - # Gen 3 growth mechanics - loop do - if berryData[0]>0 && berryData[0]<5 - levels=0 - # Advance time - timeDiff=(timenow.to_i-berryData[3]) # in seconds - if timeDiff>=timeperstage - levels+=1 - if timeDiff>=timeperstage*2 - levels+=1 - if timeDiff>=timeperstage*3 - levels+=1 - if timeDiff>=timeperstage*4 - levels+=1 - end - end - end - end - levels=5-berryData[0] if levels>5-berryData[0] - break if levels==0 - berryData[2]=false # not watered this stage - berryData[3]+=levels*timeperstage # add to time existed - berryData[0]+=levels # increase growth stage - berryData[0]=5 if berryData[0]>5 - end - if berryData[0]>=5 - # Advance time - timeDiff=(timenow.to_i-berryData[3]) # in seconds - if timeDiff>=timeperstage*4 # ripe for 4 times as long as a stage - # Replant - berryData[0]=2 # replants start at stage 2 - berryData[2]=false # not watered this stage - berryData[3]+=timeperstage*4 # add to time existed - berryData[4]=0 # reset total waterings count - berryData[5]+=1 # add to replanted count - if berryData[5] > GameData::BerryPlant::NUMBER_OF_REPLANTS # Too many replants - berryData = [0,nil,false,0,0,0] - break - end - else - break - end - end - end - # If raining, automatically water the plant - if berryData[0] > 0 && berryData[0] < 5 && $game_screen && - GameData::Weather.get($game_screen.weather_type).category == :Rain - if berryData[2] == false - berryData[2] = true - berryData[4] += 1 - end - end - end - return berryData - end - - def setGraphic(berryData,fullcheck=false) - return if !berryData || (@oldstage==berryData[0] && !fullcheck) - case berryData[0] + def set_event_graphic(berry_plant, full_check = false) + return if !berry_plant || (berry_plant.growth_stage == @old_stage && !full_check) + case berry_plant.growth_stage when 0 - @event.character_name="" - when 1 - @event.character_name="berrytreeplanted" # Common to all berries - @event.turn_down + @event.character_name = "" else - filename=sprintf("berrytree%s",GameData::Item.get(berryData[1]).id.to_s) - if pbResolveBitmap("Graphics/Characters/"+filename) - @event.character_name=filename - case berryData[0] - when 2 then @event.turn_down # X sprouted - when 3 then @event.turn_left # X taller - when 4 then @event.turn_right # X flowering - when 5 then @event.turn_up # X berries - end + if berry_plant.growth_stage == 1 + @event.character_name = "berrytreeplanted" # Common to all berries + @event.turn_down else - @event.character_name="Object ball" + filename = sprintf("berrytree%s", GameData::Item.get(berry_plant.berry_id).id.to_s) + if pbResolveBitmap("Graphics/Characters/" + filename) + @event.character_name = filename + case berry_plant.growth_stage + when 2 then @event.turn_down # X sprouted + when 3 then @event.turn_left # X taller + when 4 then @event.turn_right # X flowering + when 5 then @event.turn_up # X berries + end + else + @event.character_name = "Object ball" + end end - if @oldstage!=berryData[0] && berryData.length>6 # Gen 4 growth mechanisms - $scene.spriteset.addUserAnimation(Settings::PLANT_SPARKLE_ANIMATION_ID,@event.x,@event.y,false,1) if $scene.spriteset + if berry_plant.new_mechanics && @old_stage != berry_plant.growth_stage && + @old_stage > 0 && berry_plant.growth_stage <= GameData::BerryPlant::NUMBER_OF_GROWTH_STAGES + 1 + spriteset = $scene.spriteset(@map.map_id) + spriteset.addUserAnimation(Settings::PLANT_SPARKLE_ANIMATION_ID, + @event.x, @event.y, false, 1) if spriteset end end - @oldstage=berryData[0] + @old_stage = berry_plant.growth_stage + end + + def update_plant(berry_plant, initial = false) + berry_plant.update if berry_plant.planted? && (initial || berry_plant.new_mechanics) + end + + def update + berry_plant = @event.variable + return if !berry_plant + update_plant(berry_plant) + set_event_graphic(berry_plant) end end +#=============================================================================== +# +#=============================================================================== +Events.onSpritesetCreate += proc { |_sender, e| + spriteset = e[0] + viewport = e[1] + map = spriteset.map + map.events.each do |event| + next if !event[1].name[/berryplant/i] + spriteset.addUserSprite(BerryPlantMoistureSprite.new(event[1], map, viewport)) + spriteset.addUserSprite(BerryPlantSprite.new(event[1], map, viewport)) + end +} - +#=============================================================================== +# +#=============================================================================== def pbBerryPlant - interp=pbMapInterpreter - thisEvent=interp.get_character(0) - berryData=interp.getVariable - if !berryData - if Settings::NEW_BERRY_PLANTS - berryData=[0,nil,0,0,0,0,0,nil] - else - berryData=[0,nil,false,0,0,0] - end + interp = pbMapInterpreter + this_event = interp.get_character(0) + berry_plant = interp.getVariable + if !berry_plant + berry_plant = BerryPlantData.new + interp.setVariable(berry_plant) end - # Stop the event turning towards the player - case berryData[0] - when 1 then thisEvent.turn_down # X planted - when 2 then thisEvent.turn_down # X sprouted - when 3 then thisEvent.turn_left # X taller - when 4 then thisEvent.turn_right # X flowering - when 5 then thisEvent.turn_up # X berries - end - watering = [:SPRAYDUCK, :SQUIRTBOTTLE, :WAILMERPAIL, :SPRINKLOTAD] - berry=berryData[1] - case berryData[0] - when 0 # empty - if Settings::NEW_BERRY_PLANTS - # Gen 4 planting mechanics - if !berryData[7] # No mulch used yet - cmd=pbMessage(_INTL("It's soft, earthy soil."),[ - _INTL("Fertilize"), - _INTL("Plant Berry"), - _INTL("Exit")],-1) - if cmd==0 # Fertilize - ret=nil - pbFadeOutIn { - scene = PokemonBag_Scene.new - screen = PokemonBagScreen.new(scene,$PokemonBag) - ret = screen.pbChooseItemScreen(Proc.new { |item| GameData::Item.get(item).is_mulch? }) - } - if ret - if GameData::Item.get(ret).is_mulch? - berryData[7]=ret - $PokemonBag.pbDeleteItem(ret, 1) - pbMessage(_INTL("The {1} was scattered on the soil.\1",GameData::Item.get(ret).name)) - if pbConfirmMessage(_INTL("Want to plant a Berry?")) - pbFadeOutIn { - scene = PokemonBag_Scene.new - screen = PokemonBagScreen.new(scene,$PokemonBag) - berry = screen.pbChooseItemScreen(Proc.new { |item| GameData::Item.get(item).is_berry? }) - } - if berry - timenow=pbGetTimeNow - berryData[0]=1 # growth stage (1-5) - berryData[1]=berry # item ID of planted berry - berryData[2]=0 # seconds alive - berryData[3]=timenow.to_i # time of last checkup (now) - berryData[4]=100 # dampness value - berryData[5]=0 # number of replants - berryData[6]=0 # yield penalty - $PokemonBag.pbDeleteItem(berry,1) - pbMessage(_INTL("The {1} was planted in the soft, earthy soil.", - GameData::Item.get(berry).name)) - end - end - interp.setVariable(berryData) - else - pbMessage(_INTL("That won't fertilize the soil!")) - end - return - end - elsif cmd==1 # Plant Berry - pbFadeOutIn { - scene = PokemonBag_Scene.new - screen = PokemonBagScreen.new(scene,$PokemonBag) - berry = screen.pbChooseItemScreen(Proc.new { |item| GameData::Item.get(item).is_berry? }) - } - if berry - timenow=pbGetTimeNow - berryData[0]=1 # growth stage (1-5) - berryData[1]=berry # item ID of planted berry - berryData[2]=0 # seconds alive - berryData[3]=timenow.to_i # time of last checkup (now) - berryData[4]=100 # dampness value - berryData[5]=0 # number of replants - berryData[6]=0 # yield penalty - $PokemonBag.pbDeleteItem(berry,1) - pbMessage(_INTL("The {1} was planted in the soft, earthy soil.", - GameData::Item.get(berry).name)) - interp.setVariable(berryData) - end - return - end - else - pbMessage(_INTL("{1} has been laid down.\1",GameData::Item.get(berryData[7]).name)) - if pbConfirmMessage(_INTL("Want to plant a Berry?")) - pbFadeOutIn { - scene = PokemonBag_Scene.new - screen = PokemonBagScreen.new(scene,$PokemonBag) - berry = screen.pbChooseItemScreen(Proc.new { |item| GameData::Item.get(item).is_berry? }) - } - if berry - timenow=pbGetTimeNow - berryData[0]=1 # growth stage (1-5) - berryData[1]=berry # item ID of planted berry - berryData[2]=0 # seconds alive - berryData[3]=timenow.to_i # time of last checkup (now) - berryData[4]=100 # dampness value - berryData[5]=0 # number of replants - berryData[6]=0 # yield penalty - $PokemonBag.pbDeleteItem(berry,1) - pbMessage(_INTL("The {1} was planted in the soft, earthy soil.", - GameData::Item.get(berry).name)) - interp.setVariable(berryData) - end - return - end - end - else - # Gen 3 planting mechanics - if pbConfirmMessage(_INTL("It's soft, loamy soil.\nPlant a berry?")) - pbFadeOutIn { - scene = PokemonBag_Scene.new - screen = PokemonBagScreen.new(scene,$PokemonBag) - berry = screen.pbChooseItemScreen(Proc.new { |item| GameData::Item.get(item).is_berry? }) - } - if berry - timenow=pbGetTimeNow - berryData[0]=1 # growth stage (1-5) - berryData[1]=berry # item ID of planted berry - berryData[2]=false # watered in this stage? - berryData[3]=timenow.to_i # time planted - berryData[4]=0 # total waterings - berryData[5]=0 # number of replants - berryData.delete_at(6) # for compatibility - berryData.delete_at(6) # for compatibility - $PokemonBag.pbDeleteItem(berry,1) - pbMessage(_INTL("{1} planted a {2} in the soft loamy soil.", - $Trainer.name,GameData::Item.get(berry).name)) - interp.setVariable(berryData) - end - return - end - end - when 1 # X planted - pbMessage(_INTL("A {1} was planted here.",GameData::Item.get(berry).name)) - when 2 # X sprouted - pbMessage(_INTL("The {1} has sprouted.",GameData::Item.get(berry).name)) - when 3 # X taller - pbMessage(_INTL("The {1} plant is growing bigger.",GameData::Item.get(berry).name)) - when 4 # X flowering - if Settings::NEW_BERRY_PLANTS - pbMessage(_INTL("This {1} plant is in bloom!",GameData::Item.get(berry).name)) - else - case berryData[4] - when 4 - pbMessage(_INTL("This {1} plant is in fabulous bloom!",GameData::Item.get(berry).name)) - when 3 - pbMessage(_INTL("This {1} plant is blooming very beautifully!",GameData::Item.get(berry).name)) - when 2 - pbMessage(_INTL("This {1} plant is blooming prettily!",GameData::Item.get(berry).name)) - when 1 - pbMessage(_INTL("This {1} plant is blooming cutely!",GameData::Item.get(berry).name)) - else - pbMessage(_INTL("This {1} plant is in bloom!",GameData::Item.get(berry).name)) - end - end - when 5 # X berries - berryvalues = GameData::BerryPlant.get(berryData[1]) - # Get berry yield (berrycount) - berrycount=1 - if berryData.length > 6 - # Gen 4 berry yield calculation - berrycount = [berryvalues.maximum_yield - berryData[6], berryvalues.minimum_yield].max - else - # Gen 3 berry yield calculation - if berryData[4] > 0 - berrycount = (berryvalues.maximum_yield - berryvalues.minimum_yield) * (berryData[4] - 1) - berrycount += rand(1 + berryvalues.maximum_yield - berryvalues.minimum_yield) - berrycount = (berrycount / 4) + berryvalues.minimum_yield - else - berrycount = berryvalues.minimum_yield - end - end - item = GameData::Item.get(berry) - itemname = (berrycount>1) ? item.name_plural : item.name - pocket = item.pocket - if berrycount>1 - message=_INTL("There are {1} \\c[1]{2}\\c[0]!\nWant to pick them?",berrycount,itemname) - else - message=_INTL("There is 1 \\c[1]{1}\\c[0]!\nWant to pick it?",itemname) - end - if pbConfirmMessage(message) - if !$PokemonBag.pbCanStore?(berry,berrycount) - pbMessage(_INTL("Too bad...\nThe Bag is full...")) - return - end - $PokemonBag.pbStoreItem(berry,berrycount) - if berrycount>1 - pbMessage(_INTL("You picked the {1} \\c[1]{2}\\c[0].\\wtnp[30]",berrycount,itemname)) - else - pbMessage(_INTL("You picked the \\c[1]{1}\\c[0].\\wtnp[30]",itemname)) - end - pbMessage(_INTL("{1} put the \\c[1]{2}\\c[0] in the \\c[1]{4}\\c[0] Pocket.\1", - $Trainer.name,itemname,pocket,PokemonBag.pocketNames()[pocket])) + berry = berry_plant.berry_id + # Interact with the event based on its growth + if berry_plant.grown? + this_event.turn_up # Stop the event turning towards the player + berry_plant.reset if pbPickBerry(berry, berry_plant.berry_yield) + return + elsif berry_plant.growing? + berry_name = GameData::Item.get(berry).name + case berry_plant.growth_stage + when 1 # X planted + this_event.turn_down # Stop the event turning towards the player + pbMessage(_INTL("A {1} was planted here.", berry_name)) + when 2 # X sprouted + this_event.turn_down # Stop the event turning towards the player + pbMessage(_INTL("The {1} has sprouted.", berry_name)) + when 3 # X taller + this_event.turn_left # Stop the event turning towards the player + pbMessage(_INTL("The {1} plant is growing bigger.", berry_name)) + else # X flowering + this_event.turn_right # Stop the event turning towards the player if Settings::NEW_BERRY_PLANTS - pbMessage(_INTL("The soil returned to its soft and earthy state.")) - berryData=[0,nil,0,0,0,0,0,nil] + pbMessage(_INTL("This {1} plant is in bloom!", berry_name)) else - pbMessage(_INTL("The soil returned to its soft and loamy state.")) - berryData=[0,nil,false,0,0,0] + case berry_plant.watering_count + when 4 + pbMessage(_INTL("This {1} plant is in fabulous bloom!", berry_name)) + when 3 + pbMessage(_INTL("This {1} plant is blooming very beautifully!", berry_name)) + when 2 + pbMessage(_INTL("This {1} plant is blooming prettily!", berry_name)) + when 1 + pbMessage(_INTL("This {1} plant is blooming cutely!", berry_name)) + else + pbMessage(_INTL("This {1} plant is in bloom!", berry_name)) + end end - interp.setVariable(berryData) end - end - case berryData[0] - when 1, 2, 3, 4 - for i in watering - next if !GameData::Item.exists?(i) || !$PokemonBag.pbHasItem?(i) - if pbConfirmMessage(_INTL("Want to sprinkle some water with the {1}?",GameData::Item.get(i).name)) - if berryData.length>6 - # Gen 4 berry watering mechanics - berryData[4]=100 - else - # Gen 3 berry watering mechanics - if berryData[2]==false - berryData[4]+=1 - berryData[2]=true - end - end - interp.setVariable(berryData) - pbMessage(_INTL("{1} watered the plant.\\wtnp[40]",$Trainer.name)) - if Settings::NEW_BERRY_PLANTS - pbMessage(_INTL("There! All happy!")) - else - pbMessage(_INTL("The plant seemed to be delighted.")) - end + # Water the growing plant + GameData::BerryPlant::WATERING_CANS.each do |item| + next if !GameData::Item.exists?(item) || !$PokemonBag.pbHasItem?(item) + break if !pbConfirmMessage(_INTL("Want to sprinkle some water with the {1}?", + GameData::Item.get(item).name)) + berry_plant.water + pbMessage(_INTL("{1} watered the plant.\\wtnp[40]", $Trainer.name)) + if Settings::NEW_BERRY_PLANTS + pbMessage(_INTL("There! All happy!")) + else + pbMessage(_INTL("The plant seemed to be delighted.")) end break end + return + end + # Nothing planted yet + ask_to_plant = true + if Settings::NEW_BERRY_PLANTS + # New mechanics + if berry_plant.mulch_id + pbMessage(_INTL("{1} has been laid down.\1", GameData::Item.get(berry_plant.mulch_id).name)) + else + case pbMessage(_INTL("It's soft, earthy soil."), [ + _INTL("Fertilize"), _INTL("Plant Berry"), _INTL("Exit")], -1) + when 0 # Fertilize + mulch = nil + pbFadeOutIn { + scene = PokemonBag_Scene.new + screen = PokemonBagScreen.new(scene, $PokemonBag) + mulch = screen.pbChooseItemScreen(Proc.new { |item| GameData::Item.get(item).is_mulch? }) + } + return if !mulch + mulch_data = GameData::Item.get(mulch) + if mulch_data.is_mulch? + berry_plant.mulch_id = mulch + $PokemonBag.pbDeleteItem(mulch, 1) + pbMessage(_INTL("The {1} was scattered on the soil.\1", mulch_data.name)) + else + pbMessage(_INTL("That won't fertilize the soil!")) + return + end + when 1 # Plant Berry + ask_to_plant = false + else # Exit/cancel + return + end + end + else + # Old mechanics + return if !pbConfirmMessage(_INTL("It's soft, loamy soil.\nPlant a berry?")) + ask_to_plant = false + end + if !ask_to_plant || pbConfirmMessage(_INTL("Want to plant a Berry?")) + pbFadeOutIn { + scene = PokemonBag_Scene.new + screen = PokemonBagScreen.new(scene, $PokemonBag) + berry = screen.pbChooseItemScreen(Proc.new { |item| GameData::Item.get(item).is_berry? }) + } + if berry + berry_plant.plant(berry) + $PokemonBag.pbDeleteItem(berry, 1) + if Settings::NEW_BERRY_PLANTS + pbMessage(_INTL("The {1} was planted in the soft, earthy soil.", + GameData::Item.get(berry).name)) + else + pbMessage(_INTL("{1} planted a {2} in the soft loamy soil.", + $Trainer.name, GameData::Item.get(berry).name)) + end + end end end +#=============================================================================== +# +#=============================================================================== def pbPickBerry(berry, qty = 1) - interp=pbMapInterpreter - thisEvent=interp.get_character(0) - berryData=interp.getVariable - berry=GameData::Item.get(berry) - itemname=(qty>1) ? berry.name_plural : berry.name - if qty>1 - message=_INTL("There are {1} \\c[1]{2}\\c[0]!\nWant to pick them?",qty,itemname) + berry = GameData::Item.get(berry) + berry_name = (qty > 1) ? berry.name_plural : berry.name + if qty > 1 + message = _INTL("There are {1} \\c[1]{2}\\c[0]!\nWant to pick them?", qty, berry_name) else - message=_INTL("There is 1 \\c[1]{1}\\c[0]!\nWant to pick it?",itemname) + message = _INTL("There is 1 \\c[1]{1}\\c[0]!\nWant to pick it?", berry_name) end - if pbConfirmMessage(message) - if !$PokemonBag.pbCanStore?(berry,qty) - pbMessage(_INTL("Too bad...\nThe Bag is full...")) - return - end - $PokemonBag.pbStoreItem(berry,qty) - if qty>1 - pbMessage(_INTL("You picked the {1} \\c[1]{2}\\c[0].\\wtnp[30]",qty,itemname)) - else - pbMessage(_INTL("You picked the \\c[1]{1}\\c[0].\\wtnp[30]",itemname)) - end - pocket = berry.pocket - pbMessage(_INTL("{1} put the \\c[1]{2}\\c[0] in the \\c[1]{4}\\c[0] Pocket.\1", - $Trainer.name,itemname,pocket,PokemonBag.pocketNames()[pocket])) - if Settings::NEW_BERRY_PLANTS - pbMessage(_INTL("The soil returned to its soft and earthy state.")) - berryData=[0,nil,0,0,0,0,0,nil] - else - pbMessage(_INTL("The soil returned to its soft and loamy state.")) - berryData=[0,nil,false,0,0,0] - end - interp.setVariable(berryData) - pbSetSelfSwitch(thisEvent.id,"A",true) + return false if !pbConfirmMessage(message) + if !$PokemonBag.pbCanStore?(berry, qty) + pbMessage(_INTL("Too bad...\nThe Bag is full...")) + return false end + $PokemonBag.pbStoreItem(berry, qty) + if qty > 1 + pbMessage(_INTL("You picked the {1} \\c[1]{2}\\c[0].\\wtnp[30]", qty, berry_name)) + else + pbMessage(_INTL("You picked the \\c[1]{1}\\c[0].\\wtnp[30]", berry_name)) + end + pocket = berry.pocket + pbMessage(_INTL("{1} put the \\c[1]{2}\\c[0] in the \\c[1]{4}\\c[0] Pocket.\1", + $Trainer.name, berry_name, pocket, PokemonBag.pocketNames[pocket])) + if Settings::NEW_BERRY_PLANTS + pbMessage(_INTL("The soil returned to its soft and earthy state.")) + else + pbMessage(_INTL("The soil returned to its soft and loamy state.")) + end + this_event = pbMapInterpreter.get_character(0) + pbSetSelfSwitch(this_event.id, "A", true) + return true end diff --git a/PBS/berry_plants.txt b/PBS/berry_plants.txt index d7eaedec1..f4e543292 100644 --- a/PBS/berry_plants.txt +++ b/PBS/berry_plants.txt @@ -64,3 +64,6 @@ MICLEBERRY = 24,7,1,5 CUSTAPBERRY = 24,7,1,5 JABOCABERRY = 24,7,1,5 ROWAPBERRY = 24,7,1,5 +ROSELIBERRY = 18,6,1,5 +KEEBERRY = 24,7,1,5 +MARANGABERRY = 24,7,1,5