|
  |
NPC Actors, How to make some of your heroes controlled by CPU |
|
|
|
|
Dec 8 2011, 04:56 AM
|

Dark Jentleman

Group: Local Mod
Posts: 904
Type: Scripter
RM Skill: Skilled
Rev Points: 120

|
RPG NPC ActorsAuthor: Jens of Zanicuud Version: 1.0 Released on: 9 Dec 2011 Terms of use: Free use, just credit; for commercial use, you have to ask for permission. Customization: Free, just link the mod version in this topic... FAQ or help:Feel free to ask for everything. Hello everyone again. This time I'll post the Game_NPC script system... It handles with heroes controlled by computer. You can set their actions ratings in the Skill panel... I think it could be useful for host characters or Summons. To use it, just create a new script and paste the code below. N.B. You'll need to download these files and put it in the Icons folder to let this script work.
Icons.zip ( 1.46K )
Number of downloads: 44CODE #============================================================================== # ** Game_NPC Version 1.0 - Jens of Zanicuud # Free use, but credit is needed. You can find me on www.rpgrevolution.com # Just advise me if you want to employ it anywhere #------------------------------------------------------------------------------ # This class handles with actors controlled by CPU... # In Skill Window you can set the rating of their actions. # #==============================================================================
NPC = [5,6] #Set here the IDs of all NPC actors
#============================================================================== # ** Game_Party #------------------------------------------------------------------------------ # This class handles the party. It includes information on amount of gold # and items. Refer to "$game_party" for the instance of this class. #==============================================================================
class Game_Party #-------------------------------------------------------------------------- # * good_health? (i.e. all party with heal greater than 70%) #-------------------------------------------------------------------------- def good_health? flag = true for actor in self.actors if actor.hp*100/actor.maxhp < 70.0 flag = false end end return flag end #-------------------------------------------------------------------------- # * weakest actor (i.e. actors with lesser heal) #-------------------------------------------------------------------------- def weakest_actors_roulette weakest = [self.actors[0]] for actor in self.actors if actor.hp*100/actor.maxhp < weakest[0].hp*100/actor.maxhp weakest = [actor] elsif actor.hp*100/actor.maxhp == weakest[0].hp*100/actor.maxhp weakest.push(actor) end end return weakest[rand(weakest.size)] end end #============================================================================== # ** Game_Game_BattleAction #------------------------------------------------------------------------------ # Added ratings in actions #==============================================================================
class Game_BattleAction #-------------------------------------------------------------------------- # * Public Instance Variables #-------------------------------------------------------------------------- attr_accessor :speed # speed attr_accessor :kind # kind (basic / skill / item) attr_accessor :basic # basic (attack / guard / escape) attr_accessor :skill_id # skill ID attr_accessor :item_id # item ID attr_accessor :target_index # target index attr_accessor :forcing # forced flag attr_accessor :rating # rating #-------------------------------------------------------------------------- # * Object Initialization #-------------------------------------------------------------------------- def initialize clear end #-------------------------------------------------------------------------- # * Clear #-------------------------------------------------------------------------- def clear @speed = 0 @kind = 0 @basic = 3 @skill_id = 0 @item_id = 0 @target_index = -1 @forcing = false @rating = 0 end #-------------------------------------------------------------------------- # * Skill #-------------------------------------------------------------------------- def skill return $data_skills[self.skill_id] end #-------------------------------------------------------------------------- # * Random Target (for NPC) #-------------------------------------------------------------------------- def decide_random_target_for_NPC # Diverge with effect scope #NEW HP check if self.kind == 1 and self.skill.power < 0 if for_one_friend? battler = $game_party.weakest_actors_roulette end end if battler == nil if for_one_friend_hp0? battler = $game_party.random_target_actor_hp0 elsif for_one_friend? battler = $game_party.random_target_actor else battler = $game_troop.random_target_enemy end end # If a target exists, get an index, and if a target doesn't exist, # clear the action if battler != nil @target_index = battler.index else clear end end end
#============================================================================== # ** Game_NPC #------------------------------------------------------------------------------ # This class handles the actor. It's used within the Game_Actors class # ($game_actors) and refers to the Game_Party class ($game_party). #==============================================================================
class Game_NPC < Game_Actor #-------------------------------------------------------------------------- # * Setup # actor_id : actor ID #-------------------------------------------------------------------------- def setup(actor_id) super @rates = {} for i in -3...$data_skills.size @rates[i] = 4 end end #-------------------------------------------------------------------------- # * Actions #-------------------------------------------------------------------------- def actions act = [] for id in self.skills skill = $data_skills[id] ab = Game_BattleAction.new ab.kind = 1 ab.skill_id = skill.id ab.rating = @rates[skill.id] act.push(ab) end ab = Game_BattleAction.new ab.kind = 0 ab.basic = 0 ab.rating = @rates[0] act.push(ab) ab = Game_BattleAction.new ab.kind = 0 ab.basic = 1 ab.rating = @rates[-1] act.push(ab) return act end #-------------------------------------------------------------------------- # * Rates #-------------------------------------------------------------------------- def rates(index) return @rates[index] end #-------------------------------------------------------------------------- # * Change Rates #-------------------------------------------------------------------------- def change_rate(skill_id,rate) @rates[skill_id] = rate end #-------------------------------------------------------------------------- # * Make Action #-------------------------------------------------------------------------- def make_action # Clear current action self.current_action.clear # If unable to move unless self.movable? # End Method return end # Extract current effective actions available_actions = [] rating_max = 0 for action in self.actions # Confirm sp conditions if action.kind == 1 and $data_skills[action.skill_id].sp_cost>self.sp next end # Confirm rating conditions if action.rating == 0 next end #NEW# Stop healing skills to be used if there's no target test_skill = $data_skills[action.skill_id] if action.kind == 1 and test_skill.power < 0 and (test_skill.scope == 3 or test_skill.scope == 4) if $game_party.good_health? next end end # Add this action to applicable conditions available_actions.push(action) if action.rating > rating_max rating_max = action.rating end end # Calculate total with max rating value at 3 (exclude 0 or less) ratings_total = 0 for action in available_actions if action.rating > rating_max - 3 ratings_total += action.rating - (rating_max - 3) end end # If ratings total isn't 0 if ratings_total > 0 # Create random numbers value = rand(ratings_total) # Set things that correspond to created random numbers as current action for action in available_actions if action.rating > rating_max - 3 if value < action.rating - (rating_max - 3) self.current_action.kind = action.kind self.current_action.basic = action.basic self.current_action.skill_id = action.skill_id self.current_action.decide_random_target_for_NPC return else value -= action.rating - (rating_max - 3) end end end end end #-------------------------------------------------------------------------- # * Inputable? #-------------------------------------------------------------------------- def inputable? return false end end
#============================================================================== # ** Game_Actors #------------------------------------------------------------------------------ # This class handles the actor array. Refer to "$game_actors" for each # instance of this class. #==============================================================================
class Game_Actors #-------------------------------------------------------------------------- # * Object Initialization #-------------------------------------------------------------------------- def initialize @data = [] end #-------------------------------------------------------------------------- # * Get Actor # actor_id : actor ID #-------------------------------------------------------------------------- def [](actor_id) if actor_id > 999 or $data_actors[actor_id] == nil return nil end if @data[actor_id] == nil if NPC.include?(actor_id) @data[actor_id] = Game_NPC.new(actor_id) else @data[actor_id] = Game_Actor.new(actor_id) end end return @data[actor_id] end #-------------------------------------------------------------------------- # * Change to NPC # actor_id : actor ID #-------------------------------------------------------------------------- def change_to_NPC(id) @data[id] = Game_NPC.new(id) end end
#============================================================================== # ** Scene_Battle #------------------------------------------------------------------------------ # This class performs battle screen processing. #==============================================================================
class Scene_Battle
#-------------------------------------------------------------------------- # * Start Main Phase #-------------------------------------------------------------------------- def start_phase4 # Shift to phase 4 @phase = 4 # Turn count $game_temp.battle_turn += 1 # Search all battle event pages for index in 0...$data_troops[@troop_id].pages.size # Get event page page = $data_troops[@troop_id].pages[index] # If this page span is [turn] if page.span == 1 # Clear action completed flags $game_temp.battle_event_flags[index] = false end end # Set actor as unselectable @actor_index = -1 @active_battler = nil # Enable party command window @party_command_window.active = false @party_command_window.visible = false # Disable actor command window @actor_command_window.active = false @actor_command_window.visible = false # Set main phase flag $game_temp.battle_main_phase = true # Make enemy action for enemy in $game_troop.enemies enemy.make_action end for actor in $game_party.actors if actor.is_a?(Game_NPC) actor.make_action end end # Make action orders make_action_orders # Shift to step 1 @phase4_step = 1 end end
#============================================================================== # ** Window_Skill #------------------------------------------------------------------------------ # This window displays usable skills on the skill and battle screens. #==============================================================================
class Window_Skill < Window_Selectable #-------------------------------------------------------------------------- # * Refresh #-------------------------------------------------------------------------- def refresh if self.contents != nil self.contents.dispose self.contents = nil end @data = [] @data.push("Attacco") if @actor.is_a?(Game_NPC) @data.push("Guardia") if @actor.is_a?(Game_NPC) for i in 0...@actor.skills.size skill = $data_skills[@actor.skills[i]] if skill != nil @data.push(skill) end end # If item count is not 0, make a bit map and draw all items @item_max = @data.size if @item_max > 0 self.contents = Bitmap.new(width - 32, row_max * 32) for i in 0...@item_max draw_item(i) end end end #-------------------------------------------------------------------------- # * Draw Item # index : item number #-------------------------------------------------------------------------- def draw_item(index) skill = @data[index] if skill.is_a?(String) case skill when "Attacco" id = 0 when "Guardia" id = -1 end self.contents.font.color = normal_color x = 4 + index % 2 * (288 + 32) y = index / 2 * 32 rect = Rect.new(x, y, self.width / @column_max - 32, 32) self.contents.fill_rect(rect, Color.new(0, 0, 0, 0)) case @actor.rates(id) when 5 bitmap = RPG::Cache.icon("High") when 4 bitmap = RPG::Cache.icon("Medium") when 3 bitmap = RPG::Cache.icon("Low") when 0 bitmap = RPG::Cache.icon("Never") end opacity = 255 self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24), opacity) self.contents.draw_text(x + 28, y, 204, 32, skill, 0) else if @actor.skill_can_use?(skill.id) or @actor.is_a?(Game_NPC) self.contents.font.color = normal_color else self.contents.font.color = disabled_color end x = 4 + index % 2 * (288 + 32) y = index / 2 * 32 rect = Rect.new(x, y, self.width / @column_max - 32, 32) self.contents.fill_rect(rect, Color.new(0, 0, 0, 0)) if @actor.is_a?(Game_NPC) case @actor.rates(skill.id) when 5 bitmap = RPG::Cache.icon("High") when 4 bitmap = RPG::Cache.icon("Medium") when 3 bitmap = RPG::Cache.icon("Low") when 0 bitmap = RPG::Cache.icon("Never") end else bitmap = RPG::Cache.icon(skill.icon_name) end opacity = self.contents.font.color == normal_color ? 255 : 128 self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24), opacity) self.contents.draw_text(x + 28, y, 204, 32, skill.name, 0) self.contents.draw_text(x + 232, y, 48, 32, skill.sp_cost.to_s, 2) end end #-------------------------------------------------------------------------- # * Help Text Update #-------------------------------------------------------------------------- def update_help if self.skill == "Attack" description = "Regular attack with equipped weapon." elsif self.skill == "Guard" description = "Halves damage received." else description = self.skill.description if self.skill != nil end @help_window.set_text(description == nil ? "" : description ) end end
#============================================================================== # ** Scene_Skill #------------------------------------------------------------------------------ # This class performs skill screen processing. #==============================================================================
class Scene_Skill #-------------------------------------------------------------------------- # * Object Initialization # actor_index : actor index #-------------------------------------------------------------------------- def initialize(actor_index = 0, equip_index = 0) @actor_index = actor_index end #-------------------------------------------------------------------------- # * Main Processing #-------------------------------------------------------------------------- def main # Get actor @actor = $game_party.actors[@actor_index] # Make help window, status window, and skill window @help_window = Window_Help.new @status_window = Window_SkillStatus.new(@actor) @skill_window = Window_Skill.new(@actor) # Associate help window @skill_window.help_window = @help_window # Make target window (set to invisible / inactive) @target_window = Window_Target.new @target_window.visible = false @target_window.active = false # Execute transition Graphics.transition # Main loop loop do # Update game screen Graphics.update # Update input information Input.update # Frame update update # Abort loop if screen is changed if $scene != self break end end # Prepare for transition Graphics.freeze # Dispose of windows @help_window.dispose @status_window.dispose @skill_window.dispose @target_window.dispose end #-------------------------------------------------------------------------- # * Frame Update #-------------------------------------------------------------------------- def update # Update windows @help_window.update @status_window.update @skill_window.update @target_window.update # If skill window is active: call update_skill if @skill_window.active update_skill return end # If skill target is active: call update_target if @target_window.active update_target return end end #-------------------------------------------------------------------------- # * Frame Update (if skill window is active) #-------------------------------------------------------------------------- def update_skill # If B button was pressed if Input.trigger?(Input::B) # Play cancel SE $game_system.se_play($data_system.cancel_se) # Switch to menu screen $scene = Scene_Menu.new(1) return end # If C button was pressed if @actor.is_a?(Game_NPC) if Input.trigger?(Input::C) $game_system.se_play($data_system.decision_se) @skill = @skill_window.skill if @skill_window.index > 0 update_command return end else if Input.trigger?(Input::C) # Get currently selected data on the skill window @skill = @skill_window.skill # If unable to use if @skill == nil or not @actor.skill_can_use?(@skill.id) # Play buzzer SE $game_system.se_play($data_system.buzzer_se) return end # Play decision SE $game_system.se_play($data_system.decision_se) # If effect scope is ally if @skill.scope >= 3 # Activate target window @skill_window.active = false @target_window.x = (@skill_window.index + 1) % 2 * 304 @target_window.visible = true @target_window.active = true # Set cursor position to effect scope (single / all) if @skill.scope == 4 || @skill.scope == 6 @target_window.index = -1 elsif @skill.scope == 7 @target_window.index = @actor_index - 10 else @target_window.index = 0 end # If effect scope is other than ally else # If common event ID is valid if @skill.common_event_id > 0 # Common event call reservation $game_temp.common_event_id = @skill.common_event_id # Play use skill SE $game_system.se_play(@skill.menu_se) # Use up SP @actor.sp -= @skill.sp_cost # Remake each window content @status_window.refresh @skill_window.refresh @target_window.refresh # Switch to map screen $scene = Scene_Map.new return end end return end end # If R button was pressed if Input.trigger?(Input::R) # Play cursor SE $game_system.se_play($data_system.cursor_se) # To next actor @actor_index += 1 @actor_index %= $game_party.actors.size # Switch to different skill screen $scene = Scene_Skill.new(@actor_index) return end # If L button was pressed if Input.trigger?(Input::L) # Play cursor SE $game_system.se_play($data_system.cursor_se) # To previous actor @actor_index += $game_party.actors.size - 1 @actor_index %= $game_party.actors.size # Switch to different skill screen $scene = Scene_Skill.new(@actor_index) return end end #-------------------------------------------------------------------------- # * Frame Update (when target window is active) #-------------------------------------------------------------------------- def update_target # If B button was pressed if Input.trigger?(Input::B) # Play cancel SE $game_system.se_play($data_system.cancel_se) # Erase target window @skill_window.active = true @target_window.visible = false @target_window.active = false return end # If C button was pressed if Input.trigger?(Input::C) # If unable to use because SP ran out unless @actor.skill_can_use?(@skill.id) # Play buzzer SE $game_system.se_play($data_system.buzzer_se) return end # If target is all if @target_window.index == -1 # Apply skill use effects to entire party used = false for i in $game_party.actors used |= i.skill_effect(@actor, @skill) end end # If target is user if @target_window.index <= -2 # Apply skill use effects to target actor target = $game_party.actors[@target_window.index + 10] used = target.skill_effect(@actor, @skill) end # If single target if @target_window.index >= 0 # Apply skill use effects to target actor target = $game_party.actors[@target_window.index] used = target.skill_effect(@actor, @skill) end # If skill was used if used # Play skill use SE $game_system.se_play(@skill.menu_se) # Use up SP @actor.sp -= @skill.sp_cost # Remake each window content @status_window.refresh @skill_window.refresh @target_window.refresh # If entire party is dead if $game_party.all_dead? # Switch to game over screen $scene = Scene_Gameover.new return end # If command event ID is valid if @skill.common_event_id > 0 # Command event call reservation $game_temp.common_event_id = @skill.common_event_id # Switch to map screen $scene = Scene_Map.new return end end # If skill wasn't used unless used # Play buzzer SE $game_system.se_play($data_system.buzzer_se) end return end end #-------------------------------------------------------------------------- # * Frame Update (when arrow window is active) #-------------------------------------------------------------------------- def update_command if @skill_window.index == 0 rate = 0 elsif @skill_window.index == 1 rate = -1 else rate = @skill.id end case @actor.rates(rate) when 0 rate = 3 when 3 rate = 4 when 4 rate = 5 when 5 rate = 0 end if @skill_window.index == 0 @actor.change_rate(0,rate) elsif @skill_window.index == 1 @actor.change_rate(-1,rate) else @actor.change_rate(@skill.id,rate) end @skill_window.refresh return end end That's all folks! I hope it can be useful. See you next script... Jens
This post has been edited by Jens of Zanicuud: Dec 10 2011, 04:51 AM
__________________________
|
|
|
|
|
|
|
|
|
Dec 9 2011, 07:32 PM
|

Level 50

Group: +Gold Member
Posts: 1,518
Type: Scripter
RM Skill: Undisclosed

|
You define the NPC array twice, once on line 11 and once on line 180. I also had a problem where the NPC's aren't very smart, my Cleric decided to try and heal party members that had completely full HP. Otherwise, I really like the premise of the script, and I'm sure it'll come in useful for some people
__________________________
K.I.S.S. Want help with your scripting problems? Upload a demo! Or at the very least; provide links to the scripts in question. Most important guide ever: Newbie's Guide to Switches
|
|
|
|
|
|
|
|
|
Dec 10 2011, 01:44 AM
|

Dark Jentleman

Group: Local Mod
Posts: 904
Type: Scripter
RM Skill: Skilled
Rev Points: 120

|
QUOTE (Night_Runner @ Dec 10 2011, 04:32 AM)  You define the NPC array twice, once on line 11 and once on line 180. I also had a problem where the NPC's aren't very smart, my Cleric decided to try and heal party members that had completely full HP. Otherwise, I really like the premise of the script, and I'm sure it'll come in useful for some people  Yeah, I actually recicled enemies' AI, but can be SERIOUSLY improved... Well, actually I made enemies smarter, but as regards NPC... The problem is that I haven't tested it with healing skills, just offensive. I'll fix the double declaration bug quickly, then... When the New AI system will be complete, I will just post it in this section or edit the previous script. Thanks for support and help. Jens EDIT: Ok, Night Runner, I've updated the script. Now your Mystic won't cure if there's no need. I've just modified the script in the first topic of the post. In fact, there's still a problem as regards healing altered status, but I hope to solve it quinckly, just some other manipulation... I've created this script for a project in which magic didn't exist, so I forgot to fix that healing issue. Major updates will come soon (i.e. item usage and stuff like this...) Please, give feedback! Jens
This post has been edited by Jens of Zanicuud: Dec 10 2011, 04:55 AM
__________________________
|
|
|
|
|
|
|
|
|
Dec 10 2011, 07:20 AM
|

Dark Jentleman

Group: Local Mod
Posts: 904
Type: Scripter
RM Skill: Skilled
Rev Points: 120

|
RPG NPC Actors v 1.2 Author: Jens of Zanicuud Version: 1.2 Released on: 9 Dec 2011 Terms of use: Free use, just credit; for commercial use, you have to ask for permission. Customization: Free, just link the mod version in this topic... FAQ or help:Feel free to ask for everything. Ok, guys, some bug fixed and some features added... Let me explain... -NPC will heal only if necessary; -NPC will heal status only if necessary; -NPC will cast status like Sharpen, Barrier and so on only if needed; -RATINGS relative to frequency can be customized to privilege High Rating or equilibrating the whole of them.N.B. Icons posted before are mandatory to use this script... New code: CODE #============================================================================== # ** Game_NPC Version 1.2 - Jens of Zanicuud # Free use, but credit is needed. You can find me on www.rpgrevolution.com # Just advise me if you want to employ it anywhere #------------------------------------------------------------------------------ # This class handles with actors controlled by CPU... # In Skill Window you can set the rating of their actions. # #==============================================================================
NPC = [5,6] #Set here the IDs of all NPC actors RATES = [0,3,5,7] #Set here the ratings for Never/Low/Medium/High priority HEAL_RATE = 70.0 #Set here the heal rate, i.e. the hp percentage below which NPC will cure (a float is better than a int...)
#============================================================================== # ** Game_Party #------------------------------------------------------------------------------ # This class handles the party. It includes information on amount of gold # and items. Refer to "$game_party" for the instance of this class. #==============================================================================
class Game_Party #-------------------------------------------------------------------------- # * good_health? (i.e. all party with heal greater than 70%) #-------------------------------------------------------------------------- def good_health? flag = true for actor in self.actors if actor.hp*100/actor.maxhp < HEAL_RATE flag = false end end return flag end #-------------------------------------------------------------------------- # * weakest actor (i.e. actors with lesser heal) #-------------------------------------------------------------------------- def weakest_actors_roulette weakest = [self.actors[0]] for actor in self.actors if actor.hp*100/actor.maxhp < weakest[0].hp*100/actor.maxhp weakest = [actor] elsif actor.hp*100/actor.maxhp == weakest[0].hp*100/actor.maxhp weakest.push(actor) end end return weakest[rand(weakest.size)] end #-------------------------------------------------------------------------- # * random actor with a specified status #-------------------------------------------------------------------------- def rand_act_status(id) state = [] for actor in self.actors if actor.state?(id) state.push(actor) end end return state[rand(state.size)] end #-------------------------------------------------------------------------- # * random actor with a specified status in a skill selection #-------------------------------------------------------------------------- def rand_act_status_max(skill) state = [] for id in skill.minus_state_set for actor in self.actors if actor.state?(id) state.push(actor) end end end return state[rand(state.size)] end #-------------------------------------------------------------------------- # * random actor without a specified status #-------------------------------------------------------------------------- def rand_act_non_status(id) state = [] for actor in self.actors if !actor.state?(id) state.push(actor) end end return state[rand(state.size)] end #-------------------------------------------------------------------------- # * random actor without a specified status in a skill selection #-------------------------------------------------------------------------- def rand_act_non_status_max(skill) state = [] for id in skill.plus_state_set for actor in self.actors if !actor.state?(id) state.push(actor) end end end return state[rand(state.size)] end end #============================================================================== # ** Game_Game_BattleAction #------------------------------------------------------------------------------ # Added ratings in actions #==============================================================================
class Game_BattleAction #-------------------------------------------------------------------------- # * Public Instance Variables #-------------------------------------------------------------------------- attr_accessor :speed # speed attr_accessor :kind # kind (basic / skill / item) attr_accessor :basic # basic (attack / guard / escape) attr_accessor :skill_id # skill ID attr_accessor :item_id # item ID attr_accessor :target_index # target index attr_accessor :forcing # forced flag attr_accessor :rating # rating #-------------------------------------------------------------------------- # * Object Initialization #-------------------------------------------------------------------------- def initialize clear end #-------------------------------------------------------------------------- # * Clear #-------------------------------------------------------------------------- def clear @speed = 0 @kind = 0 @basic = 3 @skill_id = 0 @item_id = 0 @target_index = -1 @forcing = false @rating = 0 end #-------------------------------------------------------------------------- # * Skill #-------------------------------------------------------------------------- def skill return $data_skills[self.skill_id] end #-------------------------------------------------------------------------- # * Random Target (for NPC) #-------------------------------------------------------------------------- def decide_random_target_for_NPC # Diverge with effect scope #NEW HP check if self.kind == 1 and self.skill.power < 0 if for_one_friend? battler = $game_party.weakest_actors_roulette end end #NEW state minus check if battler == nil if self.kind == 1 and self.skill.minus_state_set.size != 0 if for_one_friend? battler = $game_party.rand_act_status_max(skill) end end end #NEW state plus check if battler == nil if self.kind == 1 and self.skill.plus_state_set.size != 0 if for_one_friend? battler = $game_party.rand_act_non_status_max(skill) end end end if battler == nil if for_one_friend_hp0? battler = $game_party.random_target_actor_hp0 elsif for_one_friend? battler = $game_party.random_target_actor else battler = $game_troop.random_target_enemy end end # If a target exists, get an index, and if a target doesn't exist, # clear the action if battler != nil @target_index = battler.index else clear end end end
#============================================================================== # ** Game_NPC #------------------------------------------------------------------------------ # This class handles the actor. It's used within the Game_Actors class # ($game_actors) and refers to the Game_Party class ($game_party). #==============================================================================
class Game_NPC < Game_Actor #-------------------------------------------------------------------------- # * Setup # actor_id : actor ID #-------------------------------------------------------------------------- def setup(actor_id) super @rates = {} for i in -3...$data_skills.size @rates[i] = RATES[2] #Set default value to Medium end end #-------------------------------------------------------------------------- # * Actions #-------------------------------------------------------------------------- def actions act = [] for id in self.skills skill = $data_skills[id] ab = Game_BattleAction.new ab.kind = 1 ab.skill_id = skill.id ab.rating = @rates[skill.id] act.push(ab) end ab = Game_BattleAction.new ab.kind = 0 ab.basic = 0 ab.rating = @rates[0] act.push(ab) ab = Game_BattleAction.new ab.kind = 0 ab.basic = 1 ab.rating = @rates[-1] act.push(ab) return act end #-------------------------------------------------------------------------- # * Rates #-------------------------------------------------------------------------- def rates(index) return @rates[index] end #-------------------------------------------------------------------------- # * Change Rates #-------------------------------------------------------------------------- def change_rate(skill_id,rate) @rates[skill_id] = rate end #-------------------------------------------------------------------------- # * Make Action #-------------------------------------------------------------------------- def make_action # Clear current action self.current_action.clear # If unable to move unless self.movable? # End Method return end # Extract current effective actions available_actions = [] rating_max = 0 for action in self.actions # Confirm sp conditions if action.kind == 1 and $data_skills[action.skill_id].sp_cost>self.sp next end # Confirm rating conditions if action.rating == 0 next end #NEW# Stop healing skills to be used if there's no target test_skill = $data_skills[action.skill_id] if action.kind == 1 and test_skill.power < 0 and (test_skill.scope == 3 or test_skill.scope == 4) if $game_party.good_health? next end end #NEW# Stop healing status if there's no target test_skill = $data_skills[action.skill_id] if action.kind == 1 and test_skill.minus_state_set.size != 0 and (test_skill.scope == 3 or test_skill.scope == 4) flag = false for id in test_skill.minus_state_set if $game_party.rand_act_status(id) != nil flag = true end end if !flag next end end #NEW# Stop giving status if there's no target test_skill = $data_skills[action.skill_id] if action.kind == 1 and test_skill.plus_state_set.size != 0 and (test_skill.scope == 3 or test_skill.scope == 4) flag = false for id in test_skill.plus_state_set if $game_party.rand_act_non_status(id) != nil flag = true end end if !flag next end end # Add this action to applicable conditions available_actions.push(action) if action.rating > rating_max rating_max = action.rating end end # Calculate total with max rating value at 4 (exclude 0 or less) ratings_total = 0 for action in available_actions if action.rating > rating_max - 4 ratings_total += action.rating - (rating_max - 4) end end # If ratings total isn't 0 if ratings_total > 0 # Create random numbers value = rand(ratings_total) # Set things that correspond to created random numbers as current action for action in available_actions if action.rating > rating_max - 4 if value < action.rating - (rating_max - 4) self.current_action.kind = action.kind self.current_action.basic = action.basic self.current_action.skill_id = action.skill_id self.current_action.decide_random_target_for_NPC return else value -= action.rating - (rating_max - 4) end end end end end #-------------------------------------------------------------------------- # * Inputable? #-------------------------------------------------------------------------- def inputable? return false end end
#============================================================================== # ** Game_Actors #------------------------------------------------------------------------------ # This class handles the actor array. Refer to "$game_actors" for each # instance of this class. #==============================================================================
class Game_Actors #-------------------------------------------------------------------------- # * Object Initialization #-------------------------------------------------------------------------- def initialize @data = [] end #-------------------------------------------------------------------------- # * Get Actor # actor_id : actor ID #-------------------------------------------------------------------------- def [](actor_id) if actor_id > 999 or $data_actors[actor_id] == nil return nil end if @data[actor_id] == nil if NPC.include?(actor_id) @data[actor_id] = Game_NPC.new(actor_id) else @data[actor_id] = Game_Actor.new(actor_id) end end return @data[actor_id] end #-------------------------------------------------------------------------- # * Change to NPC # actor_id : actor ID #-------------------------------------------------------------------------- def change_to_NPC(id) @data[id] = Game_NPC.new(id) end end
#============================================================================== # ** Scene_Battle #------------------------------------------------------------------------------ # This class performs battle screen processing. #==============================================================================
class Scene_Battle
#-------------------------------------------------------------------------- # * Start Main Phase #-------------------------------------------------------------------------- def start_phase4 # Shift to phase 4 @phase = 4 # Turn count $game_temp.battle_turn += 1 # Search all battle event pages for index in 0...$data_troops[@troop_id].pages.size # Get event page page = $data_troops[@troop_id].pages[index] # If this page span is [turn] if page.span == 1 # Clear action completed flags $game_temp.battle_event_flags[index] = false end end # Set actor as unselectable @actor_index = -1 @active_battler = nil # Enable party command window @party_command_window.active = false @party_command_window.visible = false # Disable actor command window @actor_command_window.active = false @actor_command_window.visible = false # Set main phase flag $game_temp.battle_main_phase = true # Make enemy action for enemy in $game_troop.enemies enemy.make_action end for actor in $game_party.actors if actor.is_a?(Game_NPC) actor.make_action end end # Make action orders make_action_orders # Shift to step 1 @phase4_step = 1 end end
#============================================================================== # ** Window_Skill #------------------------------------------------------------------------------ # This window displays usable skills on the skill and battle screens. #==============================================================================
class Window_Skill < Window_Selectable #-------------------------------------------------------------------------- # * Refresh #-------------------------------------------------------------------------- def refresh if self.contents != nil self.contents.dispose self.contents = nil end @data = [] @data.push("Attack") if @actor.is_a?(Game_NPC) @data.push("Guard") if @actor.is_a?(Game_NPC) for i in 0...@actor.skills.size skill = $data_skills[@actor.skills[i]] if skill != nil @data.push(skill) end end # If item count is not 0, make a bit map and draw all items @item_max = @data.size if @item_max > 0 self.contents = Bitmap.new(width - 32, row_max * 32) for i in 0...@item_max draw_item(i) end end end #-------------------------------------------------------------------------- # * Draw Item # index : item number #-------------------------------------------------------------------------- def draw_item(index) skill = @data[index] if skill.is_a?(String) case skill when "Attack" id = 0 when "Guard" id = -1 end self.contents.font.color = normal_color x = 4 + index % 2 * (288 + 32) y = index / 2 * 32 rect = Rect.new(x, y, self.width / @column_max - 32, 32) self.contents.fill_rect(rect, Color.new(0, 0, 0, 0)) case @actor.rates(id) when RATES[3] #High bitmap = RPG::Cache.icon("High") when RATES[2] #Medium bitmap = RPG::Cache.icon("Medium") when RATES[1] #Low bitmap = RPG::Cache.icon("Low") when RATES[0] #Never bitmap = RPG::Cache.icon("Never") end opacity = 255 self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24), opacity) self.contents.draw_text(x + 28, y, 204, 32, skill, 0) else if @actor.skill_can_use?(skill.id) or @actor.is_a?(Game_NPC) self.contents.font.color = normal_color else self.contents.font.color = disabled_color end x = 4 + index % 2 * (288 + 32) y = index / 2 * 32 rect = Rect.new(x, y, self.width / @column_max - 32, 32) self.contents.fill_rect(rect, Color.new(0, 0, 0, 0)) if @actor.is_a?(Game_NPC) case @actor.rates(skill.id) when RATES[3] #High bitmap = RPG::Cache.icon("High") when RATES[2] #Medium bitmap = RPG::Cache.icon("Medium") when RATES[1] #Low bitmap = RPG::Cache.icon("Low") when RATES[0] #Nevet bitmap = RPG::Cache.icon("Never") end else bitmap = RPG::Cache.icon(skill.icon_name) end opacity = self.contents.font.color == normal_color ? 255 : 128 self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24), opacity) self.contents.draw_text(x + 28, y, 204, 32, skill.name, 0) self.contents.draw_text(x + 232, y, 48, 32, skill.sp_cost.to_s, 2) end end #-------------------------------------------------------------------------- # * Help Text Update #-------------------------------------------------------------------------- def update_help if self.skill == "Attack" description = "Regular attack with equipped weapon." elsif self.skill == "Guard" description = "Halves damage received." else description = self.skill.description if self.skill != nil end @help_window.set_text(description == nil ? "" : description ) end end
#============================================================================== # ** Scene_Skill #------------------------------------------------------------------------------ # This class performs skill screen processing. #==============================================================================
class Scene_Skill #-------------------------------------------------------------------------- # * Object Initialization # actor_index : actor index #-------------------------------------------------------------------------- def initialize(actor_index = 0, equip_index = 0) @actor_index = actor_index end #-------------------------------------------------------------------------- # * Main Processing #-------------------------------------------------------------------------- def main # Get actor @actor = $game_party.actors[@actor_index] # Make help window, status window, and skill window @help_window = Window_Help.new @status_window = Window_SkillStatus.new(@actor) @skill_window = Window_Skill.new(@actor) # Associate help window @skill_window.help_window = @help_window # Make target window (set to invisible / inactive) @target_window = Window_Target.new @target_window.visible = false @target_window.active = false # Execute transition Graphics.transition # Main loop loop do # Update game screen Graphics.update # Update input information Input.update # Frame update update # Abort loop if screen is changed if $scene != self break end end # Prepare for transition Graphics.freeze # Dispose of windows @help_window.dispose @status_window.dispose @skill_window.dispose @target_window.dispose end #-------------------------------------------------------------------------- # * Frame Update #-------------------------------------------------------------------------- def update # Update windows @help_window.update @status_window.update @skill_window.update @target_window.update # If skill window is active: call update_skill if @skill_window.active update_skill return end # If skill target is active: call update_target if @target_window.active update_target return end end #-------------------------------------------------------------------------- # * Frame Update (if skill window is active) #-------------------------------------------------------------------------- def update_skill # If B button was pressed if Input.trigger?(Input::B) # Play cancel SE $game_system.se_play($data_system.cancel_se) # Switch to menu screen $scene = Scene_Menu.new(1) return end # If C button was pressed if @actor.is_a?(Game_NPC) if Input.trigger?(Input::C) $game_system.se_play($data_system.decision_se) @skill = @skill_window.skill if @skill_window.index > 0 update_command return end else if Input.trigger?(Input::C) # Get currently selected data on the skill window @skill = @skill_window.skill # If unable to use if @skill == nil or not @actor.skill_can_use?(@skill.id) # Play buzzer SE $game_system.se_play($data_system.buzzer_se) return end # Play decision SE $game_system.se_play($data_system.decision_se) # If effect scope is ally if @skill.scope >= 3 # Activate target window @skill_window.active = false @target_window.x = (@skill_window.index + 1) % 2 * 304 @target_window.visible = true @target_window.active = true # Set cursor position to effect scope (single / all) if @skill.scope == 4 || @skill.scope == 6 @target_window.index = -1 elsif @skill.scope == 7 @target_window.index = @actor_index - 10 else @target_window.index = 0 end # If effect scope is other than ally else # If common event ID is valid if @skill.common_event_id > 0 # Common event call reservation $game_temp.common_event_id = @skill.common_event_id # Play use skill SE $game_system.se_play(@skill.menu_se) # Use up SP @actor.sp -= @skill.sp_cost # Remake each window content @status_window.refresh @skill_window.refresh @target_window.refresh # Switch to map screen $scene = Scene_Map.new return end end return end end # If R button was pressed if Input.trigger?(Input::R) # Play cursor SE $game_system.se_play($data_system.cursor_se) # To next actor @actor_index += 1 @actor_index %= $game_party.actors.size # Switch to different skill screen $scene = Scene_Skill.new(@actor_index) return end # If L button was pressed if Input.trigger?(Input::L) # Play cursor SE $game_system.se_play($data_system.cursor_se) # To previous actor @actor_index += $game_party.actors.size - 1 @actor_index %= $game_party.actors.size # Switch to different skill screen $scene = Scene_Skill.new(@actor_index) return end end #-------------------------------------------------------------------------- # * Frame Update (when target window is active) #-------------------------------------------------------------------------- def update_target # If B button was pressed if Input.trigger?(Input::B) # Play cancel SE $game_system.se_play($data_system.cancel_se) # Erase target window @skill_window.active = true @target_window.visible = false @target_window.active = false return end # If C button was pressed if Input.trigger?(Input::C) # If unable to use because SP ran out unless @actor.skill_can_use?(@skill.id) # Play buzzer SE $game_system.se_play($data_system.buzzer_se) return end # If target is all if @target_window.index == -1 # Apply skill use effects to entire party used = false for i in $game_party.actors used |= i.skill_effect(@actor, @skill) end end # If target is user if @target_window.index <= -2 # Apply skill use effects to target actor target = $game_party.actors[@target_window.index + 10] used = target.skill_effect(@actor, @skill) end # If single target if @target_window.index >= 0 # Apply skill use effects to target actor target = $game_party.actors[@target_window.index] used = target.skill_effect(@actor, @skill) end # If skill was used if used # Play skill use SE $game_system.se_play(@skill.menu_se) # Use up SP @actor.sp -= @skill.sp_cost # Remake each window content @status_window.refresh @skill_window.refresh @target_window.refresh # If entire party is dead if $game_party.all_dead? # Switch to game over screen $scene = Scene_Gameover.new return end # If command event ID is valid if @skill.common_event_id > 0 # Command event call reservation $game_temp.common_event_id = @skill.common_event_id # Switch to map screen $scene = Scene_Map.new return end end # If skill wasn't used unless used # Play buzzer SE $game_system.se_play($data_system.buzzer_se) end return end end #-------------------------------------------------------------------------- # * Frame Update (when arrow window is active) #-------------------------------------------------------------------------- def update_command if @skill_window.index == 0 rate = 0 elsif @skill_window.index == 1 rate = -1 else rate = @skill.id end #case @actor.rates(rate) #when RATES[0] #rate = RATES[1] #when RATES[1] #rate = RATES[2] #when RATES[2] #rate = RATES[3] #when RATES[3] #rate = RATES[0] #end for i in 0...RATES.size if @actor.rates(rate) == RATES[i] rate = RATES[(i+1)%RATES.size] break end end if @skill_window.index == 0 @actor.change_rate(0,rate) elsif @skill_window.index == 1 @actor.change_rate(-1,rate) else @actor.change_rate(@skill.id,rate) end @skill_window.refresh return end end Still, it isn't a major improvement, but is better than before... Thanks a lot Night Runner for your input! See you next script... Jens EDIT:Now we have customizable heal rate, as required... Script was updated succesfully:) Jens
This post has been edited by Jens of Zanicuud: Dec 11 2011, 03:13 AM
__________________________
|
|
|
|
|
|
|
|
|
Dec 10 2011, 07:28 PM
|

~Noctem~Shinai~

Group: Revolutionary
Posts: 261
Type: Developer
RM Skill: Advanced

|
Can you not customize them to heal on a certain condition specificly like 37% or some odd number of hp?
This post has been edited by carnie_natas: Dec 10 2011, 07:38 PM
__________________________
Light one up! You can run.....But you'll only die tired!
|
|
|
|
|
|
|
|
|
Dec 11 2011, 03:10 AM
|

Dark Jentleman

Group: Local Mod
Posts: 904
Type: Scripter
RM Skill: Skilled
Rev Points: 120

|
QUOTE (carnie_natas @ Dec 11 2011, 04:28 AM)  Can you not customize them to heal on a certain condition specificly like 37% or some odd number of hp? Sure, just modify a number... Well, actually the method that handles with this is class Game_Party def good_health? flag = true for actor in self.actors if actor.hp*100/actor.maxhp < 70.0 flag = false end end return flag end If you switch that 70.0 with the percentage you need, you'll have the effect you asked for:) Maybe this worths a correction between the script, like adding a constant... I'll do this soon... Jens
__________________________
|
|
|
|
|
|
|
|
  |
1 User(s) are reading this topic (1 Guests and 0 Anonymous Users)
0 Members:
RPG RPG Revolution is an Privacy
Policy and Legal
|
|