=begin CSCA Event Movement version: 1.3(April 23, 2012) Created by: Casper Gaming (https://www.caspergaming.com/) Compatibility: Made for RPGVXAce IMPORTANT: ALL CSCA Scripts should be compatible with each other unless otherwise noted. ####Updates#### Version 1.1 -Increased compatibility -Optimized -Fixed fast random_no_wait move type and fast random move type. Version 1.2 -Event commands no longer trigger if event is stunned(minus autorun/parallel). -Able to respawn events temporarily erased without transferring player to a different map, and return events to their starting position when transferring from the same map. Version 1.3 - Events will no longer pass through a set region ID, unless otherwise specified. - Fixed events ignoring comments after save load. FFEATURES: This script updates event movement routes based on when the player moves. Move routes for events not set up for use with this script are not affected. Compatible with CSCA Dungeon Tools. SETUP This script requires setup further down. Instructions included below. SETTING UP YOUR EVENTS: Step 1. Each event that you want to be effected by this script should have a comment event command with text "MONSTER" in it. Step 2. Each event should have a separate comment event command with one of the move route types listed below. Step 3. Each event should have a separate comment event command with one of the speeds listed below. If no speed listed, normal speed is assumed. Step 4(optional). Each event that you want to pass through the region ID set below should contain a comment with text "NONMONSTER" in it. MOVE ROUTE TYPES: RANDOM is the same as the default random. TOWARD is the same as the default toward. CUSTOM is the same as the default custom. CUSTOM will ignore a FAST speed. OPPOSITE will make the event move opposite of the player. LEFT_RIGHT will make the event move left or right randomly. UP_DOWN will make the event move up or down randomly. SAME will make the event move the same as the player. RANDOM_NO_WAIT is the same as the default random, without the possibility of no movement. AVOID will make the event try to avoid contact with the player. SPEED TYPES: No speed type will make the event move once every step the player takes. FAST will make the event move twice every step the player takes. Will move once every step the player takes for move route type: CUSTOM SLOW will make the event move once every 2 steps the player takes. VERY_SLOW will make the event move once every 4 steps the player takes. Please note that it is recommended to set the event speed higher if using a faster speed, and lower if using a slow speed so the event can keep up with the player. ####SCRIPT CALLS#### HOW TO CHECK IF SURPRISE/PREEMPTIVE STRIKE Before the battle processing event command, make this script call: $game_map.csca_back_side_attack(x) where x is the event's ID. This is not cleared at the end of battle, so if you have an event that you do not wish to check if it's a surprise/preemptive strike, you'll need to make this script call: $game_map.csca_clear_modify HOW TO STUN AN EVENT Make this script call: $game_map.csca_stun_event(x, y) where x would be the number of steps you want it to be stunned for and y would be the event ID. HOW TO RE-CHECK FOR MONSTER EVENTS Let's say you turn a monster event on by switch. This script will not recognize it automatically as this script merely checks for monster events afetr every transfer. To check for monster events without transfer, make this script call: $game_map.csca_get_monster_events make sure there is a few frames wait time between when the new monster event is enabled and the script call. CREDIT and TERMS: Please visit https://www.caspergaming.com/terms-of-use/ for terms of use and credit guidelines =end module CSCA_EVENT_MOVEMENT # Don't touch this. # Enter any number between 0 and 1 for these values. BEHIND_SURPRISE = 1 # Amount to add to the surprise rate if event attacks # from behind player. SIDE_SURPRISE = 0.6 # Amount to add to surprise rate if event attacks from # player's side. BEHIND_PREEMPTIVE = 1 # Amount to add to the preemptive rate if player attacks # from behind event. SIDE_PREEMPTIVE = 0.6 # Amount to add to the preemptive rate if player attacks # from event's side. UNERASE = true # True = events respawn if they were erased even if the player # transfers to the same map. False will make events not respawn # until normal circumstances. RETURN_EVENT = true # True makes it so that events will return to their original # starting position even if the player transfers to the same # map. NOMOVE_REGION = 16 # Region ID that event's will not move into. Useful for # creating barriers that you do not want events to move out # of. DENY_THROUGH = true # Disallow "Through" events the ability to move through # the NOMOVE_REGION specified above? end # END SETUP! Don't touch this or anything below. $imported = {} if $imported.nil? $imported["CSCA-EventMovement"] = true class Game_Map include CSCA_EVENT_MOVEMENT alias csca_em_refresh refresh def refresh csca_get_monster_events csca_em_refresh end def csca_samemap_transfer_setup(map_id) events.each do |i, event| if event.csca_erased? event.csca_unerase if UNERASE else event.csca_return_start_pos if RETURN_EVENT end end end def csca_stun_event(steps, id) events.each do |i, event| if event.id == id event.csca_stun(steps) end end end def csca_get_monster_events events.each do |i, event| if event.list != nil for i in 0...event.list.size if event.list[i].code == 108 if event.list[i].parameters == ["MONSTER"] @monster_event = event @monster_event.csca_set_event_steps csca_set_movement_type(@monster_event) end if event.list[i].parameters == ["NONMONSTER"] event.csca_set_region_ignore end end end end end @monster_events_setup = true @allow_modify = false end def csca_set_movement_type(event) for i in 0...event.list.size if event.list[i].code == 108 if event.list[i].parameters == ["RANDOM"] event.csca_set_move_type(4) elsif event.list[i].parameters == ["TOWARD"] event.csca_set_move_type(5) elsif event.list[i].parameters == ["CUSTOM"] event.csca_set_move_type(6) elsif event.list[i].parameters == ["OPPOSITE"] event.csca_set_move_type(7) elsif event.list[i].parameters == ["LEFT_RIGHT"] event.csca_set_move_type(8) elsif event.list[i].parameters == ["UP_DOWN"] event.csca_set_move_type(9) elsif event.list[i].parameters == ["SAME"] event.csca_set_move_type(10) elsif event.list[i].parameters == ["RANDOM_NO_WAIT"] event.csca_set_move_type(11) elsif event.list[i].parameters == ["AVOID"] event.csca_set_move_type(12) end if event.list[i].parameters == ["FAST"] event.csca_set_move_speed(3) elsif event.list[i].parameters == ["SLOW"] event.csca_set_move_speed(2) elsif event.list[i].parameters == ["VERY_SLOW"] event.csca_set_move_speed(1) end end end end def csca_back_side_attack(event_id) events.each do |i, event| if event.id == event_id csca_check_surprise(event) csca_check_preemptive(event) end end end def csca_check_surprise(event) d1 = event.direction x1 = event.x y1 = event.y d2 = $game_player.direction x2 = $game_player.x y2 = $game_player.y if d1 == 2 && d2 == 2 && y1 == (y2 - 1) csca_alter_surprise(BEHIND_SURPRISE) elsif d1 == 4 && d2 == 4 && x1 == (x2 + 1) csca_alter_surprise(BEHIND_SURPRISE) elsif d1 == 6 && d2 == 6 && x1 == (x2 - 1) csca_alter_surprise(BEHIND_SURPRISE) elsif d1 == 8 && d2 == 8 && y1 == (y2 + 1) csca_alter_surprise(BEHIND_SURPRISE) elsif d1 == 2 && (d2 == 4 || d2 == 6) && y1 == (y2 - 1) csca_alter_surprise(SIDE_SURPRISE) elsif d1 == 8 && (d2 == 4 || d2 == 6) && y1 == (y2 + 1) csca_alter_surprise(SIDE_SURPRISE) elsif d1 == 4 && (d2 == 2 || d2 == 8) && x1 == (x2 + 1) csca_alter_surprise(SIDE_SURPRISE) elsif d1 == 6 && (d2 == 2 || d2 == 8) && x1 == (x2 - 1) csca_alter_surprise(SIDE_SURPRISE) else csca_alter_surprise(0) end end def csca_enable_modify @allow_modify = true end def csca_disable_modify @allow_modify = false end def csca_allow_modify? @allow_modify end def csca_alter_surprise(amount) @surprise_modify = amount end def csca_surprise_modify_amount @surprise_modify end def csca_check_preemptive(event) d1 = csca_prelock_direction x1 = event.x y1 = event.y d2 = $game_player.direction x2 = $game_player.x y2 = $game_player.y if d1 == 2 && d2 == 2 && y2 == (y1 - 1) csca_alter_preemptive(BEHIND_PREEMPTIVE) elsif d1 == 4 && d2 == 4 && x2 == (x1 + 1) csca_alter_preemptive(BEHIND_PREEMPTIVE) elsif d1 == 6 && d2 == 6 && x2 == (x1 - 1) csca_alter_preemptive(BEHIND_PREEMPTIVE) elsif d1 == 8 && d2 == 8 && y2 == (y1 + 1) csca_alter_preemptive(BEHIND_PREEMPTIVE) elsif d2 == 2 && (d1 == 4 || d1 == 6) && y2 == (y1 - 1) csca_alter_preemptive(SIDE_PREEMPTIVE) elsif d2 == 8 && (d1 == 4 || d1 == 6) && y2 == (y1 + 1) csca_alter_preemptive(SIDE_PREEMPTIVE) elsif d2 == 4 && (d1 == 2 || d1 == 8) && x2 == (x1 + 1) csca_alter_preemptive(SIDE_PREEMPTIVE) elsif d2 == 6 && (d1 == 2 || d1 == 8) && x2 == (x1 - 1) csca_alter_preemptive(SIDE_PREEMPTIVE) else csca_alter_preemptive(0) end end def csca_alter_preemptive(amount) @preemptive_modify = amount end def csca_preemptive_modify_amount @preemptive_modify end def csca_set_prelock_direction(value) @preemptive_direction = value end def csca_prelock_direction @preemptive_direction end def csca_clear_modify @surprise_modify = @preemptive_modify = 0 end def csca_em_region_collision_check(x, y) region_id(x, y) == NOMOVE_REGION end end class Game_CharacterBase def passable?(x, y, d) x2 = $game_map.round_x_with_direction(x, d) y2 = $game_map.round_y_with_direction(y, d) return false unless $game_map.valid?(x2, y2) return false if csca_collide_with_region?(x2, y2) && CSCA_EVENT_MOVEMENT::DENY_THROUGH return true if @through || debug_through? return false unless map_passable?(x, y, d) return false unless map_passable?(x2, y2, reverse_dir(d)) return false if collide_with_characters?(x2, y2) return false if csca_collide_with_region?(x2, y2) return true end def csca_collide_with_region?(x, y) self.is_a?(Game_Event) ? self.region_ignore? ? false : $game_map.csca_em_region_collision_check(x, y) : false end end class Game_Event < Game_Character alias csca_initialize initialize def initialize(map_id, event) super() csca_initialize(map_id, event) init_csca_event_movement(@event.x, @event.y) end def init_csca_event_movement(x, y) @starting_x = @event.x @starting_y = @event.y @csca_move_speed = 0 @stun_amount = 0 @region_ignore = false end def csca_erased? @erased end def csca_unerase @erased = false moveto(@starting_x, @starting_y) refresh end def csca_return_start_pos moveto(@starting_x, @starting_y) end def lock unless @locked @prelock_direction = @direction $game_map.csca_set_prelock_direction(@direction) turn_toward_player @locked = true end end def update_stop super update_self_movement unless (@csca_move_speed != 3 && @move_route_forcing) || csca_stunned? if csca_stunned? @stun_amount -= 1 if @csca_event_steps != $game_party.steps @csca_event_steps = $game_party.steps $game_map.refresh end end def csca_set_region_ignore @region_ignore = true end def region_ignore? @region_ignore end def csca_set_move_type(type) @move_type = type end def csca_set_move_speed(speed) @csca_move_speed = speed end alias csca_update_self_movement update_self_movement def update_self_movement csca_update_self_movement if @stop_count > stop_count_threshold && @csca_event_steps != $game_party.steps speed = @csca_move_speed steps = @csca_event_steps if speed == 0 || speed == 3 || (speed == 2 && (steps % 2) == 0) || (speed == 1 && (steps % 4) == 0) case @move_type when 4; speed == 3 ? fast_csca_move_type_random : move_type_random when 5; speed == 3 ? fast_csca_move_type_toward_player : move_type_toward_player when 6; move_type_custom when 7; csca_move_type_opposite when 8; csca_move_type_lr when 9; csca_move_type_ud when 10; csca_move_type_same when 11; speed == 3 ? fast_csca_move_type_random_nw : csca_move_type_random when 12; speed == 3 ? fast_csca_move_type_avoid : csca_move_type_avoid end end @csca_event_steps = $game_party.steps end end def csca_set_event_steps @csca_event_steps = $game_party.steps end def csca_move_type_opposite new_direction = 10 - $game_player.direction set_direction(new_direction) @csca_move_speed == 3 ? csca_fast_move_forward : move_forward end def csca_move_type_lr set_direction(4) if @direction == 2 || @direction == 8 case rand(3) when 0; set_direction(4) when 1; set_direction(6) end @csca_move_speed == 3 ? csca_fast_move_forward : move_forward end def csca_move_type_ud set_direction(2) if @direction == 4 || @direction == 6 case rand(3) when 0; set_direction(2) when 1; set_direction(8) end @csca_move_speed == 3 ? csca_fast_move_forward : move_forward end def csca_move_type_same new_direction = $game_player.direction set_direction(new_direction) @csca_move_speed == 3 ? csca_fast_move_forward : move_forward end def csca_move_type_random case rand(5) when 0..1; move_random when 2..4; move_forward end end def csca_move_type_avoid if near_the_player? case rand(6) when 0..3; move_away_from_player when 4; move_random when 5; move_forward end else move_random end end def fast_csca_move_type_random case rand(6) when 0..1; code1 = 12; code1p = [] when 2..4; code1 = 9; code1p = [] when 5; code1 = 15; code1p = [15] end case rand(6) when 0..1; code2 = 12; code2p = [] when 2..4; code2 = 9; code2p = [] when 5; code2 = 15; code2p = [15] end csca_execute_fast_move_route(code1, code2, code1p, code2p) end def fast_csca_move_type_toward_player if near_the_player? case rand(6) when 0..3; code1 = 10 when 4; code1 = 9 when 5; code1 = 12 end case rand(6) when 0..3; code2 = 10 when 4; code2 = 9 when 5; code2 = 12 end else code1 = 9 code2 = 9 end csca_execute_fast_move_route(code1, code2) end def fast_csca_move_type_random_nw case rand(5) when 0..1; code1 = 12 when 2..4; code1 = 9 end case rand(5) when 0..1; code2 = 12 when 2..4; code2 = 9 end csca_execute_fast_move_route(code1, code2) end def fast_csca_move_type_avoid if near_the_player? case rand(6) when 0..3; code1 = 11 when 4..5; code1 = 9 end case rand(6) when 0..3; code2 = 11 when 4..5; code2 = 9 end else code1 = 9 code2 = 9 end csca_execute_fast_move_route(code1, code2) end def csca_fast_move_forward mr = RPG::MoveRoute.new mr.skippable = true mr.repeat = false mr.wait = false mc = RPG::MoveCommand.new mc.code = 12 mc.parameters = [] mc2 = RPG::MoveCommand.new mc2.code = 12 mc2.parameters = [] mr.list[0] = mc mr.list[1] = mc2 force_move_route(mr) end def csca_execute_fast_move_route(code1, code2, code1p = [], code2p = []) mr = RPG::MoveRoute.new mr.skippable = true mr.repeat = false mr.wait = false mc = RPG::MoveCommand.new mc.code = code1 mc.parameters = code1p mc2 = RPG::MoveCommand.new mc2.code = code2 mc2.parameters = code2p mr.list[0] = mc mr.list[1] = mc2 force_move_route(mr) end def csca_stun(steps) @stun_amount = steps end def csca_stunned? @stun_amount > 0 end end class Game_Player < Game_Character alias csca_clear_movement_info_on_transfer clear_transfer_info def clear_transfer_info csca_clear_movement_info_on_transfer $game_map.csca_get_monster_events end end class Game_Party < Game_Unit alias csca_preemptive rate_preemptive def rate_preemptive(troop_agi) csca_preemptive(troop_agi) (agi >= troop_agi ? 0.05 : 0.03) * (raise_preemptive? ? 4 : 1) + ($game_map.csca_allow_modify? ? $game_map.csca_preemptive_modify_amount.to_f : 0) end alias csca_surprise rate_surprise def rate_surprise(troop_agi) csca_surprise(troop_agi) cancel_surprise? ? 0 : (agi >= troop_agi ? 0.03 : 0.05) + ($game_map.csca_allow_modify? ? $game_map.csca_surprise_modify_amount.to_f : 0) end end class Game_Interpreter def command_301 return if $game_party.in_battle $game_map.csca_enable_modify if @params[0] == 0 troop_id = @params[1] elsif @params[0] == 1 troop_id = $game_variables[@params[1]] else troop_id = $game_player.make_encounter_troop_id end if $data_troops[troop_id] BattleManager.setup(troop_id, @params[2], @params[3]) BattleManager.on_encounter BattleManager.event_proc = Proc.new {|n| @branch[@indent] = n } $game_player.make_encounter_count SceneManager.call(Scene_Battle) end Fiber.yield end end class Game_Player < Game_Character def encounter return false if $game_map.interpreter.running? return false if $game_system.encounter_disabled return false if @encounter_count > 0 make_encounter_count troop_id = make_encounter_troop_id return false unless $data_troops[troop_id] $game_map.csca_disable_modify BattleManager.setup(troop_id) BattleManager.on_encounter return true end alias csca_start_map_event start_map_event def start_map_event(x, y, triggers, normal) $game_map.events_xy(x, y).each do |event| return if event.csca_stunned? end csca_start_map_event(x, y, triggers, normal) end def perform_transfer if transfer? set_direction(@new_direction) if @new_map_id != $game_map.map_id $game_map.setup(@new_map_id) $game_map.autoplay else $game_map.csca_samemap_transfer_setup(@new_map_id) end moveto(@new_x, @new_y) clear_transfer_info end end end