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?
next if !$Something[i]
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
endbut 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.
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*
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"
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*
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 ^^