Chaos Project

RPG Maker => RPG Maker Scripts => Script Requests => Topic started by: almog99 on August 14, 2015, 11:31:02 pm

Title: is there a way to make this a script?
Post by: almog99 on August 14, 2015, 11:31:02 pm
http://forum.chaos-project.com/index.php?topic=12224.0 - thats a projectile deflection system he made with events and it dosent fit because it have too much flaws
(the limits are like you have to face the enemy down and put him on through and mainly its because he stationary and not moving so i cant use it i need it with a moving enemys because he basicly fakes it this way its not  really the enemy shooting the projectile)
also if its too much to ask any guidance or tip will be more then appreciated.
thanks
Title: Re: is there a way to make this a script?
Post by: KK20 on August 15, 2015, 05:55:54 pm
It'd probably require a lot of editing to the existing BABS engine. You would need to first configure what projectiles can be reflected and what weapons/weapon-types/etc. can reflect. Modify the attacking methods where it checks if there's an enemy target in range to also check for projectile objects. If a projectile is within range, turn the projectile's facing around and change its "owner" (i.e. it's the player's projectile, not the enemy's, so that collision detection can be registered).

So you can see this is already really complicated and should not be attempted by anyone without scripting knowledge and a solid understanding of how BABS works.
Title: Re: is there a way to make this a script?
Post by: almog99 on August 16, 2015, 01:44:30 am
Quote from: KK20 on August 15, 2015, 05:55:54 pm
It'd probably require a lot of editing to the existing BABS engine. You would need to first configure what projectiles can be reflected and what weapons/weapon-types/etc. can reflect. Modify the attacking methods where it checks if there's an enemy target in range to also check for projectile objects. If a projectile is within range, turn the projectile's facing around and change its "owner" (i.e. it's the player's projectile, not the enemy's, so that collision detection can be registered).

So you can see this is already really complicated and should not be attempted by anyone without scripting knowledge and a solid understanding of how BABS works.


i think in my case it my be a little different tho , my game have only one weapon and this weapon is just a filler to have dmg(actually all the characters are hitting with their hands)
and all the projectiles can be deflected so it leaves me with the modifying the attacking methods checking the range and changing the owner, do you think it is possible now?
is there a way around modifying the attacking methods?
thank you so much
Title: Re: is there a way to make this a script?
Post by: KK20 on August 16, 2015, 06:27:14 pm
Well this is what I was able to come up with. It could be better, but at least the functionality is there.

# Rewrites the attack method to allow reflecting of projectiles
# Not aliased due to the amount of setup required and possible performance loss
module BlizzABS
  class Processor
    #--------------------------------------------------------------------------
    # attack_process
    #  ch - the character in action
    #  Processes ABS attack setup and handling for actors and enemies.
    #--------------------------------------------------------------------------
    def attack_process(ch)
      # temporary variable
      ai = ch.ai
      # determine whether actor or enemy for easier reference
      if ch.is_a?(Map_Actor)
        # decide target group
        group = ((ch != $game_player && ch.restriction == 3)) ?
            ai.positive : ai.negative
        # determine range
        d = Weapons.range(ch.battler.weapon_id)
        d = 1 if d < 1
        # determine type
        type = Weapons.type(ch.battler.weapon_id)
        # determine charge
        charge = Weapons.charge(ch.battler.weapon_id)
        # determine projectile speed
        projectile_speed = Weapons.projectile_speed(ch.battler.weapon_id)
      else
        # determine target group depending on confusion
        group = (ch.restriction == 3 ? ai.positive : ai.negative)
        # determine range
        d = Enemies.range(ch.battler_id)
        d = 1 if d < 1
        # determine type
        type = Enemies.type(ch.battler_id)
        # determine charge
        charge = Enemies.charge(ch.battler_id)
        # determine charge
        charge[0] = BlizzABS::CHARGEMove if charge[0] == BlizzABS::CHARGETrigger
        # determine projectile speed
        projectile_speed = Weapons.projectile_speed(ch.battler_id)
      end
      # if item shooting type
      if type == BOW_ARROW
        # temporary variable
        ids = Weapons.consume(ch.battler.weapon_id)
        # if no more items
        if !ids.include?(ch.battler.item) ||
            $game_party.item_number(ch.battler.item) == 0
          # can't use
          return false
        end
      end
      # if not charging already
      if charge[0] != CHARGENone && !ch.charging?
        # setup charging
        ch.setup_charge(ch, charge)
        # not used yet
        return false
      end
      # create affection area depending on attack type
      case type
      when SWORD, SPEAR, FLAIL # sword attack
        # get attack affection area
        area = $BlizzABS.util.get_attack_area(ch, d, type)
      when BOOMERANG # returning projectile attack
        # decide spriteset
        spriteset = ch.is_a?(Map_Actor) ?
            BlizzABS::SPRProjWeapon + ch.battler.weapon_id.to_s :
            BlizzABS::SPRProjEnemy + ch.battler_id.to_s
        # create returning projectile
        proj = Map_Projectile.new(spriteset, ch, 0, d, projectile_speed,
            REMReturning, group)
      when BOW # projectile attack
        # decide spriteset
        spriteset = ch.is_a?(Map_Actor) ?
            BlizzABS::SPRProjWeapon + ch.battler.weapon_id.to_s :
            BlizzABS::SPRProjEnemy + ch.battler_id.to_s
        # create returning projectile
        proj = Map_Projectile.new(spriteset, ch, 0, d, projectile_speed,
            REMNormal, group)
      when BOW_ARROW # item consuming projectile
        # remove one item from inventory
        $game_party.lose_item(ch.battler.item, 1)
        # temporary variable
        item = $data_items[ch.battler.item]
        # get item explosion data
        explode = Items.type(item.id)
        # if explosion exists
        if explode[1] != EXPLNone
          # fix the missing explosion animation error
          explode[2] = 0 if explode[2] == nil
          # create projectile from exploding item with weapon attack effect
          proj = Map_Projectile.new(BlizzABS::SPRProjItem + item.id.to_s, ch,
              item.id, d, projectile_speed, REMShotItem, group, false,
              explode[1, 3])
        else
          # create projectile from item with weapon attack effect
          proj = Map_Projectile.new(BlizzABS::SPRProjItem + item.id.to_s, ch,
              item.id, d, projectile_speed, REMShotItem, group)
        end
      when SHURIKEN # self consuming weapon
        # temporary variable
        weapon = $data_weapons[ch.battler.weapon_id]
        # unequip last weapon if no more weapons in inventory
        ch.battler.equip(0, 0) if $game_party.weapon_number(weapon.id) == 0
        # remove one weapon from inventory
        $game_party.lose_weapon(weapon.id, 1)
        # self shooting weapon, create projectile from weapon
        proj = Map_Projectile.new(BlizzABS::SPRProjWeapon + weapon.id.to_s, ch,
            weapon.id, d, projectile_speed, REMShotWeapon, group)
      end
      # if projectile fired
      if proj != nil
        # add projectile to buffer
        $BlizzABS.cache.remotes.push(proj)
        # used
        return true
      end
      # iterate through all battlers
      ($game_map.battlers + $BlizzABS.battlers).each {|battler|
        # if target can be hit considering all conditions
        if battler.battler != nil && group.include?(battler.ai.group) &&
            (battler != ch || group == ai.positive) &&
            !battler.battler.dead? && @util.intersection(area,
            battler.hitbox)
          # execute attack
          battler.attack_effect(ch, ch.battler)
          # clear damage displays
          battler.battler.damage, battler.battler.damage_pop = nil, false
        end
      }
      #*************************************************************************
      # EDIT BEGINS HERE
      #*************************************************************************
      # If attacked with SWORD weapon
      if type == SWORD
       $BlizzABS.cache.remotes.each{|projectile|
          # Ignore if not a SHOOT projectile
          next unless projectile.is_a?(Map_Projectile) &&
            [REMNormalSkill, REMBreakSkill].include?(projectile.type)
          # Ignore if the creator of the projectile and this character are of
          # the same type
          next if projectile.battler.class == ch.battler.class
          # If projectile in attack area
          if @util.intersection(area, projectile.hitbox)
            # Reflect the projectile
            projectile.reflect_projectile(ch)
          end
        }
      end
      #*************************************************************************
      # EDIT ENDS HERE
      #*************************************************************************
      # enemies were attacked
      return true
    end
  end
end

# Added reflection method
class Map_Projectile < Map_Remote
 
  def reflect_projectile(ch)
    pix = 128 / $BlizzABS.pixel
    # Reset variables so that the reflector is now the owner of the projectile
    @creator = ch
    @battler_copy = ch.battler.clone
    @group = ch.ai.negative
    # Get the remaining distance the projectile had left to move
    distance = case @direction
    when 2 then @y * pix - @real_y
    when 4 then @real_x - @x * pix
    when 6 then @x * pix - @real_x
    when 8 then @real_y - @y * pix
    end
    # Change projectile's direction
    @direction = ch.direction
    # Set new target location for the projectile
    case @direction
      when 2
        @y = (@real_y + distance) / pix
        @x = ch.x
      when 4
        @x = (@real_x - distance) / pix
        @y = ch.y
      when 6
        @x = (@real_x + distance) / pix
        @y = ch.y
      when 8
        @y = (@real_y - distance) / pix
        @x = ch.x
    end
  end
end

Your player must be using a SWORD weapon type and it can only reflect projectiles of the SHOOT type. Edit it according to your needs. The reflected projectile's damage will be the same as if the player were to shoot the exact same projectile himself.
Title: Re: is there a way to make this a script?
Post by: almog99 on August 17, 2015, 01:33:53 am
THANK YOU SO MUCH !!!
For now its looking perfect !!!  :) :) :)
Edit:ok i got a problem after testing a little bit lol , i think the range getting reduced i mean if the range is 10 and the enemy sending it and it passed like 7 then i deflect it so it keeps the count from 7 and going only 3 back to the enemy , if its possible and its not a big deal i would like it the range to be full from the deflect (i mean like if its then and i deflect it so it will have again 10 squares of range)
again thank you so much
i just increasing the range of all the shooting skills to work around it , thank you kind sir !
Title: Re: is there a way to make this a script?
Post by: KK20 on August 17, 2015, 03:34:25 pm

# Added reflection method
class Map_Projectile < Map_Remote
 
  def reflect_projectile(ch)
    pix = $BlizzABS.pixel
    # Reset variables so that the reflector is now the owner of the projectile
    @creator = ch
    @battler_copy = ch.battler.clone
    @group = ch.ai.negative
   
    distance = ((BlizzABS::Skills.range(@id) - 1) * pix).to_i

    # Change projectile's direction
    @direction = ch.direction
    # Set new target location for the projectile
    case @direction
      when 2
        @y += distance
        @x = ch.x
      when 4
        @x -= distance
        @y = ch.y
      when 6
        @x += distance
        @y = ch.y
      when 8
        @y -= distance
        @x = ch.x
    end
  end
end

It just felt more natural to me having its range stay the same after being reflected. Anyways, this code will change that.