Main Menu
  • Welcome to The RPG Maker Resource Kit.

[RESOLVED]how do you get around an expected nil?

Started by shintashi, December 13, 2010, 02:25:06 AM

0 Members and 1 Guest are viewing this topic.

shintashi

I'm trying to do a basic for loop using 1..20 and i, to query/ask if stats about the events on my maps are true. I know that the event numbers will vary from map to map, and in many cases there will either be no event or the event won't have the attributes that make it relevant.


my question is, when I've got something simple like

   x = 10
for i in 1..20
     y = $Something[i].stat
    z = x - y
if z > 5
return   $Something[i].stat += 1
end
end


How do I prevent it from crashing when i returns a nil, because say, event #17 doesn't even exist?

modern algebra


shintashi

Quote from: modern algebra on December 13, 2010, 02:54:42 AM
next if !$Something[i]


That works pretty good actually, but I ran into a strange thing (because I suck at for loops)

I wrote this code:

class Post
  def initialize
    a = $game_map.events[14].x  #coordinate of landmine
for i in 1..20
   next if !$ABS.enemies[i]
    b = $ABS.enemies[i].event.x #coordinate of enemy mob
    d = a - b
    if $ABS.enemies[i].hp > 20
        return $ABS.enemies[i].hp -= d < 2 ? 20 : 0
       end
    end
  end
end


but when I trigger it (using event 14) ALL of the monsters on the map take damage, even if they aren't in range. I think its because my logic is screwed up on the range, if even one of the monsters is in range, it does damage to them all.

Zeriab

What happens if d is say -7?
Yes, you'll want the absolute value of d.

class Post
  def initialize
    a = $game_map.events[14].x  #coordinate of landmine
    for i in 1..20
      next if !$ABS.enemies[i]
      b = $ABS.enemies[i].event.x #coordinate of enemy mob
      d = a - b
      if $ABS.enemies[i].hp > 20
        return $ABS.enemies[i].hp -= d.abs < 2 ? 20 : 0
      end
    end
  end
end


You are still only looking at the x coordinate which means the mine will explode in a 5 tile wide vertical line. (Or at least do damage there.)
If you want a diamond shaped area you can do something like this:
class Post
  def initialize
    landmine = $game_map.events[14]  #coordinate of landmine
    for i in 1..20
      next if !$ABS.enemies[i]
      enemy = $ABS.enemies[i].event #coordinate of enemy mob
      d = (landmine.x - enemy.x).abs + (landmine.y - enemy.y).abs
      if $ABS.enemies[i].hp > 20
        return $ABS.enemies[i].hp -= d < 2 ? 20 : 0
      end
    end
  end
end


Assuming $ABS.enemies is an array I would use the array's .each method and clean up the code like this:
class Post
  def initialize
    landmine = $game_map.events[14]  #coordinate of landmine
    for enemy in $ABS.enemies
      next unless enemy
      # Calculate manhatten distance
      d = (landmine.x - enemy.event.x).abs + (landmine.y - enemy.event.y).abs
      if enemy.hp > 20
        return enemy.hp -= d < 2 ? 20 : 0
      end
    end
  end
end


I haven't tested any of the code snippets, but I do hope it'll help you along ^_^

*hugs*

shintashi

the absolute value thing is pretty useful, though the last version (array) crashed - it said something about array in the error box. The other two for some reason only do damage to the lowest numbered monster, ignoring the rest.

I've tried it both on event touch and parallel.

It's got to be something missing in the logic, like one of the lines is out of order or something.

We have "attack first monster  in this list when it is in range" and
"attack all monsters when one monster is in range"

but we don't have "attack N monster when N monster is in range"

Zeriab

You got an error because my assumption that $ABS.enemies was an array was wrong. If it's a hash you can use $ABS.enemies.values instead.

Anyway let's look at the working version for the first monster in range.
Why do you return the resulting hp... in a initialization method?
No need to break execution by returning the value. Just change the hp of the enemy.

What are you reasons for placing the calculations in a initialization method?

*hugs*

shintashi

oh wow. by removing "return" the monsters all die only when in range. That's awesome!

I would ask to make the monsters run away at this time, but ABS doesn't have a "fear" program yet, and I don't think regular Battle does either, although I could totally see it being used for wards and what not. This will suffice for now. Thanks much to both of you ^^