ID:264849
 
Code:
mob
trainer
rattata1
New()
Equipping(new/mob/Rattata,0,0)
dir = EAST
LineOfSight(2)
proc/LineOfSight(tiles, continuecheck = 1)
for(var/mob/M in view(tiles))
var/check = 0
for(var/mob/N in playersbattled)
if(N == M)
check = 1
if(check == 0)
if(dir == EAST)
if(M.x > x && M.y == y)
M.frozen = 1
sleep(5)
walk_to(M,src,1,1)
M.Battle(src)
if(dir == WEST)
if(M.x < x && M.y == y)
M.frozen = 1
sleep(5)
walk_to(M,src,1,1)
M.Battle(src)
if(dir == NORTH)
if(M.y > y && M.x == x)
M.frozen = 1
sleep(5)
walk_to(M,src,1,1)
M.Battle(src)
if(dir == SOUTH)
if(M.y < y && M.x == x)
M.frozen = 1
sleep(5)
walk_to(M,src,1,1)
M.Battle(src)
if(continuecheck)
LineOfSight(tiles)


Problem description:
This is my code for an NPC trainer in my pokemon game. I am trying to make a working "Line Of Sight" proc, so that the NPC trainer continuously checks the tiles in front of the NPC for players, and begins a battle with any player they haven't battled with.

However, when i walk in front of the "rattata1" trainer, whether one or two tiles in front, the appropriate action isnt carried out. Where have i gone wrong?

EDIT: I understand it has something to do with the loops, from bug testing.
A proc repeatedly calling itself at the end is a pretty poor method of looping. Given that there isn't even a delay unless a mob is found, it is probably killing itself as some sort of safety precaution. I would suggest the use of a while() loop instead. Although for this particular function, I prefer Garthor's method above.
In response to Zagreus
mob
trainer
rattata1
New()
Equipping(new/mob/Rattata,0,0)
dir = EAST
for()
LineOfSight(2)
sleep(1)

proc/LineOfSight(tiles)
for(var/mob/M in oview(tiles))
var/check = 0
for(var/mob/N in playersbattled)
if(N == M)
check = 1
if(check == 0)
if(dir == EAST)
if(M.x > x && M.y == y)
M.frozen = 1
spawn(10)
walk_to(M,src,1,0)
spawn(5)
playersbattled.Add(M)
M.Battle(src)
if(dir == WEST)
if(M.x < x && M.y == y)
M.frozen = 1
spawn(10)
walk_to(M,src,1,0)
spawn(5)
playersbattled.Add(M)
M.Battle(src)
if(dir == NORTH)
if(M.y > y && M.x == x)
M.frozen = 1
spawn(10)
walk_to(M,src,1,0)
spawn(5)
playersbattled.Add(M)
M.Battle(src)
if(dir == SOUTH)
if(M.y < y && M.x == x)
M.frozen = 1
spawn(10)
walk_to(M,src,1,0)
spawn(5)
playersbattled.Add(M)
M.Battle(src)

Ok, i made these changes. And if you mean running the proc whilst a mob is in the NPC's view/line of sight, how would that be done?

I also now encountered another problem.
mob/proc/Battle(mob/M)

because i have used src throught that proc, it believes src is the rattata trainer, not the player in line of sight. do I have to go through it all adding in a new mob/N var, and changing src to N? or is there something else i can do?
Strongly suggest tying this to Move() instead, as the only time you should be checking anything is when a mob moves. Like so:

mob/player/Move()
.=..()
if(.)
for(var/mob/trainer/T in oview(src))
if(T.LineOfSight(src))
src.Battle(T)
// Only battle one at a time, though proper map design should make this unnecessary:
return

mob/trainer
var/sight_range = 2
proc/LineOfSight(var/mob/M)
if(get_dir(src,M) == src.dir)
if(get_dist(src,M) <= sight_range)
return 1
return 0
In response to Garthor
I like your method so much better that I'm a little embarrassed about trying to fix the original method.

I have a habit of when someone shows me their problem to think "How can I make this work using the method provided." instead of thinking first about whether or not the method provided is the best way to accomplish the task or not.
In response to Garthor
<s>Well, its actually made so that more than one player can battle the trainer at one time. Instead of using the trainer's hp for the battle, a copy of the trainer's hp and max hp is used for the battle.

I'm basically trying to make it like the cartridge games for DS and such, where its one player. So the players can interact with the world and follow the storyline, and still be able to talk to their friends and such, and challenge each other to battles (in a specific area of course).

So would i have to change this code in order to account for that? Or should it still work anyway?</s>

EDIT: Never mind, i read it wrong. Thanks, garthor.