Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

Checking for any Event ID that is in an Array

I'm working with RMXP, I'm hoping someone with scripting knowledge can help me out. For some quick background, this is for projectiles in an ABS I'm working on. Every time a projectile is fired, an event spawns, and the event ID is added to an array ($projectiles_array). Once the projectile has run its course, the even ID is erased from the array.

What I'm trying to do now with the collision detection, is check each event ID that is currently in $projectiles_array. For example, on a map with no events, the hero fires 3 arrows, meaning $projectile_array == [1, 2, 3] In pseudo-code, I'd need something like this:

Code:
unless $projectiles_array.empty?

   e = $game_map.events[1] or $game_map.events[2] or $game_map.events[3]

end

Can someone help me out?
 
Something along the lines of this?
Code:
def check_projectile_collision(id)

    for ev in $game_map.events.values

        next if id == ev.id

        next if $game_map.events[id] == nil

        return true if (ev.x == $game_map.events[id].x) and (ev.y == $game_map.events[id].y)

    end

    return false

end

 
Then you'd just run something like:
Code:
#other code

if $projectiles_array.length > 0

    for id in $projectiles_array

        if check_projectile_collision(id)

            #if it hit something

        else

            #nothing collided

        end

    end

end

#continue

This is rough and untested, but should work, in theory.
 
I appreciate the effort ZenVirZan, but I already have the collision code working. I'm working with a pixel-based script, so unfortunately event.x==projectile.x doesn't work. Basically what I did was give every object/enemy a certain width and height, and it'll actually use those dimensions to make hit-boxes. Anyways, I digress; perhaps I should post the full script I'm working with and maybe you or someone else can take a look.

Code:
#==============================================================================

# ■ Sticky Switches

#------------------------------------------------------------------------------

# This is the script for Sticky Switches.

#==============================================================================

# Version 3 by Astro_mech

# Version 3 Update by Ace of Spades

 

#==============================================================================

# ■ Game_Character

#------------------------------------------------------------------------------

#   With Facing Detection by: Astro_mech

#   New Facing Detections by:  Ace of Spades

#==============================================================================

 

class Game_Character

DOWN  = 2

LEFT  = 4

RIGHT = 6

UP    = 8

#--------------------------------------------------------------------------

def facing?(event)

  case @direction

  when DOWN

    return (self.y < event.y and event.direction == UP)

  when LEFT

    return (self.x < event.x and event.direction == RIGHT)

  when RIGHT

    return (self.x > event.x and event.direction == LEFT)

  when UP

    return (self.y > event.y and event.direction == DOWN)

  end

end

#--------------------------------------------------------------------------

def opposite_dir?(event)

  case @direction

  when DOWN

    return (self.y > event.y and event.direction == UP)

  when LEFT

    return (self.x > event.x and event.direction == RIGHT)

  when RIGHT

    return (self.x < event.x and event.direction == LEFT)

  when UP

    return (self.y < event.y and event.direction == DOWN)

  end

end

#--------------------------------------------------------------------------

 def sourcefacing?(event)

  case @direction

  when DOWN

    return (self.y < event.y)

  when LEFT

    return (self.x < event.x)

  when RIGHT

    return (self.x > event.x)

  when UP

    return (self.y > event.y)

  end

end

#--------------------------------------------------------------------------

def facingsource?(event)

   if event.direction == DOWN

     return (self.y > event.y)

   end

   if event.direction == LEFT

     return (self.x < event.x)

   end

   if event.direction == RIGHT

    return (self.x > event.x)

    end

   if event.direction == UP

    return (self.y < event.y)

  end

end

 #--------------------------------------------------------------------------

def facingawaysource?(event)

   if event.direction == UP

     return (self.y > event.y)

   end

   if event.direction == RIGHT

     return (self.x < event.x)

   end

   if event.direction == LEFT

    return (self.x > event.x)

    end

   if event.direction == DOWN

    return (self.y < event.y)

  end

end

 #--------------------------------------------------------------------------

 def sourcefacingaway?(event)

  case @direction

  when UP

    return (self.y < event.y)

  when RIGHT

    return (self.x < event.x)

  when LEFT

    return (self.x > event.x)

  when DOWN

    return (self.y > event.y)

  end

end

#------------------------------------------------------------------------------

end

#==============================================================================

# ■ Game_Event

#------------------------------------------------------------------------------

#  With Sticky Keys by Astro_mech

#==============================================================================

 

class Game_Event < Game_Character

#--------------------------------------------------------------------------

alias ss_initialize initialize

def initialize(*args)

  @sticky_switches = []

  ss_initialize(*args)

end

#--------------------------------------------------------------------------

def refresh

  new_page = nil

  unless @erased

    for page in @event.pages.reverse

      c = page.condition

      if c.switch1_valid

        if $game_switches[c.switch1_id] == false

          next

        end

      end

      if c.switch2_valid

        if $game_switches[c.switch2_id] == false

          next

        end

      end

      if c.variable_valid

        if $game_variables[c.variable_id] < c.variable_value

          next

        end

      end

      if c.self_switch_valid

        key = [@map_id, @event.id, c.self_switch_ch]

        if $game_self_switches[key] != true

          next

        end

      end

      new_page = page

      break

    end

  end

  if new_page == @page

    return

  end

  @page = new_page

  clear_starting

  if @page == nil

    @tile_id = 0

    @character_name = ""

    @character_hue = 0

    @move_type = 0

    @through = true

    @trigger = nil

    @list = nil

    @interpreter = nil

    return

  end

  @tile_id = @page.graphic.tile_id

  @character_name = @page.graphic.character_name

  @character_hue = @page.graphic.character_hue

  if @original_direction != @page.graphic.direction

    @direction = @page.graphic.direction

    @original_direction = @direction

    @prelock_direction = 0

  end

  if @original_pattern != @page.graphic.pattern

    @pattern = @page.graphic.pattern

    @original_pattern = @pattern

  end

  @opacity = @page.graphic.opacity

  @blend_type = @page.graphic.blend_type

  @move_type = @page.move_type

  @move_speed = @page.move_speed

  @move_frequency = @page.move_frequency

  @move_route = @page.move_route

  @move_route_index = 0

  @move_route_forcing = false

  @walk_anime = @page.walk_anime

  @step_anime = @page.step_anime

  @direction_fix = @page.direction_fix

  @through = @page.through

  @always_on_top = @page.always_on_top

  @trigger = @page.trigger

  @list = @page.list

  @interpreter = nil

  if @trigger == 4

    @interpreter = Interpreter.new

  end

  check_event_trigger_auto

  @sticky_switches = []

  for line in @list.find_all {|i| i.code == 108}

    a = line.parameters[0].strip.split(' ')

    if a[0] == "sticky_switch"

      if ["A", "B", "C", "D"].include?(a[1].upcase)

        id = a[1].upcase

     end 

    if a[2] == nil or a[2].to_i < 0

        e = "$game_player"

#Start Edits

    else

      if a[2] == "projectile"

        unless $projectiles_array.empty?

        $projectiles_array.each do |i|

        e = "$game_map.events[#{i}]"

        end

        end

#End Edits

      else

          e = "$game_map.events[#{a[2]}]"

        end

      end

      if a[3] == nil

        d = 1

      else

        d = a[3].to_i

      end

      if a[4] == nil

        look = 0

      else

        look = a[4].to_i

      end

      @sticky_switches.push([id, e, d, look])

    end

  end

end

#--------------------------------------------------------------------------

alias ss_update update

def update

  ss_update

  update_sticky_switches

end

#--------------------------------------------------------------------------

def update_sticky_switches

  for sswitch in @sticky_switches

    event = eval(sswitch[1])

    if sswitch[2] >= 0

      v = (event.x.between?(self.x-sswitch[2], self.x+sswitch[2]) and

           event.y.between?(self.y-sswitch[2], self.y+sswitch[2]))

    else

      v = true

    end

    if sswitch[3] != 0

      case sswitch[3]

      when +1 # Both Events Facing Eachother

        v &= self.facing?(event)

      when -1 # Both Events Facing Opposite Directions

        v &= self.opposite_dir?(event)

      when +2 # Event/Player is Facing Source Event

        v &= self.facingsource?(event)

       when -2 # Source Event is Facing Event/Player

        v &= self.sourcefacing?(event)

       when +3 # Event/Player is Facing Away from Event/Player

        v &= self.facingawaysource?(event)

       when -3 # Source Event is Facing Away from Event/Player

        v &= self.sourcefacingaway?(event)

      end

    end

    if sswitch[0].is_a?(String) # Self Switches

      key = [@map_id, @id, sswitch[0]]

      $game_map.need_refresh |= (v != $game_self_switches[key])

      $game_self_switches[key] = v

    else                        # Switches

      $game_map.need_refresh |= (v != $game_switches[sswitch[0]])

      $game_switches[sswitch[0]] = v

    end

  end

end

end

 

# 1.  Place any event on the map. I'll call this event self to avoid confusion.

# 2.  Open the event editor, and create a comment anywhere in the event (self).

# 3.  Type "sticky_switch" (without the quotes) in the top line of the event.

# 4.  Type a space, and then the id of the switch to become one of self's sticky switches. To use a local switch, type A, B, C, or D for the respective local switch.

# 5.  Type another space, and then the id of the event on the map to be checked to see if it is close to self. Type -1 or leave this blank to set the event to be the player.

# 6.  Type another space, and then the distance you want self to be able to detect the event. Leave this blank or enter 0 for no distance detection.

# 7.  Type another space, and then a number for the direction check mode: 0 (or blank) for no direction check, 1 to check if self is facing the event, and -1 to check if self is facing opposite of the event.

# 8.  Remember not to leave areas blank if you use something after it. For instance, fill in distance if you want to use direction checking.

# 9.  Repeat steps 2-8 to add any other sticky switches, on the same page or otherwise.

#10.  Click "Ok" on the event editor page, and test your game. The switch should turn on when the event is close to self.

#       View Types  0 = Event/Player is Within Sources Range

#                         1 = Both Events Are Facing Each Other

#                        -1 = Both Events Are Facing Away From Each Other

#                         2 = Event/Player is Facing Source

#                        -2 = Source is Facing Event/Player

#                         3 = Event/Player is Facing Away from Event/Player

#                        -3 = Source Event is Facing Away from Event/Player
 
This script is called Sticky_Switches.  Basically what this does is allow you to put a comment into an event, and that event will automatically turn a switch on if certain conditions are met.  For example, commenting
sticky_switch A -1 64 2
in an event would turn on local switch A if the player is within 64 pixels of the event (or two tiles), and the player is currently facing the event.  Once local switch A is on, it begins checking for melee collision, allowing me to save processing power by not constantly checking for collision on every single event on the map.  Hope that makes sense!
 
Anyways, the problem I'm having is that I need an option in the script to check if a projectile is in proximity.  So if I were to comment
sticky_switch A projectile 64 0
inside an event, local switch A would turn on if any event ID that is currently in $projectiles_array is within 64 pixels of the event. The edits I've made are between lines 206 and 214, but the code I have there obviously isn't accomplishing what I need it to. I've just been experimenting, but I don't really know how to go about doing what I'm trying to accomplish. Anyone willing to take a look?
 
It sounds to me like all you need is this:
[rgss]for projectile in $projectiles
  # do stuff
end
[/rgss]
Unless I get you totally wrong :eek:uch: But you kind of have that with your .each method...
 
The method I wrote doesn't actually accomplish what I want it to, but it was the best I could come up with. Unfortunately my scripting knowledge is little to none, so I don't really understand how to accomplish what I'm trying to do, that just happened to be my best attempt. I'm confused with what you posted, where could I apply that in the script I posted?

I'm beginning to suspect this might not have been as simple of a question as I thought. At this point, I need the sticky switches script to check the event ID of each projectile, in the format of "$game_map.events[#{i}]", where i is any value currently listed in $projectiles_array (this would replace lines 209-213). Although the more I look at it, the more I realize their may be a problem elsewhere in the script that's holding me back.
 
If anyone else is willing to take a look at this, I'd really appreciate it. I'm still trying to work around this, but ideally I'd love to get this to work. I don't feel it's too far out of the realm of possibility, if someone with some scripting knowledge could offer any suggestions.
 
The problem is in your each loop:
Code:
$projectiles_array.each do |i|

  e = "$game_map.events[#{i}]"

end
You cycle through all the projectiles in the array, but each time you set it to e, the previous projectile is erased; so in the end, you're only checking for the last projectile in the array, rather than the whole array.

Try this instead:
Code:
#==============================================================================

# ■ Sticky Switches

#------------------------------------------------------------------------------

# This is the script for Sticky Switches.

#==============================================================================

# Version 3 by Astro_mech

# Version 3 Update by Ace of Spades

 

#==============================================================================

# ■ Game_Character

#------------------------------------------------------------------------------

#   With Facing Detection by: Astro_mech

#   New Facing Detections by:  Ace of Spades

#==============================================================================

 

class Game_Character

  DOWN  = 2

  LEFT  = 4

  RIGHT = 6

  UP    = 8

  #--------------------------------------------------------------------------

  def facing?(event)

    case @direction

    when DOWN

      return (self.y < event.y and event.direction == UP)

    when LEFT

      return (self.x < event.x and event.direction == RIGHT)

    when RIGHT

      return (self.x > event.x and event.direction == LEFT)

    when UP

      return (self.y > event.y and event.direction == DOWN)

    end

  end

  #--------------------------------------------------------------------------

  def opposite_dir?(event)

    case @direction

    when DOWN

      return (self.y > event.y and event.direction == UP)

    when LEFT

      return (self.x > event.x and event.direction == RIGHT)

    when RIGHT

      return (self.x < event.x and event.direction == LEFT)

    when UP

      return (self.y < event.y and event.direction == DOWN)

    end

  end

  #--------------------------------------------------------------------------

   def sourcefacing?(event)

    case @direction

    when DOWN

      return (self.y < event.y)

    when LEFT

      return (self.x < event.x)

    when RIGHT

      return (self.x > event.x)

    when UP

      return (self.y > event.y)

    end

  end

  #--------------------------------------------------------------------------

  def facingsource?(event)

     if event.direction == DOWN

       return (self.y > event.y)

     end

     if event.direction == LEFT

       return (self.x < event.x)

     end

     if event.direction == RIGHT

      return (self.x > event.x)

      end

     if event.direction == UP

      return (self.y < event.y)

    end

  end

   #--------------------------------------------------------------------------

  def facingawaysource?(event)

     if event.direction == UP

       return (self.y > event.y)

     end

     if event.direction == RIGHT

       return (self.x < event.x)

     end

     if event.direction == LEFT

      return (self.x > event.x)

      end

     if event.direction == DOWN

      return (self.y < event.y)

    end

  end

   #--------------------------------------------------------------------------

   def sourcefacingaway?(event)

    case @direction

    when UP

      return (self.y < event.y)

    when RIGHT

      return (self.x < event.x)

    when LEFT

      return (self.x > event.x)

    when DOWN

      return (self.y > event.y)

    end

  end

  #------------------------------------------------------------------------------

end

#==============================================================================

# ■ Game_Event

#------------------------------------------------------------------------------

#  With Sticky Keys by Astro_mech

#==============================================================================

 

class Game_Event < Game_Character

  #--------------------------------------------------------------------------

  alias ss_initialize initialize

  def initialize(*args)

    @sticky_switches = []

    ss_initialize(*args)

  end

  #--------------------------------------------------------------------------

  def refresh

    new_page = nil

    unless @erased

      for page in @event.pages.reverse

        c = page.condition

        if c.switch1_valid

          if $game_switches[c.switch1_id] == false

            next

          end

        end

        if c.switch2_valid

          if $game_switches[c.switch2_id] == false

            next

          end

        end

        if c.variable_valid

          if $game_variables[c.variable_id] < c.variable_value

            next

          end

        end

        if c.self_switch_valid

          key = [@map_id, @event.id, c.self_switch_ch]

          if $game_self_switches[key] != true

            next

          end

        end

        new_page = page

        break

      end

    end

    if new_page == @page

      return

    end

    @page = new_page

    clear_starting

    if @page == nil

      @tile_id = 0

      @character_name = ""

      @character_hue = 0

      @move_type = 0

      @through = true

      @trigger = nil

      @list = nil

      @interpreter = nil

      return

    end

    @tile_id = @page.graphic.tile_id

    @character_name = @page.graphic.character_name

    @character_hue = @page.graphic.character_hue

    if @original_direction != @page.graphic.direction

      @direction = @page.graphic.direction

      @original_direction = @direction

      @prelock_direction = 0

    end

    if @original_pattern != @page.graphic.pattern

      @pattern = @page.graphic.pattern

      @original_pattern = @pattern

    end

    @opacity = @page.graphic.opacity

    @blend_type = @page.graphic.blend_type

    @move_type = @page.move_type

    @move_speed = @page.move_speed

    @move_frequency = @page.move_frequency

    @move_route = @page.move_route

    @move_route_index = 0

    @move_route_forcing = false

    @walk_anime = @page.walk_anime

    @step_anime = @page.step_anime

    @direction_fix = @page.direction_fix

    @through = @page.through

    @always_on_top = @page.always_on_top

    @trigger = @page.trigger

    @list = @page.list

    @interpreter = nil

    if @trigger == 4

      @interpreter = Interpreter.new

    end

    check_event_trigger_auto

    @sticky_switches = []

    for line in @list.find_all {|i| i.code == 108}

      a = line.parameters[0].strip.split(' ')

      if a[0] == "sticky_switch"

        if ["A", "B", "C", "D"].include?(a[1].upcase)

          id = a[1].upcase

        end

        # Start Edits

        e = []

        if a[2] == nil or a[2].to_i < 0

          e.push("$game_player")

       

        else

          if a[2] == "projectile"

            unless $projectiles_array.empty?

              $projectiles_array.each do |i|

                e.push("$game_map.events[#{i}]")

              end

            end

          else

            e.push("$game_map.events[#{a[2]}]")

          end

        end

        # End Edits

        if a[3] == nil

          d = 1

        else

          d = a[3].to_i

        end

        if a[4] == nil

          look = 0

        else

          look = a[4].to_i

        end

        @sticky_switches.push([id, e, d, look])

      end

    end

  end

  #--------------------------------------------------------------------------

  alias ss_update update

  def update

    ss_update

    update_sticky_switches

  end

  #--------------------------------------------------------------------------

  def update_sticky_switches

    for sswitch in @sticky_switches

      # Start Edits

      v = false

      for e in sswitch[1]

        event = eval(e) # change from string to object

        if sswitch[2] >= 0

          v = (event.x.between?(self.x-sswitch[2], self.x+sswitch[2]) and

               event.y.between?(self.y-sswitch[2], self.y+sswitch[2]))

        else

          v = true

        end

        if sswitch[3] != 0

          case sswitch[3]

          when +1 # Both Events Facing Eachother

            v &= self.facing?(event)

          when -1 # Both Events Facing Opposite Directions

            v &= self.opposite_dir?(event)

          when +2 # Event/Player is Facing Source Event

            v &= self.facingsource?(event)

           when -2 # Source Event is Facing Event/Player

            v &= self.sourcefacing?(event)

           when +3 # Event/Player is Facing Away from Event/Player

            v &= self.facingawaysource?(event)

           when -3 # Source Event is Facing Away from Event/Player

            v &= self.sourcefacingaway?(event)

          end

        end

        break if v == true

      end

      # End Edits

      if sswitch[0].is_a?(String) # Self Switches

        key = [@map_id, @id, sswitch[0]]

        $game_map.need_refresh |= (v != $game_self_switches[key])

        $game_self_switches[key] = v

      else                        # Switches

        $game_map.need_refresh |= (v != $game_switches[sswitch[0]])

        $game_switches[sswitch[0]] = v

      end

    end

  end

end

 

# 1.  Place any event on the map. I'll call this event self to avoid confusion.

# 2.  Open the event editor, and create a comment anywhere in the event (self).

# 3.  Type "sticky_switch" (without the quotes) in the top line of the event.

# 4.  Type a space, and then the id of the switch to become one of self's sticky switches. To use a local switch, type A, B, C, or D for the respective local switch.

# 5.  Type another space, and then the id of the event on the map to be checked to see if it is close to self. Type -1 or leave this blank to set the event to be the player.

# 6.  Type another space, and then the distance you want self to be able to detect the event. Leave this blank or enter 0 for no distance detection.

# 7.  Type another space, and then a number for the direction check mode: 0 (or blank) for no direction check, 1 to check if self is facing the event, and -1 to check if self is facing opposite of the event.

# 8.  Remember not to leave areas blank if you use something after it. For instance, fill in distance if you want to use direction checking.

# 9.  Repeat steps 2-8 to add any other sticky switches, on the same page or otherwise.

#10.  Click "Ok" on the event editor page, and test your game. The switch should turn on when the event is close to self.

#       View Types  0 = Event/Player is Within Sources Range

#                         1 = Both Events Are Facing Each Other

#                        -1 = Both Events Are Facing Away From Each Other

#                         2 = Event/Player is Facing Source

#                        -2 = Source is Facing Event/Player

#                         3 = Event/Player is Facing Away from Event/Player

#                        -3 = Source Event is Facing Away from Event/Player

I changed two sections. The first part is where you made your edits; instead of setting e to one event, I made it an array that pushes (adds) each item in the projectiles array.

The second edit is in "def update_sticky_switches"; because it's an array, not a single event, I added a for loop that checks each event. If at the end of one check "v" (your switch check variable) is true, it will break and not bother to check the other elements in the array.

Let me know if that works out!

PS I helped indent the script for you; one of my pet peeves is messy code! (No worries, yours was relatively clean compared to the mess of XAS_ABS...)
 
Thank you so much for you help Regi! That's what I love about this place, knowledgable, friendly users, and quick response times. However, I did run into some errors with the code you provided. I ran through a few scenarios, and these are the errors I came up with:

Checking for player
line 246: No Method Error occured
undefined method 'values' for ["$game_player"]:Array

Checking when no projectiles are on the map
line 246: No Method Error occured
undefined method 'values' for []:Array

Checked with two projectiles on the map, events 4 and 5
undefined method 'values' for [$game_map.events[4]", "$game_map.events[5]"]:Array

I really appreciate you taking the time to look at this for me, it'd mean a lot to the progress of my game if I could get this working properly. I'd be able to put more interactive objects on each map with less lag processing it. If you could take another look to see what might have went wrong, I'd be really thankful.
 
Oops, you can get rid of the ".values" on line 246. I have a habit of adding that since I always work with arrays with events :x

I also fixed indentation from lines 213-216, if you care about that :P The new code is in my previous post, or you can make the edits yourself.

Let me know if that works!
 
So I tried out the revised code, and two things I noticed:
It still isn't detecting the event id's that are projectiles, and when I try to check for both the player and a projectile in the same event, nothing will register. The player detection by itself still works fine though. There weren't any script errors this time around, but projectiles still aren't being detected.
 
Hrm... do you update $projectiles_array continuously? The way the script is currently set up, it only adds projectiles to the sticky switch whenever the event refreshes (each time it changes a page). This means if you add an event to $projectiles_array after the event has been set up, the new event won't register.

Try this:
Code:
#==============================================================================

# ■ Sticky Switches

#------------------------------------------------------------------------------

# This is the script for Sticky Switches.

#==============================================================================

# Version 3 by Astro_mech

# Version 3 Update by Ace of Spades

#==============================================================================

# ■ Game_Character

#------------------------------------------------------------------------------

#   With Facing Detection by: Astro_mech

#   New Facing Detections by: Ace of Spades

#==============================================================================

 

class Game_Character

  DOWN  = 2

  LEFT  = 4

  RIGHT = 6

  UP    = 8

  #--------------------------------------------------------------------------

  def facing?(event)

    case @direction

    when DOWN

      return (self.y < event.y and event.direction == UP)

    when LEFT

      return (self.x < event.x and event.direction == RIGHT)

    when RIGHT

      return (self.x > event.x and event.direction == LEFT)

    when UP

      return (self.y > event.y and event.direction == DOWN)

    end

  end

  #--------------------------------------------------------------------------

  def opposite_dir?(event)

    case @direction

    when DOWN

      return (self.y > event.y and event.direction == UP)

    when LEFT

      return (self.x > event.x and event.direction == RIGHT)

    when RIGHT

      return (self.x < event.x and event.direction == LEFT)

    when UP

      return (self.y < event.y and event.direction == DOWN)

    end

  end

  #--------------------------------------------------------------------------

   def sourcefacing?(event)

    case @direction

    when DOWN

      return (self.y < event.y)

    when LEFT

      return (self.x < event.x)

    when RIGHT

      return (self.x > event.x)

    when UP

      return (self.y > event.y)

    end

  end

  #--------------------------------------------------------------------------

  def facingsource?(event)

     if event.direction == DOWN

       return (self.y > event.y)

     end

     if event.direction == LEFT

       return (self.x < event.x)

     end

     if event.direction == RIGHT

      return (self.x > event.x)

      end

     if event.direction == UP

      return (self.y < event.y)

    end

  end

   #--------------------------------------------------------------------------

  def facingawaysource?(event)

     if event.direction == UP

       return (self.y > event.y)

     end

     if event.direction == RIGHT

       return (self.x < event.x)

     end

     if event.direction == LEFT

      return (self.x > event.x)

      end

     if event.direction == DOWN

      return (self.y < event.y)

    end

  end

   #--------------------------------------------------------------------------

   def sourcefacingaway?(event)

    case @direction

    when UP

      return (self.y < event.y)

    when RIGHT

      return (self.x < event.x)

    when LEFT

      return (self.x > event.x)

    when DOWN

      return (self.y > event.y)

    end

  end

  #------------------------------------------------------------------------------

end

#==============================================================================

# ■ Game_Event

#------------------------------------------------------------------------------

#  With Sticky Keys by Astro_mech

#==============================================================================

 

class Game_Event < Game_Character

  #--------------------------------------------------------------------------

  alias ss_initialize initialize

  def initialize(*args)

    @sticky_switches = []

    @last_projectiles = []

    ss_initialize(*args)

  end

  #--------------------------------------------------------------------------

  def refresh

    new_page = nil

    unless @erased

      for page in @event.pages.reverse

        c = page.condition

        if c.switch1_valid

          if $game_switches[c.switch1_id] == false

            next

          end

        end

        if c.switch2_valid

          if $game_switches[c.switch2_id] == false

            next

          end

        end

        if c.variable_valid

          if $game_variables[c.variable_id] < c.variable_value

            next

          end

        end

        if c.self_switch_valid

          key = [@map_id, @event.id, c.self_switch_ch]

          if $game_self_switches[key] != true

            next

          end

        end

        new_page = page

        break

      end

    end

    if new_page == @page

      return

    end

    @page = new_page

    clear_starting

    if @page == nil

      @tile_id = 0

      @character_name = ""

      @character_hue = 0

      @move_type = 0

      @through = true

      @trigger = nil

      @list = nil

      @interpreter = nil

      return

    end

    @tile_id = @page.graphic.tile_id

    @character_name = @page.graphic.character_name

    @character_hue = @page.graphic.character_hue

    if @original_direction != @page.graphic.direction

      @direction = @page.graphic.direction

      @original_direction = @direction

      @prelock_direction = 0

    end

    if @original_pattern != @page.graphic.pattern

      @pattern = @page.graphic.pattern

      @original_pattern = @pattern

    end

    @opacity = @page.graphic.opacity

    @blend_type = @page.graphic.blend_type

    @move_type = @page.move_type

    @move_speed = @page.move_speed

    @move_frequency = @page.move_frequency

    @move_route = @page.move_route

    @move_route_index = 0

    @move_route_forcing = false

    @walk_anime = @page.walk_anime

    @step_anime = @page.step_anime

    @direction_fix = @page.direction_fix

    @through = @page.through

    @always_on_top = @page.always_on_top

    @trigger = @page.trigger

    @list = @page.list

    @interpreter = nil

    if @trigger == 4

      @interpreter = Interpreter.new

    end

    check_event_trigger_auto

    @sticky_switches = []

    for line in @list.find_all {|i| i.code == 108}

      a = line.parameters[0].strip.split(' ')

      if a[0] == "sticky_switch"

        if ["A", "B", "C", "D"].include?(a[1].upcase)

          id = a[1].upcase

        end

        # Start Edits

        e = []

        if a[2] == nil or a[2].to_i < 0

          e.push("$game_player")

       

        elsif a[2] == "projectile"

          unless $projectiles_array.empty?

            $projectiles_array.each do |i|

              e.push("$game_map.events[#{i}]")

            end

          end

        else

          e.push("$game_map.events[#{a[2]}]")

        end

        # End Edits

        if a[3] == nil

          d = 1

        else

          d = a[3].to_i

        end

        if a[4] == nil

          look = 0

        else

          look = a[4].to_i

        end

        @sticky_switches.push([id, e, d, look])

      end

    end

  end

  #--------------------------------------------------------------------------

  alias ss_update update

  def update

    ss_update

    

    return if @sticky_switches.empty?

    if @last_projectiles != $projectiles_array

      refresh

      @last_projectiles = $projectiles_array

    end

    update_sticky_switches

  end

  #--------------------------------------------------------------------------

  def update_sticky_switches

    for sswitch in @sticky_switches

      # Start Edits

      v = false

      for e in sswitch[1]

        event = eval(e) # change from string to object

        if sswitch[2] >= 0

          v = (event.x.between?(self.x-sswitch[2], self.x+sswitch[2]) and

               event.y.between?(self.y-sswitch[2], self.y+sswitch[2]))

        else

          v = true

        end

        if sswitch[3] != 0

          case sswitch[3]

          when +1 # Both Events Facing Eachother

            v &= self.facing?(event)

          when -1 # Both Events Facing Opposite Directions

            v &= self.opposite_dir?(event)

          when +2 # Event/Player is Facing Source Event

            v &= self.facingsource?(event)

           when -2 # Source Event is Facing Event/Player

            v &= self.sourcefacing?(event)

           when +3 # Event/Player is Facing Away from Event/Player

            v &= self.facingawaysource?(event)

           when -3 # Source Event is Facing Away from Event/Player

            v &= self.sourcefacingaway?(event)

          end

        end

        break if v == true

      end

      # End Edits

      if sswitch[0].is_a?(String) # Self Switches

        key = [@map_id, @id, sswitch[0]]

        $game_map.need_refresh |= (v != $game_self_switches[key])

        $game_self_switches[key] = v

      else                        # Switches

        $game_map.need_refresh |= (v != $game_switches[sswitch[0]])

        $game_switches[sswitch[0]] = v

      end

    end

  end

end

 

# 1.  Place any event on the map. I'll call this event self to avoid confusion.

# 2.  Open the event editor, and create a comment anywhere in the event (self).

# 3.  Type "sticky_switch" (without the quotes) in the top line of the event.

# 4.  Type a space, and then the id of the switch to become one of self's sticky switches. To use a local switch, type A, B, C, or D for the respective local switch.

# 5.  Type another space, and then the id of the event on the map to be checked to see if it is close to self. Type -1 or leave this blank to set the event to be the player.

# 6.  Type another space, and then the distance you want self to be able to detect the event. Leave this blank or enter 0 for no distance detection.

# 7.  Type another space, and then a number for the direction check mode: 0 (or blank) for no direction check, 1 to check if self is facing the event, and -1 to check if self is facing opposite of the event.

# 8.  Remember not to leave areas blank if you use something after it. For instance, fill in distance if you want to use direction checking.

# 9.  Repeat steps 2-8 to add any other sticky switches, on the same page or otherwise.

#10.  Click "Ok" on the event editor page, and test your game. The switch should turn on when the event is close to self.

#       View Types  0 = Event/Player is Within Sources Range

#                         1 = Both Events Are Facing Each Other

#                        -1 = Both Events Are Facing Away From Each Other

#                         2 = Event/Player is Facing Source

#                        -2 = Source is Facing Event/Player

#                         3 = Event/Player is Facing Away from Event/Player

#                        -3 = Source Event is Facing Away from Event/Player
I added a @last_projectiles variable that is compared to $projectiles_array in the update function, which refreshes the event (and sticky-switch) if $projectile_array changes.

This still doesn't fix testing a player AND a projectile simultaneously, but if you let me know how you want the syntax to be, I can help you.
 
Okay, so it seemed you were correct about the problem. However, it still only detects projectiles that have entered the map before the event page is activated. The way I have everything set up now, is the collision of objects is detected with parallel process events. So every object (bush, rock, enemy, etc) that the player interacts with, is constantly checking for collision. The idea of this script is to have all those events set up as action key events on the first page, with a sticky switch that activates a local switch whenever the player or a projectile is in range, so they aren't constantly checking for collision. So essentially, yes, I'd need it to refresh what the event is checking for whenever a new projectile is added or removed. As far as the syntax goes, it doesn't matter if I could use two separate commands to check for both the player and projectiles, or if there would be one command to check for the player and projectiles in a two tile range simultaneously
 
Hopefully this should do it.
Code:
#==============================================================================

# ■ Sticky Switches

#------------------------------------------------------------------------------

# This is the script for Sticky Switches.

#==============================================================================

# Version 3 by Astro_mech

# Version 3 Update by Ace of Spades

#==============================================================================

# ■ Game_Character

#------------------------------------------------------------------------------

#   With Facing Detection by: Astro_mech

#   New Facing Detections by: Ace of Spades

#==============================================================================

 

class Game_Character

  DOWN  = 2

  LEFT  = 4

  RIGHT = 6

  UP    = 8

  #--------------------------------------------------------------------------

  def facing?(event)

    case @direction

    when DOWN

      return (self.y < event.y and event.direction == UP)

    when LEFT

      return (self.x < event.x and event.direction == RIGHT)

    when RIGHT

      return (self.x > event.x and event.direction == LEFT)

    when UP

      return (self.y > event.y and event.direction == DOWN)

    end

  end

  #--------------------------------------------------------------------------

  def opposite_dir?(event)

    case @direction

    when DOWN

      return (self.y > event.y and event.direction == UP)

    when LEFT

      return (self.x > event.x and event.direction == RIGHT)

    when RIGHT

      return (self.x < event.x and event.direction == LEFT)

    when UP

      return (self.y < event.y and event.direction == DOWN)

    end

  end

  #--------------------------------------------------------------------------

   def sourcefacing?(event)

    case @direction

    when DOWN

      return (self.y < event.y)

    when LEFT

      return (self.x < event.x)

    when RIGHT

      return (self.x > event.x)

    when UP

      return (self.y > event.y)

    end

  end

  #--------------------------------------------------------------------------

  def facingsource?(event)

     if event.direction == DOWN

       return (self.y > event.y)

     end

     if event.direction == LEFT

       return (self.x < event.x)

     end

     if event.direction == RIGHT

      return (self.x > event.x)

      end

     if event.direction == UP

      return (self.y < event.y)

    end

  end

   #--------------------------------------------------------------------------

  def facingawaysource?(event)

     if event.direction == UP

       return (self.y > event.y)

     end

     if event.direction == RIGHT

       return (self.x < event.x)

     end

     if event.direction == LEFT

      return (self.x > event.x)

      end

     if event.direction == DOWN

      return (self.y < event.y)

    end

  end

   #--------------------------------------------------------------------------

   def sourcefacingaway?(event)

    case @direction

    when UP

      return (self.y < event.y)

    when RIGHT

      return (self.x < event.x)

    when LEFT

      return (self.x > event.x)

    when DOWN

      return (self.y > event.y)

    end

  end

  #------------------------------------------------------------------------------

end

#==============================================================================

# ■ Game_Event

#------------------------------------------------------------------------------

#  With Sticky Keys by Astro_mech

#==============================================================================

 

class Game_Event < Game_Character

  #--------------------------------------------------------------------------

  alias ss_initialize initialize

  def initialize(*args)

    @sticky_switches = []

    ss_initialize(*args)

  end

  #--------------------------------------------------------------------------

  def refresh

    new_page = nil

    unless @erased

      for page in @event.pages.reverse

        c = page.condition

        if c.switch1_valid

          if $game_switches[c.switch1_id] == false

            next

          end

        end

        if c.switch2_valid

          if $game_switches[c.switch2_id] == false

            next

          end

        end

        if c.variable_valid

          if $game_variables[c.variable_id] < c.variable_value

            next

          end

        end

        if c.self_switch_valid

          key = [@map_id, @event.id, c.self_switch_ch]

          if $game_self_switches[key] != true

            next

          end

        end

        new_page = page

        break

      end

    end

    if new_page == @page

      return

    end

    @page = new_page

    clear_starting

    if @page == nil

      @tile_id = 0

      @character_name = ""

      @character_hue = 0

      @move_type = 0

      @through = true

      @trigger = nil

      @list = nil

      @interpreter = nil

      return

    end

    @tile_id = @page.graphic.tile_id

    @character_name = @page.graphic.character_name

    @character_hue = @page.graphic.character_hue

    if @original_direction != @page.graphic.direction

      @direction = @page.graphic.direction

      @original_direction = @direction

      @prelock_direction = 0

    end

    if @original_pattern != @page.graphic.pattern

      @pattern = @page.graphic.pattern

      @original_pattern = @pattern

    end

    @opacity = @page.graphic.opacity

    @blend_type = @page.graphic.blend_type

    @move_type = @page.move_type

    @move_speed = @page.move_speed

    @move_frequency = @page.move_frequency

    @move_route = @page.move_route

    @move_route_index = 0

    @move_route_forcing = false

    @walk_anime = @page.walk_anime

    @step_anime = @page.step_anime

    @direction_fix = @page.direction_fix

    @through = @page.through

    @always_on_top = @page.always_on_top

    @trigger = @page.trigger

    @list = @page.list

    @interpreter = nil

    if @trigger == 4

      @interpreter = Interpreter.new

    end

    check_event_trigger_auto

    @sticky_switches = []

    for line in @list.find_all {|i| i.code == 108}

      a = line.parameters[0].strip.split(' ')

      if a[0] == "sticky_switch"

        if ["A", "B", "C", "D"].include?(a[1].upcase)

          id = a[1].upcase

        end

        # Start Edits

        events = []

        chars = a[2].strip.split(',')

        for c in chars

          if c == nil or c.to_i < 0

            events.push("$game_player")

          elsif c == "p" or c == "projectiles"

            events.push("projectiles")

          else

            events.push("$game_map.events[#{c}]")

          end

        end

        # End Edits

        if a[3] == nil

          dir = 1

        else

          dir = a[3].to_i

        end

        if a[4] == nil

          look = 0

        else

          look = a[4].to_i

        end

        @sticky_switches.push([id, events, dir, look])

      end

    end

  end

  #--------------------------------------------------------------------------

  alias ss_update update

  def update

    ss_update

    return if @sticky_switches.empty?

    update_sticky_switches

  end

  #--------------------------------------------------------------------------

  def update_sticky_switches

    for sswitch in @sticky_switches

      # Start Edits

      v = false

      events = sswitch[1].dup

      if events.include?("projectiles")

        unless $projectiles_array.empty?

          $projectiles_array.each do |i|

            events.push("$game_map.events[#{i}]")

          end

        end

        events.delete("projectiles")

      end

      for e in events

        event = eval(e) # change from string to object

        if sswitch[2] >= 0

          v = (event.x.between?(self.x-sswitch[2], self.x+sswitch[2]) and

               event.y.between?(self.y-sswitch[2], self.y+sswitch[2]))

        else

          v = true

        end

        if sswitch[3] != 0

          case sswitch[3]

          when +1 # Both Events Facing Eachother

            v &= self.facing?(event)

          when -1 # Both Events Facing Opposite Directions

            v &= self.opposite_dir?(event)

          when +2 # Event/Player is Facing Source Event

            v &= self.facingsource?(event)

          when -2 # Source Event is Facing Event/Player

            v &= self.sourcefacing?(event)

          when +3 # Event/Player is Facing Away from Event/Player

            v &= self.facingawaysource?(event)

          when -3 # Source Event is Facing Away from Event/Player

            v &= self.sourcefacingaway?(event)

          end

        end

        break if v == true

      end

      # End Edits

      if sswitch[0].is_a?(String) # Self Switches

        key = [@map_id, @id, sswitch[0]]

        $game_map.need_refresh |= (v != $game_self_switches[key])

        $game_self_switches[key] = v

      else                        # Switches

        $game_map.need_refresh |= (v != $game_switches[sswitch[0]])

        $game_switches[sswitch[0]] = v

      end

    end

  end

end

 

# 1.  Place any event on the map. I'll call this event self to avoid confusion.

# 2.  Open the event editor, and create a comment anywhere in the event (self).

# 3.  Type "sticky_switch" (without the quotes) in the top line of the event.

# 4.  Type a space, and then the id of the switch to become one of self's sticky switches. To use a local switch, type A, B, C, or D for the respective local switch.

# 5.  Type another space, and then the id of the event on the map to be checked to see if it is close to self. Type -1 or leave this blank to set the event to be the player.

# 6.  Type another space, and then the distance you want self to be able to detect the event. Leave this blank or enter 0 for no distance detection.

# 7.  Type another space, and then a number for the direction check mode: 0 (or blank) for no direction check, 1 to check if self is facing the event, and -1 to check if self is facing opposite of the event.

# 8.  Remember not to leave areas blank if you use something after it. For instance, fill in distance if you want to use direction checking.

# 9.  Repeat steps 2-8 to add any other sticky switches, on the same page or otherwise.

#10.  Click "Ok" on the event editor page, and test your game. The switch should turn on when the event is close to self.

#       View Types  0 = Event/Player is Within Sources Range

#                         1 = Both Events Are Facing Each Other

#                        -1 = Both Events Are Facing Away From Each Other

#                         2 = Event/Player is Facing Source

#                        -2 = Source is Facing Event/Player

#                         3 = Event/Player is Facing Away from Event/Player

#                        -3 = Source Event is Facing Away from Event/Player
The syntax for multiple events should be:
sticky_switch A -1,1,p 64 0

In this case, you'd be checking for the player, event 1, and all projectiles (make sure not to add any spaces between commas, or it'll think you're moving on). You can type either "p" or "projectiles"; I thought the former would be easier.

If you're wondering how, I changed the comment from adding the events themselves to simply adding the string "projectiles". Then in "update_sticky_switches", it checks if the array of events includes "projectiles"; if so, it deletes that and adds all the events in $projectiles_array. This way, there's no need to refresh the page, as it updates every frame, and should catch new projectiles.
 
Well, I've been using the script for a couple days and everything appears to be working correctly! Hopefully I can start placing more objects on the map and not have to worry about it hurting the performance too much. I just want to thank you again for all your help, I really do appreciate it, and I'll certainly be placing your name in the credits.

In the mean time, if there's anything I can possibly help you with in return, feel free to let me know.
 
You're welcome, glad I could help! I don't think I need much help other than feedback on ideas and beta-testers, later, but if you're willing I can definitely give you a link to my private subforum.
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top