module SymbolEncount
FOLLOWER_CONTACT = true
SYMBOL_SETTING_LIST = {
0 => [
5,#怪物逃跑时玩家的等级
0,#玩家等级的判断种类(默认0)
3,#怪物逃跑时离玩家的距离
5,#怪物逃跑时离玩家的距离(玩家加速时)
0,#玩家没有反应时的移动模式
0,#与透明度变化时的玩家之间的距离
2,#反应前的移动速度
4,#反应后的移动速度
5,#反应前的移动频率
5,#反应后的移动频率
1,#反应时显示心情的ID
[10]#无法移动符号的版本ID
],
}
end
$rsi ||= {}
$rsi["单位计算辅助"] = true
class RPG::UsableItem < RPG::BaseItem
def stealth_obj_count
self.note.each_line{|line|
return $1.to_i if line =~ /无视:(\d+)/i
}
0
end
end
class << BattleManager
attr_writer :run_event
@run_event = nil
alias _symbol_encount_setup setup
def setup(troop_id, can_escape = true, can_lose = false)
_symbol_encount_setup(troop_id, can_escape, can_lose)
set_battle_condition
end
def set_battle_condition
if @run_event && @run_event.symbol_encount
@run_event.set_contact_condition
case @run_event.contact_condition
when 1
@preemptive = true
when 2
@surprise = true
end
end
@run_event = nil
end
end
class Game_Actor < Game_Battler
def use_item(item)
stealth_effect(item)
super
end
def stealth_effect(item)
result = item.stealth_obj_count
$game_player.stealth_count = result if result > 0
end
end
class Game_Party < Game_Unit
def get_player_level(type)
case type
when 0
members.inject(0){|r, actor| r += actor.level} / members.size
when 1
members.max_by{|actor| actor.level}
when 2
$game_party.members.first.level
end
end
end
class Game_Character < Game_CharacterBase
alias _symbol_init_private_members init_private_members
def init_private_members
_symbol_init_private_members
@origin_opacity = @opacity
end
alias _symbol_process_move_command process_move_command
def process_move_command(command)
params = command.parameters
@origin_opacity = params[0] if command.code == ROUTE_CHANGE_OPACITY
_symbol_process_move_command(command)
end
def positional_relationship(character)
if character.real_x == real_x
character.real_y > real_y ? 1 : 0
elsif character.real_y == real_y
character.real_x > real_x ? 2 : 3
else
-1
end
end
def update_symbol_opacity
end
alias _symbol_opacity_update update
def update
_symbol_opacity_update
update_symbol_opacity
end
end
class Game_Player < Game_Character
attr_writer :stealth_count
def init_public_members
super
reset_stealth
end
def reset_stealth
@stealth_count = 0
end
def stealth?
!@stealth_count.zero?
end
alias _increase_stealth_count increase_steps
def increase_steps
_increase_stealth_count
@stealth_count -= 1 if stealth?
end
def update_symbol_opacity
if stealth? && !$game_map.interpreter.running?
@opacity = 128
else
@opacity = @origin_opacity
end
end
end
class Game_Follower < Game_Character
attr_reader :member_index
end
class Game_Event < Game_Character
include SymbolEncount
attr_reader :symbol_encount
attr_reader :contact_condition
alias _symbol_encount_ini init_private_members
def init_private_members
_symbol_encount_ini
init_symbol_encount
end
alias _symbol_encount_setup_page setup_page
def setup_page(new_page)
init_symbol_encount
_symbol_encount_setup_page(new_page)
end
def init_symbol_encount
@forming = false
@symbol_encount = false
@symbol_away_level = 0
@symbol_away_level_type = 0
@reaction_distance = 0
@reaction_distance_with_dash = 0
@nonreaction_move_type = 0
@visibility_distance = 0
@reaction_before_speed = 0
@reaction_after_speed = 0
@reaction_before_speed = 0
@reaction_after_frequency = 0
@reaction_balloon_id = 0
@unpassable_region = []
@contact_index = -1
@contact_condition = 0
end
def enable_symbol_encount(id)
data = SYMBOL_SETTING_LIST[id]
@symbol_encount = true
@symbol_away_level = data[0]
@symbol_away_level_type = data[1]
@reaction_distance = data[2]
@reaction_distance_with_dash = data[3]
@nonreaction_move_type = data[4]
@visibility_distance = data[5]
@reaction_before_speed = data[6]
@reaction_after_speed = data[7]
@reaction_before_frequency = data[8]
@reaction_after_frequency = data[9]
@reaction_balloon_id = data[10]
@unpassable_region = data[11].dup
end
def passable?(x, y, d)
if @symbol_encount
x2 = $game_map.round_x_with_direction(x, d)
y2 = $game_map.round_y_with_direction(y, d)
return false if @unpassable_region.include?($game_map.region_id(x2, y2))
end
super
end
def lock
unless @locked
@prelock_direction = @direction
turn_toward_player unless @symbol_encount
@locked = true
end
end
def player_level
$game_party.get_player_level(@symbol_away_level_type)
end
def distance_from_player
distance_x_from($game_player.x).abs + distance_y_from($game_player.y).abs
end
def distance_from_character(character)
distance_x_from(character.x).abs + distance_y_from(character.y).abs
end
def reaction_distance
if @forming
@reaction_distance_with_dash.next
elsif $game_player.dash? && $game_player.moving?
@reaction_distance_with_dash
else
@reaction_distance
end
end
def active_symbol_encount?
if $game_map.interpreter.running?
false
elsif @erased || $game_player.stealth?
@forming = false
false
else
true
end
end
def direction_as_player?
direction == $game_player.direction
end
def contact?(character)
distance_from_character(character) <= 1
end
def reaction?
distance_from_player <= reaction_distance
end
def away?
player_level > @symbol_away_level
end
def set_contact_condition
@contact_index = -1
@contact_condition = 0
if contact?($game_player)
@contact_index = 0
elsif FOLLOWER_CONTACT
$game_player.followers.visible_folloers.each{|follower|
@contact_index = follower.member_index if contact?(follower)
}
end
if @contact_index.zero?
@contact_condition = direction_and_positional
elsif $game_player.followers.visible_folloers.size == @contact_index
@contact_condition = 2
else
@contact_condition = 0
end
end
def direction_and_positional
position = positional_relationship($game_player)
if position == -1
0
else
case direction
when 2
direction_as_player? ? (position == 0 ? 1 : 2) : 0
when 4
direction_as_player? ? (position == 2 ? 1 : 2) : 0
when 6
direction_as_player? ? (position == 3 ? 1 : 2) : 0
when 8
direction_as_player? ? (position == 1 ? 1 : 2) : 0
else
0
end
end
end
alias _symbol_encount_trigger check_event_trigger_touch
def check_event_trigger_touch(x, y)
if @symbol_encount && FOLLOWER_CONTACT
unless $game_map.interpreter.running?
if @trigger == 2 && collide_with_player_characters?(x, y)
start unless jumping?
end
end
else
_symbol_encount_trigger(x, y)
end
end
def start_forming
@move_speed = @reaction_after_speed
@move_frequency = @reaction_after_frequency
unless @reaction_balloon_id.zero?
Audio.se_play('Audio/SE/Absorb1', 70, 100)
@balloon_id = @reaction_balloon_id
end
end
def end_forming
@move_speed = @reaction_before_speed
@move_frequency = @reaction_before_frequency
end
def reaction_movement
@move_speed = @reaction_after_speed
@move_frequency = @reaction_after_frequency
if @symbol_away_level.zero?
move_type_toward_player
elsif away?
move_away_from_player
else
move_type_toward_player
end
end
def nonreaction_movement
@move_speed = @reaction_before_speed
@move_frequency = @reaction_before_frequency
case @nonreaction_move_type
when 0
move_type_random
when 1
end
end
alias _update_with_symbol update
def update
update_symbol_reaction if @symbol_encount && @wait_count <= 0 && !@move_route_forcing
_update_with_symbol
end
def update_symbol_reaction
if active_symbol_encount?
if !@forming && reaction?
start_forming
elsif @forming && !reaction?
end_forming
end
@forming = reaction?
end
end
def update_symbol_opacity
if @visibility_distance.zero?
@opacity = @origin_opacity
else
@opacity = @origin_opacity - 50 * (distance_from_player - @visibility_distance)
end
end
alias _update_self_movement_with_symbol update_self_movement
def update_self_movement
if @symbol_encount
update_symbol_movement if near_the_screen? && @stop_count > stop_count_threshold
else
_update_self_movement_with_symbol
end
end
def update_symbol_movement
if near_the_screen? && @stop_count > stop_count_threshold
if active_symbol_encount?
@forming ? reaction_movement : nonreaction_movement
else
nonreaction_movement
end
end
end
end
class Game_Interpreter
alias _command_301_with_symbol_encount command_301
def command_301
unless $game_party.in_battle
BattleManager.run_event = $game_map.events[@event_id]
_command_301_with_symbol_encount
end
end
def reset_stealth
$game_player.reset_stealth
end
end