#============================================================================== # □ Sapphire Action System IV Skill Fix ver.1.2.3 #============================================================================== # Author : 습작(etude87) #============================================================================== module Sapphire_Core #-------------------------------------------------------------------------- # ■ 투사체 발사 속도 확장 #-------------------------------------------------------------------------- # 설명 : 투사체 발사 속도를 6 이상 지원합니다. # SAS가 픽셀기반처럼 보이지만 사실 타일을 몇등분해서 사용하는 것일 뿐이라서 이동 역시 # 분할된 타일 단위로 이뤄지고 있기 때문에 이동 속도에 따라서는 종종 타 구간에 비해서 # 더 그려지는 구간이 생겨서 파티클 소멸이간이 불균등하게 이뤄지면서 듬성듬성하게 보여질 수 # 있습니다. 해당 현상에 대해서는 이동속도를 6의 배수로 설정해주시면 좋습니다. #-------------------------------------------------------------------------- #-------------------------------------------------------------------------- # ■ 파티클 소멸 시간 #-------------------------------------------------------------------------- # 설명 : 파티클 생성 후 소멸까지 소요되는 시간입니다.(단위 프레임) # 미 설정시 (255 - 이동속도 * 5)의 속도(최소값 1)로 사라집니다. # 개별 스킬에 Disappear = n 을 입력하시면 됩니다.(0보다 클것) #-------------------------------------------------------------------------- #-------------------------------------------------------------------------- # ■ 자식 스킬 #-------------------------------------------------------------------------- # 설명 : 적 타격시 자식 스킬을 생성합니다. # 관통 효과 등으로 응용할 수 있습니다. # 개별 스킬에 ChildSkill = n 을 입력하시면 됩니다.(n은 스킬 ID) #-------------------------------------------------------------------------- #-------------------------------------------------------------------------- # ■ 다른 방향으로 발사 #-------------------------------------------------------------------------- # 설명 : 플레이어가 바라보는 방향(키패드6)을 기준으로 다른 방향(키패드1,2,3,4,7,8,9)을 # 향해 투사체가 날아가게 합니다. # 개별 스킬에 ChangeDir = n 을 입력하시면 됩니다.(n은 해당 방향 키패드 숫자) #-------------------------------------------------------------------------- #-------------------------------------------------------------------------- # ■ 다른 스킬을 함께 발사 목록 #-------------------------------------------------------------------------- # 설명 : 스킬 사용시 다른 ID의 스킬을 함께 사용합니다. # 다른 방향으로 발사 기능을 사용하면 동시에 다른방향으로 스킬 사용이 가능합니다. # 마나코스트는 합산해서 계산하나 딜레이는 메인 스킬을 따릅니다. # # 작성예 ) # 대상스킬ID => [함께사용될 스킬ID 목록], #-------------------------------------------------------------------------- Link_Skill_List = {1 => [2,3,4,5,6,7,8], 9 => [10], }#<= 지우지 말것 #-------------------------------------------------------------------------- # ■ 기본 스킬 사거리 #-------------------------------------------------------------------------- # 설명 : 투사체의 기본 사거리를 설정합니다. # 설정값이 0인 경우 사거리는 무제한이 됩니다. # 단위 1당 Sapphire_Core 모듈에 설정된 1 Pixel값을 가집니다. # 개별 스킬에 대한 설정은 Range = n 을 입력하시면 됩니다. #-------------------------------------------------------------------------- Default_Skill_Range = 0 #-------------------------------------------------------------------------- # ■ 스킬 소멸시 자식 스킬 적용 여부 #-------------------------------------------------------------------------- # 설명 : 적을 맞추지 못하고 사거리가 다해 스킬이 소멸하는 경우에도 자식 스킬을 생성합니다. # 개별 스킬에 RangeChild = true/false 를 입력하시면 됩니다. #-------------------------------------------------------------------------- Default_Skill_Range_Child = false #-------------------------------------------------------------------------- # ■ 기본 스킬 시작 위치 #-------------------------------------------------------------------------- # 설명 : 투사체가 플레이어로부터 얼마나 떨어져서 발사를 시작하는지를 설정합니다. # 설정값이 0인 경우 플레이어의 위치에서 바로 시작합니다. # 음수인 경우 플레이어의 위치보다 뒤쪽에서 시작합니다. # 단위 1당 Sapphire_Core 모듈에 설정된 1 Pixel값을 가집니다. # 개별 스킬에 대한 설정은 Offset = n 을 입력하시면 됩니다. #-------------------------------------------------------------------------- Default_Skill_Offset = 0 #-------------------------------------------------------------------------- # ■ 기본 반사 설정 #-------------------------------------------------------------------------- # 설명 : 적 이외의 이동 불가능한 장애물과 만나면 이동 방향을 반전합니다. # 개별 스킬에 대한 설정은 Reflection = true/false 를 입력하시면 됩니다. #-------------------------------------------------------------------------- Default_Skill_Reflection = false #-------------------------------------------------------------------------- # ■ 기본 반사 횟수 설정 #-------------------------------------------------------------------------- # 설명 : 개별 스킬에 대해서 미 설정시 참조할 반사 횟수를 설정합니다. # 설정값이 0인 경우 무한 반사합니다. # 개별 스킬에 대한 설정은 ReflectionCount = n 을 입력하시면 됩니다. #-------------------------------------------------------------------------- Default_Skill_Reflection_Count = 0 #-------------------------------------------------------------------------- # ■ 8방향 사용 여부 #-------------------------------------------------------------------------- # 설명 : 사용 설정을 하시면 대각선 방향인 경우 투사체가 대각선 방향으로 사출됩니다. #-------------------------------------------------------------------------- Use_Dir8 = true #-------------------------------------------------------------------------- # ■ 기본 최대 시작 각도(0부터 설정 값중 무작위의 각도로 시작합니다.) #-------------------------------------------------------------------------- # 설명 : SAS는 XAS와 달리 투사체 이미지 자체가 움직이는 것이 아니라 점선 그리듯 # 이동하며 매 위치마다 점점 사라지는 파티클 스프라이트를 생성합니다. # 0 이상일 경우 0부터 설정 값까지 중에서 무작위로 선택하여 파티클 스프라이트를 # 회전시켜 생성합니다. # 본래 SAS의 기본값은 360입니다. # 개별 스킬에 대한 설정은 StartAngle = n 을 입력하시면 됩니다. #-------------------------------------------------------------------------- Default_Particle_Start_Angle = 0 #-------------------------------------------------------------------------- # ■ 기본 최대 회전 각도(0부터 설정 값중 무작위의 각도로 회전합니다.) #-------------------------------------------------------------------------- # 설명 : 점점 사라지는 파티클 스프라이트는 생성 이후부터 매 프레임마다 # 0부터 설정 값까지 중 무작위로 선택하여 그만큼 회전을 합니다. # 본래 SAS의 기본값은 10입니다. # 개별 스킬에 대한 설정은 AnglePlus = n 을 입력하시면 됩니다. #-------------------------------------------------------------------------- Default_Particle_Angle_Plus = -1 #-------------------------------------------------------------------------- # ■ 기본 방향에 다른 반전 및 회전 사용 여부 #-------------------------------------------------------------------------- # 설명 : 파티클의 좌우 반전 및 상하 각도 회전을 적용합니다. # 개별 스킬에 대한 설정은 Mirror = true/false 를 입력하시면 됩니다. #-------------------------------------------------------------------------- Default_Particle_Mirror = false #-------------------------------------------------------------------------- # ■ 기본 파티클 생성 간격 #-------------------------------------------------------------------------- # 설명 : 파티클 생성과 다음 파티클 생성까지의 간격입니다. # 0인 경우 매 이동마다 파티클을 그려주게 됩니다. # 1이상인 경우 파티클 생성 후 설정 값만큼 이동 후 다시 파티클을 생성합니다. # 개별 스킬에 대한 설정은 Interval = n 을 입력하시면 됩니다. #-------------------------------------------------------------------------- Default_Particle_Interval = 0 #-------------------------------------------------------------------------- end #============================================================================== #============================================================================== module Pixel_Core Pixel_Range = {2=>[0,0.25], 4=>[-0.25,0], 6=>[0.25,0], 8=>[0,-0.25], 1=>[-0.25,0.25], 3=>[0.25,0.25], 7=>[-0.25,-0.25], 9=>[0.25,-0.25], } Tile_Range = {2=>[0,1], 4=>[-1,0], 6=>[1,0], 8=>[0,-1], 1=>[-1,1], 3=>[1,1], 7=>[-1,-1], 9=>[1,-1], } end #============================================================================== #============================================================================== class RPG::Skill < RPG::UsableItem #-------------------------------------------------------------------------- def disappear self.note.get("Disappear", 0).to_i end #-------------------------------------------------------------------------- def child_skill self.note.get("ChildSkill", 0).to_i end #-------------------------------------------------------------------------- def range self.note.get("Range", Sapphire_Core::Default_Skill_Range).to_i end #-------------------------------------------------------------------------- def range_child self.note.get("RangeChild", Sapphire_Core::Default_Skill_Range_Child) end #-------------------------------------------------------------------------- def offset self.note.get("Offset", Sapphire_Core::Default_Skill_Offset).to_i end #-------------------------------------------------------------------------- def change_direction self.note.get("ChangeDir", 0).to_i end #-------------------------------------------------------------------------- def reflection self.note.get("Reflection", Sapphire_Core::Default_Skill_Reflection) end #-------------------------------------------------------------------------- def reflection_count self.note.get("ReflectionCount", Sapphire_Core::Default_Skill_Reflection_Count).to_i end #-------------------------------------------------------------------------- def mirror self.note.get("Mirror", Sapphire_Core::Default_Particle_Mirror) end #-------------------------------------------------------------------------- def start_angle self.note.get("StartAngle", Sapphire_Core::Default_Particle_Start_Angle).to_i end #-------------------------------------------------------------------------- def angle_plus self.note.get("AnglePlus", Sapphire_Core::Default_Particle_Angle_Plus).to_i end #-------------------------------------------------------------------------- def interbal self.note.get("Interval", Sapphire_Core::Default_Particle_Interval).to_i end #-------------------------------------------------------------------------- end #============================================================================== #============================================================================== class Game_Player < Game_Character #-------------------------------------------------------------------------- def cast_skill return if @current_skill[0].nil? || @recover > 0 return if $game_party.members[0].mp < @current_skill[0].mp_cost $game_map.skills << Sapphire_Skill.new(self) $game_party.members[0].mp -= @current_skill[0].mp_cost $game_map.sas_hud.refresh_bars @recover = @current_skill[0].recover cast_link_skill end #-------------------------------------------------------------------------- def cast_link_skill if Sapphire_Core::Link_Skill_List.include?(@current_skill[0].id) last_current_skill = @current_skill[0] for skill in Sapphire_Core::Link_Skill_List[last_current_skill.id] next unless $data_skills[skill].is_a?(RPG::Skill) next unless $data_skills[skill].particle @current_skill[0] = $data_skills[skill] @current_skill[1] = $data_skills[skill].particle $game_map.skills << Sapphire_Skill.new(self) $game_party.members[0].mp -= @current_skill[0].mp_cost $game_map.sas_hud.refresh_bars end @current_skill[0] = last_current_skill @current_skill[1] = last_current_skill.particle end end #-------------------------------------------------------------------------- def move_by_input return if !movable? || $game_map.interpreter.running? move_straight(Sapphire_Core::Use_Dir8 ? Input.dir8 : Input.dir4) if (Sapphire_Core::Use_Dir8 ? Input.dir8 : Input.dir4) > 0 end #-------------------------------------------------------------------------- end #============================================================================== #============================================================================== class Game_Event < Game_Character #-------------------------------------------------------------------------- def prepare_link_skill @last_skills = @enemy.skills skill = @last_skills[rand(@last_skills.size)] @enemy.skills = [skill] end #-------------------------------------------------------------------------- def cast_link_skill current_skill_id = @enemy.skills[0][0].id if Sapphire_Core::Link_Skill_List.include?(current_skill_id) for skill in Sapphire_Core::Link_Skill_List[current_skill_id] next unless $data_skills[skill].is_a?(RPG::Skill) next unless $data_skills[skill].particle @enemy.skills = [[$data_skills[skill], $data_skills[skill].particle]] $game_map.skills << Sapphire_Skill.new(self) end end @enemy.skills = @last_skills end #-------------------------------------------------------------------------- def update_skills return if @recover > 0 || @enemy.nature == 0 if @enemy.auto_attack prepare_link_skill $game_map.skills << Sapphire_Skill.new(self) @recover = @enemy.recover cast_link_skill else update_cast end end #-------------------------------------------------------------------------- def update_cast case @direction when 2 distance = ($game_player.py - @py) if ($game_player.px - @px).abs <= @cx && distance <= @enemy.view && distance >= Sapphire_Core::Enemy_Skill_Distance prepare_link_skill $game_map.skills << Sapphire_Skill.new(self) @recover = @enemy.recover cast_link_skill end when 4 distance = (@px - $game_player.px) if ($game_player.py - @py).abs <= @cx && distance <= @enemy.view && distance >= Sapphire_Core::Enemy_Skill_Distance prepare_link_skill $game_map.skills << Sapphire_Skill.new(self) @recover = @enemy.recover cast_link_skill end when 6 distance = ($game_player.px - @px) if ($game_player.py - @py).abs <= @cx && distance <= @enemy.view && distance >= Sapphire_Core::Enemy_Skill_Distance prepare_link_skill $game_map.skills << Sapphire_Skill.new(self) @recover = @enemy.recover cast_link_skill end when 8 distance = (@py - $game_player.py) if ($game_player.px - @px).abs <= @cx && distance <= @enemy.view && distance >= Sapphire_Core::Enemy_Skill_Distance prepare_link_skill $game_map.skills << Sapphire_Skill.new(self) @recover = @enemy.recover cast_link_skill end end end #-------------------------------------------------------------------------- end #============================================================================== #============================================================================== class Sprite_Character < Sprite_Base #-------------------------------------------------------------------------- def update_src_rect case @character.direction when 2,4,6,8 dir = @character.direction when 1,3 dir = 2 when 7,9 dir = 8 end if @tile_id == 0 index = @character.character_index pattern = @character.pattern < 3 ? @character.pattern : 1 sx = (index % 4 * 3 + pattern) * @cw sy = (index / 4 * 4 + (dir - 2) / 2) * @ch self.src_rect.set(sx, sy, @cw, @ch) end end #-------------------------------------------------------------------------- end #============================================================================== #============================================================================== class Sapphire_Skill #-------------------------------------------------------------------------- attr_reader :disappear attr_reader :mirror attr_reader :start_angle attr_reader :angle_plus #-------------------------------------------------------------------------- alias etude87_sf_initialize initialize def initialize(char) @child_skill = false @range_child = false @move_count = 0 etude87_sf_initialize(char) if @skill.change_direction > 0 case @skill.change_direction when 1 case @direction when 1; @direction = 8 when 3; @direction = 4 when 7; @direction = 6 when 2; @direction = 7 when 4; @direction = 9 when 6; @direction = 1 when 8; @direction = 3 when 9; @direction = 2 end when 2 case @direction when 1; @direction = 7 when 3; @direction = 1 when 7; @direction = 9 when 9; @direction = 3 when 2; @direction = 4 when 4; @direction = 8 when 6; @direction = 2 when 8; @direction = 6 end when 3 case @direction when 1; @direction = 4 when 3; @direction = 2 when 7; @direction = 8 when 9; @direction = 6 when 2; @direction = 1 when 4; @direction = 7 when 6; @direction = 3 when 8; @direction = 9 end when 4 @direction = 10 - @direction when 7 case @direction when 1; @direction = 6 when 3; @direction = 8 when 7; @direction = 2 when 9; @direction = 4 when 2; @direction = 9 when 4; @direction = 3 when 6; @direction = 7 when 8; @direction = 1 end when 8 case @direction when 1; @direction = 3 when 3; @direction = 9 when 7; @direction = 1 when 9; @direction = 7 when 2; @direction = 6 when 4; @direction = 2 when 6; @direction = 8 when 8; @direction = 4 end when 9 case @direction when 1; @direction = 2 when 3; @direction = 6 when 7; @direction = 4 when 9; @direction = 8 when 2; @direction = 3 when 4; @direction = 1 when 6; @direction = 9 when 8; @direction = 7 end end end @disappear = @skill.disappear @mirror = @skill.mirror @start_angle = @skill.start_angle @angle_plus = @skill.angle_plus @reflection_count = @skill.reflection_count if @skill.offset > 0 @skill.offset.times do @px += Tile_Range[@direction][0] @py += Tile_Range[@direction][1] @real_x = @x @real_y = @y @x += Pixel_Range[@direction][0] @y += Pixel_Range[@direction][1] end elsif @skill.offset < 0 @skill.offset.abs.times do @px += Tile_Range[10-@direction][0] @py += Tile_Range[10-@direction][1] @real_x = @x @real_y = @y @x += Pixel_Range[10-@direction][0] @y += Pixel_Range[10-@direction][1] end end end #-------------------------------------------------------------------------- def update move unless moving? return update_move if moving? end #-------------------------------------------------------------------------- def distance_per_frame 2 ** [@move_speed,6].min / 256.0 end #-------------------------------------------------------------------------- def move_pixel ([@move_speed,6].max/6).times do run_move_pixel end if @move_speed > 6 case @move_speed%6 when 1 extra_move(6) when 2 extra_move(3) when 3 extra_move(2) when 4 2.times do extra_move(3) end when 5 extra_move(2) extra_move(5) end end end #-------------------------------------------------------------------------- def extra_move(n) run_move_pixel if Graphics.frame_count % n == 0 end #-------------------------------------------------------------------------- def run_move_pixel return if @last_move cast_particle if @move_count % (@skill.interbal + 1) == 0 if @move_count >= @skill.range && @skill.range > 0 @last_move = true @remaining = 3 if cast_child_skill? && @skill.range_child @range_child = true cast_child_skill end elsif pixel_passable?(@px,@py,@direction) @px += Tile_Range[@direction][0] @py += Tile_Range[@direction][1] @real_x = @x @real_y = @y @x += Pixel_Range[@direction][0] @y += Pixel_Range[@direction][1] else unless reflection?(@px + Tile_Range[@direction][0],@py + Tile_Range[@direction][1]) front_pixel_touch?(@px + Tile_Range[@direction][0],@py + Tile_Range[@direction][1]) @last_move = true @remaining = 3 end end @move_count += 1 end #-------------------------------------------------------------------------- alias etude87_sf_perform_damage perform_damage def perform_damage(char) etude87_sf_perform_damage(char) @child_skill = cast_child_skill? end #-------------------------------------------------------------------------- def reflection?(px,py) return false unless @skill.reflection return false if @reflection_count <= 0 && @skill.reflection_count > 0 if @cast_by_enemy if ($game_player.px - px).abs <= @cx && ($game_player.py - py).abs <= @cy return false end reflection(px,py) else for event in $game_map.enemies if (event.px - px).abs < event.cx && (event.py - py).abs < event.cy next if event.enemy.static return false end end reflection(px,py) end return true end #-------------------------------------------------------------------------- def reflection(px,py) case @direction when 2,4,6,8 @direction = 10 - @direction when 1,9 if pixel_passable?(px,py,3) @direction = 3 else @direction = 7 end when 3,7 if pixel_passable?(px,py,1) @direction = 1 else @direction = 9 end end @reflection_count -= 1 end #-------------------------------------------------------------------------- alias etude87_sf_destroy destroy def destroy if @child_skill == true cast_child_skill else etude87_sf_destroy end end #-------------------------------------------------------------------------- def cast_child_skill? return false unless $data_skills[@skill.child_skill].is_a?(RPG::Skill) return false unless $data_skills[@skill.child_skill].particle return true end #-------------------------------------------------------------------------- def cast_child_skill return unless cast_child_skill? @last_x = @real_x @last_y = @real_y unless @range_child loop do break if @last_x != @real_x or @last_y != @real_y @px += Tile_Range[@direction][0] @py += Tile_Range[@direction][1] @real_x = @x @real_y = @y @x += Pixel_Range[@direction][0] @y += Pixel_Range[@direction][1] end end @skill = $data_skills[@skill.child_skill] @bitmap = @skill.particle @child_skill = false @range_child = false @move_count = 0 @move_speed = @skill.speed @move_frequency = 6 @done = false @last_move = false @remaining = 0 @blend = @skill.blend @water_remaining = 0 RPG::SE.new(@skill.cast_se,Sapphire_Core::Skill_Volume).play unless @skill.cast_se.nil? @disappear = @skill.disappear @mirror = @skill.mirror @start_angle = @skill.start_angle @angle_plus = @skill.angle_plus @reflection_count = @skill.reflection_count end #-------------------------------------------------------------------------- end #============================================================================== #============================================================================== class Sapphire_Particle < Sprite #-------------------------------------------------------------------------- def initialize(key,char) super(nil) @key = key @char = char self.bitmap = Sapphire_Bitcore[@key] self.ox = self.bitmap.width/2 self.oy = self.bitmap.height/2 self.z = 200 if @char.mirror case @char.direction when 3 self.angle = 315 when 2 self.angle = 270 when 9 self.angle = 45 when 4 self.mirror = true when 7 self.mirror = true self.angle = 315 when 8 self.mirror = true self.angle = 270 when 1 self.mirror = true self.angle = 45 end end self.angle += rand(@char.start_angle) @add = rand(@char.angle_plus) @done = false @rx = @char.real_x @ry = @char.real_y self.blend_type = @char.blend @speed = @char.move_speed @start = true end #-------------------------------------------------------------------------- def update self.x = $game_map.adjust_unlx(@rx) * 32 + 16 self.y = $game_map.adjust_unly(@ry) * 32 + 16 if @char.mirror case @char.direction when 2,3,6,9 self.angle += @add else self.angle -= @add end else self.angle += @add end if @start @start = false else if @char.disappear > 0 self.opacity <= 0 ? dispose : self.opacity -= (255.0/@char.disappear) else self.opacity <= 0 ? dispose : self.opacity -= @speed * 5 end end end #-------------------------------------------------------------------------- end