ID:261817
 
Here I have some A.I. tha I've been working for mobs... and the problem is a type Mismatch on the specified line.

R = return
Sp() = spawn
I used the #define for those 2

mob/proc/PreyAI()
if(!canattack)
if(prey.len)
for(var/mob/M in prey)
if(!M) R
else prey -= M
else R
else if(canattack)
if(length(prey))
for(var/mob/M in prey)
if(!M) R
else
if(!M in oview(vision)) prey -= M
else if(!M.infight) M.suffix = ""
for(var/mob/M in oview(vision))
if(!M) R
if(istype(src,/mob/NPC) && istype(M,/mob/NPC)) R //An NPC can't attack another NPC
if(M in prey) R // ERROR IS HERE
else src.prey += M
if(M.infight) M.suffix = "Fighting"
Sp() PreyAI()

mob/NPC/proc/AttkAI()
if(ischasing) R
if(length(prey)) R
else for(var/mob/M in prey)
if(M.infight) R
var/emotion = personality + mood
var/attkchance = prob(round(emotion))
if(attkchance)
ischasing = M
while(M in prey)
step_towards(src,M)
sleep(src.walkdelay)


It adds the mob that it finds into prey which is displayed on the Statpanel, but it still gives Type Mismatch and it also isn't calling AttkAI().

Note that I put AttkAI() in because I suspect that there will be something wrong with it when the other proc is fixed, and was hoping someone may save me the trouble of finding it myself, lol.

Resonating Light
Are you certain the type mismatch isn't actually on the line after that? Because it looks to me like the prey var has not been defined or initialized correctly as a list, and there's the problem.

One thing I can tell you: Using return in those loops is a bad idea; you should use continue instead, which will skip to the next thing in the loop. Whenever you use return or continue (or break) at the end of an if() block, too, you won't need the else statement because it's implied.
if(M in prey) R
else src.prey += M
There's no use to that else there.

Besides that, I'm a little curious why you've set up #define statements for return and spawn; unless you're writing a game for the next 4K challenge, they're just going to clutter your code and cause confusion.

Lummox JR
In response to Lummox JR
Lummox JR wrote:
Are you certain the type mismatch isn't actually on the line after that? Because it looks to me like the prey var has not been defined or initialized correctly as a list, and there's the problem.

Oh! I didn't notice that, but yeah... It's on the line below. And here is how I have prey defined.
mob/var/prey[]


If I'm not mistaken, that should create an empty list correctly.
One thing I can tell you: Using return in those loops is a bad idea; you should use continue instead, which will skip to the next thing in the loop. Whenever you use return or continue (or break) at the end of an if() block, too, you won't need the else statement because it's implied.
if(M in prey) R
> else src.prey += M
There's no use to that else there.

Thanks, I wasn't really sure about all that. I'll have to go through and fix all those.
Besides that, I'm a little curious why you've set up #define statements for return and spawn; unless you're writing a game for the next 4K challenge, they're just going to clutter your code and cause confusion.

I actaully created #defines for a lot of things... And to be honest, the only reason I did it was because I finally learned just what #defines did and got fascinated with them, then got a little carried away, lol.
Lummox JR

[EDIT]I just decided to change prey to
mob/var/list/prey = new()
and it worked... I don't really understand why that mattered though, so yeah... Why did that fix the problem?
In response to Resonating_Light
I have another question, how does break work? Does it completely terminate the loop that it's in or what exactely? I know it stops the loop but I'm not sure to what point the loop is stopped. E.G.
mob/proc/Findbirdys()
var/list/L = new()
for(var/mob/M in world)
if(istype(M,/mob/birdy))
L += M
break
src << L
Would that add every mob that is type /mob/bird to the list, or would it just quit after it finds one /mob/bird? I ask this because after editing the code with breaks and such, it seems to screw up somewhat... For instance, I took a few steps and had a mob in view but it didn't add it immediately, I had to take a few more steps before the mob was added to the prey list. And I double checked if the players vision var was set to 6 just as world.view is.

So, I probably did something wrong with the breaks and/or whatever else I changed in it.
mob/proc/PreyAI()
if(!canattack)
if(prey.len)
for(var/mob/M in prey)
if(!M) break
prey -= M
else return
if(canattack)
if(length(prey))
for(var/mob/M in prey)
if(!M) break
if(!M in oview(vision)) prey -= M
else if(!M.infight) M.suffix = ""
for(var/mob/M in oview(vision))
if(!M) break
if(istype(src,/mob/NPC) && istype(M,/mob/NPC)) break//An NPC can't attack another NPC
if(M in prey)
if(M.infight) M.suffix = "Fighting"
break
prey += M // ERROR IS HERE
Sp() PreyAI()
In response to Resonating_Light
Resonating_Light wrote:
mob/var/prey[]

[EDIT]I just decided to change prey to
mob/var/list/prey = new()
and it worked... I don't really understand why that mattered though, so yeah... Why did that fix the problem?

There's a difference between a blank list and an uninitialised list. mob/var/prey[] just makes a list called prey, but doesn't actually "create" it properly. Whereas "mob/var/list/prey = new()" does (hence the "new"). You could also have specified the length of the prey list as zero, like this: mob/var/prey[0]
In response to Resonating_Light
Resonating_Light wrote:
Would that add every mob that is type /mob/bird to the list, or would it just quit after it finds one /mob/bird?

The latter. It "break"s out of a loop completely, and doesn't execute any further iterations of the loop.

You might want to look at the "continue" statement; it just ends the current iteration, and continues looping.
In response to Resonating_Light
Resonating_Light wrote:
Lummox JR wrote:
Are you certain the type mismatch isn't actually on the line after that? Because it looks to me like the prey var has not been defined or initialized correctly as a list, and there's the problem.

Oh! I didn't notice that, but yeah... It's on the line below. And here is how I have prey defined.
mob/var/prey[]


That won't do it for you. You need to define this as mob/var/list/prey, and then in New() actually initialize the list with prey=new or prey=list().

If I'm not mistaken, that should create an empty list correctly.

It may for some cases, but it's not a safe way to handle lists for mobs because when you define a var as a list for a datum, all datums of that type will share the same list.

Besides that, I'm a little curious why you've set up #define statements for return and spawn; unless you're writing a game for the next 4K challenge, they're just going to clutter your code and cause confusion.

I actaully created #defines for a lot of things... And to be honest, the only reason I did it was because I finally learned just what #defines did and got fascinated with them, then got a little carried away, lol.

Heh. That's understandable.

You're best off saving #define for constants (at least, the kind where a var/const isn't what you need), and for mini-procs you'd use a lot like this:
#define qdel(a) if(a) del(a)
That kind of thing can be useful.

[EDIT]I just decided to change prey to mob/var/list/prey = new() and it worked... I don't really understand why that mattered though, so yeah... Why did that fix the problem?

Because the problem lies in the way lists are initialized. I'm not entirely sure that's a safe syntax to use, though: For absolutely robust code I'd not initialize the list there (just declare it, but don't use =new()), and instead initialize it in the mob/New() proc.

Also, you can initialize lists as need arises, which sometimes is a much better way. Just do a check before you add anything to the list or work with it:
if(!prey) prey = new
That will save DM from having to keep track of a lot of empty lists. Additionally you can always set prey to null whenever the list is emptied. It's a good way to conserve memory and makes your game friendlier to larger worlds and more players.

Lummox JR
In response to Crispy
Thanks to both of ya.