hey guys, i have been trying really hard to make dynamic events for my woodcutting and mining script, the way i want the events to work is when i cut a tree or rock is when the job has successfully been completed the tree changes to a stump, or the rock temp loses its ore, if anyone has played runescape they will know the effect im trying to capture.
i have sort of been able to get it to work, by using an attr_accessor, when the job is succesful it sets the accessor to true, then the event changes page, after the script has run, in the second page it checks two conditions, 1 that the cutting/mining timer is at 0, then the second branch it checks if the accessor is true, if its true it changes the graphic and sets a random respawn timer, if its false it changes back to the first page giving the effect that the job was not successful, heres the script as it stands and screenies of the event that runs the proccess:
=begin
------------
HOW TO USE:
------------
In an event, use a script call and by putting one of the following:
$game_party.cut_tree(id)
$game_party.mine_rock(id)
Where 'id' is the type of wood/rock you want to cut/mine depending on the
values configured in the Configuration below.
The script processes the animation and adds the EXP upon successful harvest.
=end
#---------------------------------------------------------------------------
# Configuration for different types of trees and rocks to cut and mine.
# Defines how long it takes to cut/mine, EXP gained, and level requirement.
#---------------------------------------------------------------------------
module Config
#wc xp to lvl 2
Wc_to_2 = 83
#mine xp to lvl 2
Mine_to_2 = 83
#woodcutting lvl inflation
Wc_inflation = 10
#mining lvl inflation
Mine_inflation = 10
#woodcutting extension
Wc_exten = '_hack'
#mining
Mine_exten = '_hack'
#set the filenames of the hatchet and pickaxe images
Hatchet_spr = 'hatchet'
Pickaxe_spr = 'pickaxe'
#set the filename of the mine and cutting sounds, you may need to add the
#file extension, i.e .mp3
Mine_sound = '042-Knock03'
Mine_vol = 100
Mine_pitch = 100
Cut_sound = '042-Knock03'
Cut_vol = 100
Cut_pitch = 100
#set the wait time between each swing, this will need editing depending on
#the length of the sound
Mine_wait_sound = 45
Cut_wait_sound = 45
def self.tree_setup(tree)
return case tree
#when TREE_ID then [MIN_WAIT_TIME, MAX_WAIT_TIME, EXP_GAINED, ITEM_GAINED,
#AMOUNT_ITEM_GAINED, LEVEL_REQUIRED]
when 1 then [60, 100, 5, 1, 1, 1, 100, 200]
when 2 then [40, 100, 10, 1, 2, 5, 100, 200]
else ''
end
end
def self.rock_setup(rock)
return case rock
#when ROCK_ID then [MIN_WAIT_TIME, MAX_WAIT_TIME, EXP_GAINED, ITEM_GAINED,
#AMOUNT_ITEM_GAINED, LEVEL_REQUIRED]
when 1 then [60, 100, 5, 2, 1, 1, 100, 200]
when 2 then [40, 100, 10, 2, 2, 5, 100, 200]
else ''
end
end
end
#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#
#
# E N D C O N F I G U R A T I O N
#
#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#
class Game_Temp
attr_accessor :message_waiting
alias init_wait initialize
def initialize
init_wait
@message_waiting = false
end
end
class Interpreter
def update
# Initialize loop count
@loop_count = 0
# Loop
loop do
# Add 1 to loop count
@loop_count += 1
# If 100 event commands ran
if @loop_count > 100
# Call Graphics.update for freeze prevention
Graphics.update
@loop_count = 0
end
# If map is different than event startup time
if $game_map.map_id != @map_id
# Change event ID to 0
@event_id = 0
end
# If a child interpreter exists
if @child_interpreter != nil
# Update child interpreter
@child_interpreter.update
# If child interpreter is finished running
unless @child_interpreter.running?
# Delete child interpreter
@child_interpreter = nil
end
# If child interpreter still exists
if @child_interpreter != nil
return
end
end
# If waiting for message to end
if @message_waiting or $game_temp.message_waiting #<--edited here
return
end
# If waiting for move to end
if @move_route_waiting
# If player is forcing move route
if $game_player.move_route_forcing
return
end
# Loop (map events)
for event in $game_map.events.values
# If this event is forcing move route
if event.move_route_forcing
return
end
end
# Clear move end waiting flag
@move_route_waiting = false
end
# If waiting for button input
if @button_input_variable_id > 0
# Run button input processing
input_button
return
end
# If waiting
if @wait_count > 0
# Decrease wait count
@wait_count -= 1
return
end
# If an action forcing battler exists
if $game_temp.forcing_battler != nil
return
end
# If a call flag is set for each type of screen
if $game_temp.battle_calling or
$game_temp.shop_calling or
$game_temp.name_calling or
$game_temp.menu_calling or
$game_temp.save_calling or
$game_temp.gameover
return
end
# If list of event commands is empty
if @list == nil
# If main map event
if @main
# Set up starting event
setup_starting_event
end
# If nothing was set up
if @list == nil
return
end
end
# If return value is false when trying to execute event command
if execute_command == false
return
end
# Advance index
@index += 1
end
end
end
#---------------------------------------------------------------------------
# * Game Actor
# Creates woodcutting and mining attributes to the actor. Sets up the EXP chart
# as well as set/get methods for their levels and EXP.
#---------------------------------------------------------------------------
class Game_Actor
attr_reader :minelevel # mining level
attr_accessor :mineexp # mining exp
attr_reader :wclevel # woodcutting level
attr_accessor :wcexp # woodcutting exp
#--------------------------------------------------------------------------
alias setup_mod setup
def setup(actor_id)
setup_mod(actor_id)
@minelevel = 1
@mineexp_list = Array.new(101)
make_mineexp_list
@mineexp = @mineexp_list[@minelevel]
#-------------------------------------
@wclevel = 1
@wcexp_list = Array.new(101)
make_wcexp_list
@wcexp = @wcexp_list[@wclevel]
end
#--------------------------------------------------------------------------
# * CALCULATE mine XP
#--------------------------------------------------------------------------
def make_mineexp_list
actor = $data_actors[@actor_id]
@mineexp_list[1] = 0
@mineexp_list[2] = Config::Mine_to_2
for i in 3..100
if i > actor.final_level
@mineexp_list[i] = 0
else
@mineexp_list[i] = ((@mineexp_list[i-1] + @mineexp_list[2]) + (@mineexp_list[i-1] / Config::Mine_inflation))
end
end
end
#--------------------------------------------------------------------------
# * Change mine EXP
# mineexp : new mine xp
#--------------------------------------------------------------------------
def mineexp=(mineexp)
@mineexp = [[mineexp, 9999999].min, 0].max
# Level up
while @mineexp >= @mineexp_list[@minelevel+1] and @mineexp_list[@minelevel+1] > 0
@minelevel += 1
end
# Level down
while @mineexp < @mineexp_list[@minelevel]
@minelevel -= 1
end
end
#--------------------------------------------------------------------------
# * Get mine EXP String
#--------------------------------------------------------------------------
def mineexp_s
return @mineexp_list[@minelevel+1] > 0 ? @mineexp.to_s : "-------"
end
#--------------------------------------------------------------------------
# * Get Next Level mine EXP String
#--------------------------------------------------------------------------
def next_mineexp_s
return @mineexp_list[@minelevel+1] > 0 ? @mineexp_list[@minelevel+1].to_s : "-------"
end
#--------------------------------------------------------------------------
# * Get Until Next Level mine EXP String
#--------------------------------------------------------------------------
def next_rest_mineexp_s
return @mineexp_list[@minelevel+1] > 0 ?
(@mineexp_list[@minelevel+1] - @mineexp).to_s : "-------"
end
#--------------------------------------------------------------------------
# * CALCULATE WC XP
#--------------------------------------------------------------------------
def make_wcexp_list
actor = $data_actors[@actor_id]
@wcexp_list[1] = 0
@wcexp_list[2] = Config::Wc_to_2
for i in 3..100
if i > actor.final_level
@wcexp_list[i] = 0
else
@wcexp_list[i] = (Config::Wc_inflation*(i-1) + @wcexp_list[i-1])
end
end
end
#--------------------------------------------------------------------------
# * Change WC EXP
# wcexp : new WC EXP
#--------------------------------------------------------------------------
def wcexp=(wcexp)
@wcexp = [[wcexp, 9999999].min, 0].max
# Level up
while @wcexp >= @wcexp_list[@wclevel+1] and @wcexp_list[@wclevel+1] > 0
@wclevel += 1
end
# Level down
while @wcexp < @wcexp_list[@wclevel]
@wclevel -= 1
end
end
#--------------------------------------------------------------------------
# * Get WC EXP String
#--------------------------------------------------------------------------
def wcexp_s
return @wcexp_list[@wclevel+1] > 0 ? @wcexp.to_s : "-------"
end
#--------------------------------------------------------------------------
# * Get Next Level WC EXP String
#--------------------------------------------------------------------------
def next_wcexp_s
return @wcexp_list[@wclevel+1] > 0 ? @wcexp_list[@wclevel+1].to_s : "-------"
end
#--------------------------------------------------------------------------
# * Get Until Next Level WC EXP String
#--------------------------------------------------------------------------
def next_rest_wcexp_s
return @wcexp_list[@wclevel+1] > 0 ?
(@wcexp_list[@wclevel+1] - @wcexp).to_s : "-------"
end
end
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=#
# *Game_Player (activate/deactivate step_anime)
# Also processes the action of cutting and mining
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=#
class Game_Player < Game_Character
attr_accessor :step_anime, :old_count, :wc_count, :mine_count, :character_name
def initialize
super
@old_count, @wc_count, @mine_count = 0, 0, 0
end
alias call_update_after_counting_down_timers update
def update
if @wc_count > 0 or @mine_count > 0
super
# A direction was pressed or canceled
if Input.dir4 != 0 or Input.trigger?(Input::B)
@old_count, @wc_count, @mine_count = 0, 0, 0
$game_party.finalize(false) # Failed to complete task
return
end
if @wc_count == @old_count - Config::Cut_wait_sound
@old_count = @wc_count
Audio.se_play("Audio/SE/" + Config::Cut_sound, Config::Cut_vol, Config::Cut_pitch)
end
if @mine_count == @old_count - Config::Mine_wait_sound
@old_count = @mine_count
Audio.se_play("Audio/SE/" + Config::Mine_sound, Config::Mine_vol, Config::Mine_pitch)
end
@wc_count -= 1 if @wc_count > 0
@mine_count -= 1 if @mine_count > 0
# Call the last steps when cutting/mining completes
$game_party.finalize(true) if (@wc_count == 0 and @mine_count == 0)
else
call_update_after_counting_down_timers
end
end
end
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=#
# *Game_Party
# Controls the majority of cutting/mining functions
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=#
class Game_Party
attr_accessor :cutting, :mining, :taskcomp, :randomizer
alias init_before_cutting_mining initialize
def initialize
init_before_cutting_mining
@cutting = false
@mining = false
@taskcomp = false
@object = nil
end
def cut_tree(id)
@object = Config.tree_setup(id)
randomizer = @object[0] + rand(@object[1] + 1 - @object[0])
@actors.each{|actor| $game_player.wc_count = (randomizer * 2 - 1) if actor.wclevel >= @object[5] }
for i in 0...$game_party.actors.size
actor = $game_party.actors[i]
if actor.wclevel < @object[5]
lvl = @object[5].to_s
$game_temp.message_waiting = true
$game_temp.message_proc = Proc.new { $game_temp.message_waiting = false }
$game_temp.message_text = "you need to be lvl " + lvl + " to cut this tree"
end
end
$game_player.old_count = $game_player.wc_count
return if $game_player.wc_count == 0
@cutting = true
player = @actors[0]
mine_graphic = player.character_name + Config::Wc_exten
$game_player.character_name = mine_graphic
player.set_graphic(mine_graphic, player.character_hue, player.battler_name, player.battler_hue)
$game_player.step_anime = true
end
def mine_rock(id)
@object = Config.rock_setup(id)
randomizer = @object[0] + rand(@object[1] + 1 - @object[0])
@actors.each{|actor| $game_player.mine_count = (randomizer * 2 - 1) if actor.minelevel >= @object[5] }
for i in 0...$game_party.actors.size
actor = $game_party.actors[i]
if actor.minelevel < @object[5]
lvl = @object[5].to_s
$game_temp.message_waiting = true
$game_temp.message_proc = Proc.new { $game_temp.message_waiting = false }
$game_temp.message_text = "you need to be lvl " + lvl + " to mine this rock"
end
end
$game_player.old_count = $game_player.mine_count
return if $game_player.mine_count == 0
@mining = true
player = @actors[0]
mine_graphic = player.character_name + Config::Mine_exten
$game_player.character_name = mine_graphic
player.set_graphic(mine_graphic, player.character_hue, player.battler_name, player.battler_hue)
$game_player.step_anime = true
end
def finalize(task_completed)
type = 1 if @cutting
type = 2 if @mining
player = @actors[0]
if type == 1
orig_name = player.character_name.split(Config::Wc_exten)
else #type == 2
orig_name = player.character_name.split(Config::Mine_exten)
end
$game_player.character_name = orig_name[0]
player.set_graphic(orig_name[0], player.character_hue, player.battler_name, player.battler_hue)
$game_player.step_anime = false
@cutting, @mining = false, false
return unless task_completed
@taskcomp = true
# Reward EXP to the actors with high enough levels
if type == 1
@actors.each{|a| a.wcexp += @object[2] if a.wclevel >= @object[5] }
$game_party.gain_item(@object[3], @object[4])
else #type == 2
@actors.each{|a| a.mineexp += @object[2] if a.minelevel >= @object[5] }
$game_party.gain_item(@object[3], @object[4])
end
end
end
#==============================================================================
# ** Sprite_Character
# Editted to include the hatchet and pickaxe sprites
#==============================================================================
class Sprite_Character < RPG::Sprite
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
super
# If tile ID, file name, or hue are different from current ones
if @tile_id != @character.tile_id or
@character_name != @character.character_name or
@character_hue != @character.character_hue
# Remember tile ID, file name, and hue
@tile_id = @character.tile_id
@character_name = @character.character_name
@character_hue = @character.character_hue
# If tile ID value is valid
if @tile_id >= 384
self.bitmap = RPG::Cache.tile($game_map.tileset_name,
@tile_id, @character.character_hue)
self.src_rect.set(0, 0, 32, 32)
self.ox = 16
self.oy = 32
# If tile ID value is invalid
else
self.bitmap = RPG::Cache.character(@character.character_name,
@character.character_hue)
if @character_name == $game_player.character_name and
($game_party.cutting or $game_party.mining)
RPG::Cache.clear
type = ($game_party.cutting ? Config::Hatchet_spr : Config::Pickaxe_spr)
src_bitmap = RPG::Cache.character(type, 0)
self.bitmap.blt(0, 0, src_bitmap, Rect.new(0,0,src_bitmap.width,src_bitmap.height))
end
@cw = bitmap.width / 4
@ch = bitmap.height / 4
self.ox = @cw / 2
self.oy = @ch
end
end
# Set visible situation
self.visible = (not @character.transparent)
# If graphic is character
if @tile_id == 0
# Set rectangular transfer
sx = @character.pattern * @cw
sy = (@character.direction - 2) / 2 * @ch
self.src_rect.set(sx, sy, @cw, @ch)
end
# Set sprite coordinates
self.x = @character.screen_x
self.y = @character.screen_y
self.z = @character.screen_z(@ch)
# Set opacity level, blend method, and bush depth
self.opacity = @character.opacity
self.blend_type = @character.blend_type
self.bush_depth = @character.bush_depth
# Animation
if @character.animation_id != 0
animation = $data_animations[@character.animation_id]
animation(animation, true)
@character.animation_id = 0
end
end
end
so you can generally see whats happening here, the problem is say i go to cut another tree/rock after just cutting one, then i imediatly walk away from it without completing the harvest, because the previous tree/rock set the attr_accessor to true and doesnt set it to false until the event has finished processing the tree/rock that i didnt harvest acts as if i did and changes thec graphic and sets the wait timer, i also had an idea to make the script to change the self switch manually but i couldnt get that to work
edit: ok i sort of got it to manually change the self switch of the events, what i did was add this to the update in interpreter:
theres only one problem with this, if there is a parrallel proccess event running then event id becomes that one instead of the event that is currently calling the script, and i cant figure a way around this