Chaos Project

RPG Maker => RPG Maker Scripts => Script Requests => Topic started by: MEANDONLYME on April 11, 2017, 02:44:20 am

Title: Touch Damage From Player In Blizz-ABS
Post by: MEANDONLYME on April 11, 2017, 02:44:20 am
So I'm trying to create a state in Blizz-ABS in which the enemy takes damage if the players touches him.
Now, this can be done with custom event triggers on one enemy, but it will be a nightmare to copy the same trigger to every enemy in the game.
I'm thinking the problem could be solved in two ways: a script that applies some event's custom event trigger to all events (enemies), or a script like Touch Damage (http://forum.chaos-project.com/index.php/topic,2787.0.html) only the opposite (since here we need the enemy to take damage from touching the player).
I'm very tempted to ask for the first option- just because it opens so many possibilities, but choose what you like as long as you help.   :naughty:
Title: Re: Touch Damage From Player In Blizz-ABS
Post by: KK20 on April 12, 2017, 01:24:08 am
Here's to adding global triggers:
Spoiler: ShowHide

=begin
--------------------------------------------------------------------------------
Global Custom Event Triggers                                        Ver 1.0
by KK20                                                             Apr 11 2017
--------------------------------------------------------------------------------

[ Purpose ]

Allows the creation of Global Triggers, making enemies with the same custom
triggers easier to create.

[ Instructions ]

Place this script below all of Blizz-ABS. (and above Main obviously)
Scroll down this script and find COMMON_EVENT_ID. The number assigned to it
indicates what Common Event ID you want to use as the default global triggers.
Change its value to whatever suits your project's needs.

In your Database, create a Common Event. Add as many triggers as you like to it,
much in the same fashion as if you were adding triggers to an enemy event. Refer
to the Blizz-ABS manual for further instructions on how to set this up.

A new custom trigger can be defined for enemy events:
   
                           Trigger:Global=X

where X represents the Common Event ID in your database.
You can create multiple Global Triggers this way--just use another Common Event.
Have triggers that should only apply to boss monsters? This command will help.

**NOTE**
If you use this trigger, IT MUST BE AT THE VERY TOP OF THE COMMAND LIST.
As a result, YOU CANNOT USE THIS TRIGGER MORE THAN ONCE PER EVENT.

Enemy events that do not use this new trigger will use the default triggers
defined in your Common Event as specified by COMMON_EVENT_ID.

If you set Global=0, then your event will NOT use any global triggers.

You can still add more triggers to enemy events after the Trigger:Global.

--------------------------------------------------------------------------------
=end
module BlizzABS
 
 
  # The common event that holds the global Custom Event Trigger for enemies if
  # no Trigger:Global=X is defined in the enemy's event command list.
  COMMON_EVENT_ID = 1
 
 
  class Utility
    alias get_common_triggers get_triggers
    def get_triggers(list)
      cloned_list = list.clone
      triggers = [-1, {}]
      # If the first event command is a comment
      if list[0].code == 108
        comment = list[0].parameters[0]
        ce_id = comment.scan(/Trigger:Global=(\d+)/).flatten[0]
        # If a Global trigger was defined, use it
        if ce_id
          ce_id = ce_id.to_i
          # No global trigger if ID is 0
          unless ce_id == 0
            triggers = get_common_triggers($data_common_events[ce_id].list)
          end
          # Remove this comment from being interpreted by the alias
          cloned_list = list[1, list.size - 1]
        else # Use the default
          triggers = get_common_triggers($data_common_events[COMMON_EVENT_ID].list)
        end
      else # Use the default
        triggers = get_common_triggers($data_common_events[COMMON_EVENT_ID].list)
      end
      # Call the alias
      triggers2 = get_common_triggers(cloned_list)
      # Combine two results to get resulting triggers
      result = []
      special = {}
      result.push(triggers[0] == BlizzABS::CETNone ? triggers2[0] : triggers[0])
      (triggers[1].keys + triggers2[1].keys).each { |key|
        special[key] = (triggers[1][key] || []) + (triggers2[1][key] || [])
      }
      result.push(special)
      result
    end
  end
end


Regarding touch damage to enemies, you might run into issues with that as discussed in this topic:
http://forum.chaos-project.com/index.php/topic,15717.msg195587.html#msg195587
Title: Re: Touch Damage From Player In Blizz-ABS
Post by: MEANDONLYME on April 12, 2017, 10:58:01 am
Thank you very much, you seem to be helping a lot of people here.
I couldn't get the global trigger to work for some time, until I realized the common event only controls the trigger, and you can't add commands in the case of a trigger.
The script does help cover touch damage (In my game I'm fine with the skill not killing the enemy which solves the problem in the thread you linked).
But is there a possibility to define specific commands for different triggers in the common event? Is it even possible to make more than one trigger on blizz?
Title: Re: Touch Damage From Player In Blizz-ABS
Post by: KK20 on April 12, 2017, 04:54:00 pm
You can always add more than one trigger; just make a new Comment directly below another Trigger.

@>Comment: Trigger:Weapon=1
@>Comment: Trigger:ActionButton

I can see the need to add custom event commands to the global triggers, but that will require some extra tweaking to my script. I'll see if it's even possible firstly. Might be as simple as copying the common event command list and somehow shoving them into the map event's list.

You might also be interested in this script I made too.
http://forum.chaos-project.com/index.php/topic,12230.0.html
Title: Re: Touch Damage From Player In Blizz-ABS
Post by: MEANDONLYME on April 12, 2017, 11:26:48 pm
Yeah, I knew you could add different triggers, the problem was I couldn't check which trigger was activated-  and the script you linked solved this.
Let me know if you manage to make custom commands in the common event.  :naughty:
Title: Re: Touch Damage From Player In Blizz-ABS
Post by: KK20 on April 20, 2017, 04:12:17 am
Give that a shot

=begin
--------------------------------------------------------------------------------
Global Custom Event Triggers                                        Ver 1.1
by KK20                                                             Apr 20 2017
--------------------------------------------------------------------------------

[ Purpose ]

Allows the creation of Global Triggers, making enemies with the same custom
triggers easier to create.

[ Instructions ]

Place this script below all of Blizz-ABS. (and above Main obviously)
Scroll down this script and find COMMON_EVENT_ID. The number assigned to it
indicates what Common Event ID you want to use as the default global triggers.
Change its value to whatever suits your project's needs.

In your Database, create a Common Event. Add as many triggers as you like to it,
much in the same fashion as if you were adding triggers to an enemy event. Refer
to the Blizz-ABS manual for further instructions on how to set this up.

*** New in Version 1.1 ***
If you have a common execution of command events for this trigger, you may also
add them to the common event. They will be automatically added to the event's
command list in-game.

A new custom trigger can be defined for enemy events:
   
                           Trigger:Global=X

where X represents the Common Event ID in your database.
You can create multiple Global Triggers this way--just use another Common Event.
Have triggers that should only apply to boss monsters? This command will help.

**NOTE**
If you use this trigger, IT MUST BE AT THE VERY TOP OF THE COMMAND LIST.
As a result, YOU CANNOT USE THIS TRIGGER MORE THAN ONCE PER EVENT.

Enemy events that do not use this new trigger will use the default triggers
defined in your Common Event as specified by COMMON_EVENT_ID.

If you set Global=0, then your event will NOT use any global triggers.

You can still add more triggers to enemy events after the Trigger:Global.

--------------------------------------------------------------------------------
=end
module BlizzABS
 
 
  # The common event that holds the global Custom Event Trigger for enemies if
  # no Trigger:Global=X is defined in the enemy's event command list.
  COMMON_EVENT_ID = 1
 
 
  class Utility
    alias get_common_triggers get_triggers
    def get_triggers(list)
      ce_list = nil
      cloned_list = list.clone
      triggers = [-1, {}]
      # If the first event command is a comment
      if list[0].code == 108
        comment = list[0].parameters[0]
        ce_id = comment.scan(/Trigger:Global=(\d+)/).flatten[0]
        # If a Global trigger was defined, use it
        if ce_id
          ce_id = ce_id.to_i
          # No global trigger if ID is 0
          unless ce_id == 0
            ce_list = $data_common_events[ce_id].list
            triggers = get_common_triggers(ce_list)
          end
          # Remove this comment from being interpreted by the alias
          cloned_list = list[1, list.size - 1]
        else # Use the default
          ce_list = $data_common_events[COMMON_EVENT_ID].list
          triggers = get_common_triggers(ce_list)
        end
      else # Use the default
        ce_list = $data_common_events[COMMON_EVENT_ID].list
        triggers = get_common_triggers(ce_list)
      end
      # Call the alias
      triggers2 = get_common_triggers(cloned_list)
      # Combine two results to get resulting triggers
      result = []
      special = {}
      result.push(triggers[0] == BlizzABS::CETNone ? triggers2[0] : triggers[0])
      (triggers[1].keys + triggers2[1].keys).each { |key|
        special[key] = (triggers[1][key] || []) + (triggers2[1][key] || [])
      }
      result.push(special)
      # Now add the global event commands to the event itself
      list.unshift(*ce_list) if ce_list
      # Return the triggers
      result
    end
  end
end
Title: Re: Touch Damage From Player In Blizz-ABS
Post by: MEANDONLYME on April 20, 2017, 10:46:21 pm
Well, it does work until I try to check with what specific trigger was activated. Here's the demo:
http://www.mediafire.com/file/o0ycjck0d0sdldk/Project3.exe
The bugs I found are:
When you add a trigger for a specific item, the trigger applies to all items.
When you check what item was used it gives you the wrong item.
Title: Re: Touch Damage From Player In Blizz-ABS
Post by: KK20 on April 20, 2017, 11:07:15 pm
Yeah, I found that out before I saw your edit. It also applied to skills. Must've been a rushed copy-pasta mistake.

Problem were the lines that looked like this
@event_trigger = [BlizzABS::CETSkill, id]

In this case, the 'id' being used was the event ID, not the item/skill ID being used :P

Try this:
Spoiler: ShowHide


=begin
===============================================================================
Enemy Event Trigger Condition Checking                                Ver. 1.01
- By KK20                                                            [10/26/12]
===============================================================================
                                  [ Updates ]
Version:

  1.01                                                               [10/26/12]
  -  There was an issue with running events when enemies died

===============================================================================
[Information]
  Blizzard ABS allows the creator to make event triggers for map battlers. It
  was possible for players to allow multiple triggers for one event page,
  meaning that the events would run if any ONE of those triggers was satisfied.
  With this script, the creator can now make conditional branches for each
  trigger.
 
 
[Example]
  The event can be triggered via ActionButton and Weapon. If player presses
  ActionButton, the event will say "Hi." If the player attacks with his weapon,
  the event says "Ouch!"
 
-------------------------------------------------------------------------------

[How to Use]
  Create triggers as you would normally (at the top of the event list as a
  comment line--read the BlizzABS manual for details). In a conditional branch,
  use the 'Script' option. Then, type this line:
 
      $game_map.events[@SELF].triggered?(trigger_id, object_id)
     
  >> trigger_id : The ID of the trigger type (i.e. CETPlayerTouch, CETWeapon)
   [[** NOTE **]]
   If you want to learn more of the types of triggers, refer to the manual.
   Also, it is MANDATORY to add this code before the trigger variable:
                                 
                                 BlizzABS::
   
  >> object_id  : The ID of the object (i.e weapon ID, skill ID, item ID)
  [[** NOTE **]]
  This parameter is 'nil' by default. Thus, this parameter can be entirely
  skipped. Only specify a value if necessary.
 
 
[Examples of Usage]
  $game_map.events[@SELF].triggered?(BlizzABS::CETActionButton)
    => If the player pressed the ActionButton to trigger the event
   
  $game_map.events[@SELF].triggered?(BlizzABS::CETWeapon, 5)
    => If the player attacked with the weapon of ID 5
   
  $game_map.events[@SELF].triggered?(BlizzABS::CETSkill)
    => If the player attacked with any skill
   
===============================================================================
Credits
  KK20      : Creating this script edit
  Blizzard  : So that you can use this script in BlizzABS (duh :P)
  Sin86     : For the idea and bug report
===============================================================================
=end

class Map_Enemy < Map_Battler
  #----------------------------------------------------------------------------
  # triggered?
  #  trigger_id : The ID of the trigger type (i.e. CETPlayerTouch, CETWeapon)
  #  object_id  : The ID of the object (i.e weapon ID, skill ID, item ID)
  #  Returns if the event was triggered by a certain trigger.
  #----------------------------------------------------------------------------
  def triggered?(trigger_id, object_id = nil)
    return (@event_trigger[0] == trigger_id) if object_id.nil?
    return @event_trigger == [trigger_id, object_id]
  end
  #----------------------------------------------------------------------------
  # Initialization
  # ** Initialize variable 'event_trigger'
  #----------------------------------------------------------------------------
  alias init_map_enemy_after initialize
  def initialize(map_id, event, id = 0, group = 0, attributes = 0x00,
                 move = false, immortal = false, full_passable = false,
                 custom = false, delay = 40, view = 5, hear = 40, nojump = false)
    @event_trigger = [-1, -1]
    init_map_enemy_after(map_id, event, id, group, attributes,
                 move, immortal, full_passable,
                 custom, delay, view, hear, nojump)
  end
               
  #----------------------------------------------------------------------------
  # start
  #  Setups the starting event code.
  #  ** Removed the line -> @trigger = 1 **
  #----------------------------------------------------------------------------
  def start
    # if event code exists
    return if @list.size <= 1
    # set starting and execution flag
    @starting = @execute = true
  end
  #----------------------------------------------------------------------------
  # event_execution?
  #  Tests if the enemy died and is executing an event now.
  #  ** Added @event_trigger = [-1, -1] **
  #----------------------------------------------------------------------------
  def event_execution?
    # stop if not executing
    return false if !@execute
    # if about to start or running already
    if @starting || $game_system.map_interpreter.running?
      # reset blending type
      @blend_type = 0 if @starting
      # reset moving route
      @force_move = []
      # executing event
      return true
    end
    # if enemy revived with event command
    if valid? && !battler.dead?
      # reset opacity
      @opacity = 255
      # reset blending type
      @blend_type = 0
      # reset execute flag
      @execute = false
      # recreate data pack for new enemy
      @ai = BlizzABS::AI::Data_Enemy.new(self, @ai.group, @ai.attributes,
          @ai.custom, @ai.delay_time, @ai.view_range, @ai.hearing_range_ratio)
      # reset moving route
      @force_move = []
    # if opacity is 0
    elsif (!valid? || battler.dead?) && @opacity == 0
      # set execute flag and erased flag
      @execute, @erased = false, true
      # refresh
      refresh
    end
    @event_trigger = [-1, -1]
    # not executing event
    return false
  end
  #----------------------------------------------------------------------------
  # attack_effect
  #  character - the character that holds attack data (can be projectile)
  #  _battler  - the attacking battler
  #  Executes attack upon a map character.
  #----------------------------------------------------------------------------
  def attack_effect(character, _battler)
    # call superclass method
    result = super
    # if actor
    if _battler.is_a?(Game_Actor)
      # get weapon ID and custom event trigger type
      id, cet = _battler.weapon_id, BlizzABS::CETWeapon
    # if enemy
    elsif _battler.is_a?(Game_Enemy)
      # get weapon ID and custom event trigger type
      id, cet = _battler.id, BlizzABS::CETEnemy
    end
    # if can be activated by this weapon / enemy
    if result && @custom_triggers.has_key?(cet) &&
        (@custom_triggers[cet].size == 0 ||
        @custom_triggers[cet].include?(id))
      # run this enemy as event
      @event_trigger = [cet, id]
      self.start
    end
    # return result
    return result
  end
  #----------------------------------------------------------------------------
  # skill_effect
  #  character - the character that holds skill use (can be projectile)
  #  _battler  - the skill using battler
  #  skill     - the skill
  #  Executes skill use upon a map character.
  #----------------------------------------------------------------------------
  def skill_effect(character, _battler, skill)
    # call superclass method
    result = super
    # if can be activated by this skill
    if result && @custom_triggers.has_key?(BlizzABS::CETSkill) &&
        (@custom_triggers[BlizzABS::CETSkill].size == 0 ||
        @custom_triggers[BlizzABS::CETSkill].include?(skill.id))
      # run this enemy as event
      @event_trigger = [BlizzABS::CETSkill, skill.id]
      self.start
    end
    # return result
    return result
  end
  #----------------------------------------------------------------------------
  # item_effect
  #  character - the character that holds item use (can be projectile)
  #  item      - the item
  #  Executes item use upon a map character.
  #----------------------------------------------------------------------------
  def item_effect(character, _battler, item)
    # call superclass method
    result = super
    # if can be activated by this item
    if result && @custom_triggers.has_key?(BlizzABS::CETItem) &&
        (@custom_triggers[BlizzABS::CETItem].size == 0 ||
        @custom_triggers[BlizzABS::CETItem].include?(item.id))
      # run this enemy as event
      @event_trigger = [BlizzABS::CETItem, item.id]
      self.start
    end
    # return result
    return result
  end
  #----------------------------------------------------------------------------
  # check_event_trigger_touch
  #  x - x-coordinate
  #  y - y-coordinate
  #  Checks event touching. Called when event moves into player.
  #----------------------------------------------------------------------------
  def check_event_trigger_touch(x, y)
    # get pixel movement rate
    pix = $BlizzABS.pixel
    # stop if an event is being executed already
    return false if $game_system.map_interpreter.running?
    # if any battler in the way
    if @trigger == BlizzABS::CETEventTouch && !jumping? && !over_trigger? &&
        !$game_player.through && $game_player.character_name != '' &&
        $BlizzABS.util.rect_intersection(Rect.new(x, y, pix, pix),
            Rect.new($game_player.x, $game_player.y, pix, pix))
      # start
      @event_trigger = [BlizzABS::CETEventTouch, id]
      start
      # started
      return true
    end
    # not started
    return false
  end
  #----------------------------------------------------------------------------
  # check_event_trigger_at
  #  x - x-coordinate
  #  y - y-coordinate
  #  Check event if it was triggered at a specific position. (pixel movement)
  #  Called when player presses action button or walks into event.
  #----------------------------------------------------------------------------
  def check_event_trigger_at(x, y)
    # get pixel movement rate
    pix = $BlizzABS.pixel
    # if player touched this event and not jumping and not over_trigger
    if !jumping? && !over_trigger? && $BlizzABS.util.rect_intersection(
        Rect.new(@x, @y, pix, pix), Rect.new(x, y, pix, pix))
      # start
      @event_trigger = Input.trigger?(Input::C) ? [BlizzABS::CETActionButton, -1] : [BlizzABS::CETPlayerTouch, -1]
      start
      # started
      return true
    end
    # not started
    return false
  end
end

#==============================================================================
# ** Interpreter
#------------------------------------------------------------------------------
#  This interpreter runs event commands. This class is used within the
#  Game_System class and the Game_Event class.
#==============================================================================
class Interpreter
  #--------------------------------------------------------------------------
  # * Starting Event Setup
  #   Editted 'if event.trigger < 3' to be '!= 3'
  #--------------------------------------------------------------------------
  def setup_starting_event
    # Refresh map if necessary
    if $game_map.need_refresh
      $game_map.refresh
    end
    # If common event call is reserved
    if $game_temp.common_event_id > 0
      # Set up event
      setup($data_common_events[$game_temp.common_event_id].list, 0)
      # Release reservation
      $game_temp.common_event_id = 0
      return
    end
    # Loop (map events)
    for event in $game_map.events.values
      # If running event is found
      if event.starting
        # If not auto run
        if event.trigger != 3 # if event.trigger < 3
          # Clear starting flag
          event.clear_starting
          # Lock
          event.lock
        end
        # Set up event
        setup(event.list, event.id)
        return
      end
    end
    # Loop (common events)
    for common_event in $data_common_events.compact
      # If trigger is auto run, and condition switch is ON
      if common_event.trigger == 1 and
         $game_switches[common_event.switch_id] == true
        # Set up event
        setup(common_event.list, 0)
        return
      end
    end
  end
end

Title: Re: Touch Damage From Player In Blizz-ABS
Post by: MEANDONLYME on April 21, 2017, 12:59:55 pm
Oh, it works perfectly!
You know, i'm using a bunch of your scripts from the script requests forum and I feel kind of bad that most people probably won't see them. I'm talking about this script and a reflection system for blizz that you made.
Can I make a demo and publish it here (or send it and you'll publish)?
EDIT: On a second thought, I'm not sure I currently have the time for creating a demo, but I will let you know if that will change.
Title: Re: Touch Damage From Player In Blizz-ABS
Post by: KK20 on April 21, 2017, 09:46:50 pm
I'll add the Global Triggers to the database and will need to update the first post for the trigger condition checking. I'm not too proud of the reflecting one as that was made more as a proof-of-concept; it's too experimental to be considered an official script.

But sure, go ahead and make the demo if you'd like :)