[RGSS3] Help skill does different things with different state

Discussion in 'Learning Ruby and RGSSx' started by Alyon93, Aug 18, 2015.

  1. Another Fen

    Another Fen Veteran Veteran

    Messages:
    530
    Likes Received:
    244
    First Language:
    German
    return true if item.for_immovable?

    would accept any target when the item is marked for immovables. To restrict the use on movable targets, you could go with this for example:

    return false if item.for_immovable? && movable?

    If you don't want the other restrictions to apply when the movable condition is fulfilled, you can use

    return true if item.for_immovable? && !movable?

    instead.
     
    Last edited by a moderator: Aug 27, 2015
    #21
  2. Alyon93

    Alyon93 Veteran Veteran

    Messages:
    62
    Likes Received:
    2
    Location:
    Milano(MI), Italy
    First Language:
    Italian
    Primarily Uses:
    N/A
    Okay now it's doing something strange. 

    It's working but not as intended. 

    If I target an actor dead in a previous turn it doesn't do anything. 

    Instead it revives the last actor died in the turn you use the "Help" Skill whether or not it is the target. 

    Also no animation is shown.

    Here is the script as it is right now:

    Code:
    $imported = {} if $imported.nil?$imported['ALYON-Help'] = truemodule ALYON_HLP  module REGEXP    # DO NOT CHANGE (unless you know what you're doing)    # This defines the regular expression used to identify grab skills    POISON = /<(?:poison)>/i  endend#==============================================================================# ** RPG::BaseItem#==============================================================================class RPG::State < RPG::BaseItem  def poison?    return !(note =~ ALYON_HLP::REGEXP::POISON).nil?  endend#==============================================================================# ** RPG::UsableItem#==============================================================================class RPG::UsableItem  # This new method returns true if the items notebox  # contains the sequence '<target immovable>'  def for_unmovable?    note.include?("<target unmovable>")  endend#==============================================================================# ** Game_Unit#==============================================================================class Game_Unit  #--------------------------------------------------------------------------  # * overwrites smooth_target metod  #--------------------------------------------------------------------------  def smooth_target(index)    member = members[index]    #(member && member.alive?) ? member : alive_members[0]  endend#==============================================================================# ** Game_Battler#==============================================================================class Game_Battler  #--------------------------------------------------------------------------  # * overwrites use_item metod  #--------------------------------------------------------------------------  alias_method(:use_item_alias_storeUser, :use_item)  def use_item(item)    use_item_alias_storeUser(item)     $game_variables[16] = self  end    #--------------------------------------------------------------------------  # * overwrites item_apply metod  #--------------------------------------------------------------------------  alias_method(:item_apply_storeTarget, :item_apply)  def item_apply(user, item)    item_apply_storeTarget(user, item)    $game_variables[15] = self  end    #--------------------------------------------------------------------------  # * overwrites item_test metod  #--------------------------------------------------------------------------  def item_test(user, item)    return false if item.for_dead_friend? != dead?    return true if $game_party.in_battle    return true if item.for_opponent?    return true if item.damage.recover? && item.damage.to_hp? && hp < mhp    return true if item.damage.recover? && item.damage.to_mp? && mp < mmp    return true if item_has_any_valid_effects?(user, item)    return false if item.for_immovable? && movable?    return false  endend#==============================================================================# ** Game_Actor#==============================================================================class Game_Actor < Game_Battler  def help(subject)    if subject.death_state?      if subject.state?(2) && $game_party.has_item?($data_items[6])        $game_party.consume_item($data_items[6])        subject.remove_state(2)        subject.remove_state(1)        if $game_party.has_item?($data_items[18])          subject.hp += (0.25 * subject.mhp).round          $game_party.consume_item($data_items[18])        elsif $game_party.has_item?($data_items[3])          subject.hp += (1.00 * subject.mhp).round          $game_party.consume_item($data_items[3])        end      elsif subject.state?(4) && $game_party.has_item?($data_items[6])        $game_party.consume_item($data_items[6])        subject.remove_state(2)        subject.remove_state(1)        if $game_party.has_item?($data_items[18])          subject.hp += (0.25 * subject.mhp).round          $game_party.consume_item($data_items[18])        elsif $game_party.has_item?($data_items[3])          subject.hp += (1.00 * subject.mhp).round          $game_party.consume_item($data_items[3])        end      else        subject.remove_state(1)        if $game_party.has_item?($data_items[18])          subject.hp += (0.25 * subject.mhp).round          $game_party.consume_item($data_items[18])        elsif $game_party.has_item?($data_items[3])          subject.hp += (1.00 * subject.mhp).round          $game_party.consume_item($data_items[3])        end      end    end    endend 
    Thanks for all your help  :)
     
    #22
  3. Alyon93

    Alyon93 Veteran Veteran

    Messages:
    62
    Likes Received:
    2
    Location:
    Milano(MI), Italy
    First Language:
    Italian
    Primarily Uses:
    N/A
  4. Another Fen

    Another Fen Veteran Veteran

    Messages:
    530
    Likes Received:
    244
    First Language:
    German
    Hi,

    Sorry for the delay. I also didn't counter-check this post yet as it is already quite late.

    However, a few points regarding your previous post:
       

    Probably the most common situation is when you have two members in your party attacking the same enemy and the first members attack is fatal, the second member will "smoothly" switch to another alive target instead of skipping their turn.

       

    By using the method you can distinguish between skills that are supposed to be used on incapacitated targets and skills that are not. A suggestion was to use the notebox for that, but you could also go with the skills/items ID instead of course. It's use is similar to your RPG::State#poison? method.

    The existence of the method alone does not prevent the user from anything. You have to modify the implementation of the target selection/validation process accordingly to make the result of this method have an impact.

    So assuming you set the scope of your skill to "One Ally" (scope 7) and added "<target immovable>" to its notebox, then this should happen:

    Target Determination Process:

    A list of target battlers is created by invoking make_targets upon the attackers current action:

    576  #--------------------------------------------------------------------------
    577  # * Use Skill/Item
    578  #--------------------------------------------------------------------------
    579  def use_item
    580
       item = @subject.current_action.item
    581    @log_window.display_use_item(@subject, item)
    582    @subject.use_item(item)
    583    refresh_status
    584    targets = @subject.current_action.make_targets.compact
    585
       show_animation(targets, item.animation_id)
    586    targets.each {|target| item.repeats.times { invoke_item(target, item) } }
    587  end
    Depending on whether the skill is meant for use on enemies or friends, this method calculates the corresponding target list. Since the attacker is probably not confused (line 147) and the skill is not "for_opponent?" (line 149; here comes the scope into play for the first time) but "for_friend?" (line 151) the targets are decided by the targets_for_friends method.

    143  #--------------------------------------------------------------------------
    144
      # * Create Target Array
    145  #--------------------------------------------------------------------------
    146  def make_targets
    147    if !forcing && subject.confusion?
    148      [confusion_target]
    149    elsif item.for_opponent?
    150      targets_for_opponents
    151    elsif item.for_friend?
    152      targets_for_friends
    153    else
    154      []
    155    end
    156  end

    This method specifies the selected targets depending on the items scope. Since the skill is neither "for_user?" nor "for_dead_friend?" but "for_friend?", the section between line 204 and 208 is considered for deciding the final targets.

    As the skill is also "for_one?", the target list will only consist of a single battler retrieved from the units  smooth_target  method you already found.

    191  #--------------------------------------------------------------------------
    192  # * Targets for Allies
    193  #--------------------------------------------------------------------------
    194  def targets_for_friends
    195    if item.for_user?
    196      [subject]
    197    elsif item.for_dead_friend?
    198      if item.for_one?
    199        [friends_unit.smooth_dead_target(@target_index)]
    200      else
    201        friends_unit.dead_members
    202      end
    203    elsif item.for_friend?
    204      if item.for_one?
    205        [friends_unit.smooth_target(@target_index)]
    206
         else
    207        friends_unit.alive_members
    208      end
    209    end
    210  end

    ---

    If you wanted to add additional conditions for a specific scope, you can either modify the corresponding section or extend the method to handle specific cases separately. For example, you could check whether the skill/item is "for_immovable?" first and search for fitting targets.

    (This method could probably also be reduced as the "dead friend" section does exactly the same as the "alive friend" section, only for a different set of possible targets)
    Target Validation Process:

    During the validation test, there is still the problem that "One Ally" as a scope means that the target must be alive, otherwise the condition in line 70 ("The item is for a dead friend" does not equal "the target is dead") is met and the method immediately returns false.

    You have to modify this condition if you want to be able to use certain items on alive/dead targets alike. You could change it into

    return false if item.for_dead_friend? != dead? && item.for_opponent?

    to limit this condition to items that are meant to be used on opponents.

    Also, since the method is terminated when the first "return" statement is executed, the upper lines take precedence over the lower ones. Any line past line 71 does not have any effect during battle, so you'll usually have to add custom conditions at the start of the method.

     66  #--------------------------------------------------------------------------
     67
      # * overwrites item_test metod
     68  #--------------------------------------------------------------------------
     69  def item_test(user, item)
     70    return false if item.for_dead_friend? != dead?
     71    return true if $game_party.in_battle  # <- Everything past this line is not reached in battle
     72    return true if item.for_opponent?
     73    return true if item.damage.recover? && item.damage.to_hp? && hp < mhp
     74    return true if item.damage.recover? && item.damage.to_mp? && mp < mmp
     75    return true if item_has_any_valid_effects?(user, item)

     76    return false if item.for_immovable? && movable?
     77    return false
     78  end
     
    Last edited by a moderator: Sep 8, 2015
    #24

Share This Page