ID:140608
 
Code:
mob
icon='Enemies.dmi'
CircleDemon
icon_state="CircleDemon"
hp = 50
str = 7
def = 10
monster = 1
AI()
New()
. = ..()
Wolf
icon_state="Wolf"
hp = 20
str = 1
def = 2
monster = 1
Elephant
icon_state="Elephant"
hp = 40
str = 3
def = 5
monster = 1
mob
proc
AI()
for(var/mob/M in oview(5,src)) //List of mobs 5 tiles or closer to monster
if(M.client) //If M's monster var is 0
walk_to(src,M,1,3) // Walk to it every .3 secs until it is 1 tile away
if(get_dist(src,M)<=1) //If it is 1 tile or less away
src.attack(M) //Attack it
spawn(2)src.AI() //Repeat
else //If M's monster var is 1
return // Screw it.


mob
proc
AIdef()
for(var/mob/M in oview(5,src))
if(src.monster == 1)
walk_to(src,M,1,3)
src.attack(M)

mob
proc
attack(mob/defender)
if(atking == 1)
return
else
if(src.str-defender.def <=0)
oview(2)<<"[defender] has dodged [src]'s attack!"
atking = 1
sleep(5)
atking = 0
else
var/damage=src.str-defender.def*rand(1,2)
defender.hp-=damage
oview(2)<<"[defender] was hit by [src] for [damage] Damage!"
if(defender.hp<=0)
defender.deathcheck()
atking = 1
sleep (20)
atking = 0


Problem description:
The monster won't attack back
First, your AI proc is written wrong. It should look more like this:

mob/proc/AI()
while(src)
for(var/mob/M in oview(5,src))
if(M.client)
if(get_dist(src,M) > 1)
step_to(src,M)
else
src.attack(M)
//break so we don't try to attack two players at once
break
//sleep 2 ticks between moves
sleep(2)


I don't know what you want the AIdef() proc to be, so it just shouldn't exist really.

Second, you need to change oview(2) in your attack() proc to be oview(2,src). Though, probably it should be view().

Third, you are never actually calling your AI() proc. The line that you do have:

mob
CircleDemon
AI()


doesn't call the proc, it overrides it and replaces it with one that does nothing. To call it, you should put it in New(), like so:

mob
CircleDemon
New()
..()
spawn() AI()


spawn() is used because we don't want to wait for AI() to finish (as it never will) before continuing with the New() proc.
In response to Garthor
Well i had the AI() in that position before but it still doesn't attack back(but it does rarely attack back after it spawns again if i'm still standing in the same place that i was when i killed it). I don't get any errors, but he just doesn't attack back

world
name = "Test"
New()
Repop_Loop()

proc
Repop_Loop()
world.Repop()
world<<"A new day has begun!"
sleep(600)
Repop_Loop()


this is my respawn code, is there anything wrong with it?
In response to Scarymonkeys623
Yes. Similar to how I suggested you fix your AI() proc: don't call a proc from itself, use a while() loop instead. Also, put the call to it behind a spawn(), so it doesn't hold up world/New().
In response to Garthor
so your saying do somthing like this?

world
name = "Test"
New()
Repop_Loop()
spawn()

proc
Repop_Loop()
world.Repop()
world<<"A new day has begun!"
sleep(600)
while()
In response to Scarymonkeys623
No. Programming isn't guesswork and putting together random bits of code; you need to actually understand how it works and act accordingly.
You need to look up spawn() and while() in the Reference so you know how to use them. You should also look up for(), since that's what should be used for infinite loops.
In response to Kaioken
Kaioken wrote:
You should also look up for(), since that's what should be used for infinite loops.

The difference is less than negligible, if there is a difference at all. I feel that while(src) or something along those lines is much easier to read than for(), and can easily be modified to something like while(alive) in case you want something like that.
In response to Garthor
Garthor wrote:
The difference is less than negligible, if there is a difference at all.

Of course the difference in execution is negligible (perhaps unless in very heavy loops which strain the server). My point is the difference in the actual operation done, not the execution speed.
When you want to have an infinite loop, you do not need any condition, therefore you do not want to check any condition. Meaning that you shouldn't do so.
Using while(1) is bad in exactly the same way that sticking if(1) arbitrarily in your code is - the compiled result is identical, too. The result is that virtually nothing changes and there is no repercussion, except that your code causes an extra, entirely unneeded operation to happen, and this is reflected in your source code.
If someone stuck if(1) arbitrarily in their code, you would tell him that's silly, wouldn't you? Although there is no difference in the program. It's just a matter of doing things properly, nothing else.

A similar situation is when a proc is needlessly recursive (using spawn() to workaround blowing up the call stack and the memory) instead of properly using a looping construct. Even though the speed lost here isn't typically noticeable, either, you and I both preach against this (which even happens to be against the norm).

Of course, when a language doesn't have any construct for a conditionless loop other than goto, then so be it, there is a lacking in the language and you need to use either while(1) or goto. But when you have the actual option, it becomes preferred than the less relevant options.

I feel that while(src) or something along those lines is much easier to read than for(), and can easily be modified to something like while(alive) in case you want something like that.

Readability is something different, and is at times subjective and adjustable. The truth is that objectively even while(1) isn't very readable* (while one? what?), but you're simply adjusted to automatically regard it as an infinite loop. You can do the same with for(), which I and others already do.
*: while(TRUE) is getting readable, though, but that's not of particular importance. Extra tidbit: as far as it and while(alive) goes, you could always name for() as loop_forever() or anything of the sort, too. Hell, you could give for() the name while(1), but that would obviously be a little misleading, other than in your own project at least.

Also, I'll note that posting with while(src) is even worse, because while you do it for readability, it leads newbies to the misconception that you actually need to check if src is still valid, which reinforces the phenomenon of newbies sticking if(src) in their code, which is generally not different than if(1).
In response to Kaioken
Kaioken wrote:
Using while(1) is bad in exactly the same way that sticking if(1) arbitrarily in your code is - the compiled result is identical, too. The result is that virtually nothing changes and there is no repercussion, except that your code causes an extra, entirely unneeded operation to happen

And for is supposed to take not only a condition, but an initial statement and an increment statement as well. The fact that you can leave them out and write only for() but cannot do so with while() is likewise a syntax issue of the language as much as you say only having goto is.

And specifically concerning the part of your post that I quoted, are you sure of what happens behind the scenes and what gets processed if you have just for()? I'm not sure, but it wouldn't surprise me if it also had an unecessary operation, albeit a no-op, in place of the initial and incrementing statements, and just executed a jump without the condition instead of the conditional part. If that's the case, it's actually more needless operations. Even if that is not the case, and for() gets optimized nicely, it still has the unconditional jump, as opposed to the conditional jump of while(1), but, depending on how the conditional jump evaluates, that very well might be a single operation to the processor too.

I will continue to use while(1). Even if you find that for() does indeed optimize to not include operations for the initial/increment at all, I still probably will not use it just because it does not seem intuitive; regardless of whether or not it can be done as you do it, "for" is for handling extra looping baggage for you and "while" is for handling loops for which you control the breaking yourself and that's just how the programming logic goes. Again, I argue that the fact that while() without any condition isn't accepted syntax is the problem.
In response to Loduwijk
Loduwijk wrote:
And for is supposed to take not only a condition, but an initial statement and an increment statement as well. The fact that you can leave them out and write only for() but cannot do so with while() is likewise a syntax issue of the language as much as you say only having goto is.

Well, rather obviously not. If it was 'an issue', it wouldn't be likely to compile, let alone work properly. And at the end of the day, it is very intended and documented that each segment of for() is separately optional.

And specifically concerning the part of your post that I quoted, are you sure of what happens behind the scenes and what gets processed if you have just for()? I'm not sure, but it wouldn't surprise me if it also had an unecessary operation

Seeing as for() is specifically designed to be potentially used with no condition at all, I'd expect it to translate just to a jump. And incidentally, it has been confirmed that it does.

"for" is for handling extra looping baggage for you and "while" is for handling loops for which you control the breaking yourself and that's just how the programming logic goes.

Huh? "for" is essentially a for-convenience (and readability) shorthand for "while" (and in DM, it's also the construct for infinite loops), and traditionally in both "for" and "while", you typically don't manually do the breaking yourself since those constructs take a condition.

Again, I argue that the fact that while() without any condition isn't accepted syntax is the problem.

Since while() and usually for() are always condition-based constructs, it'd generally make more sense to provide a different construct for conditionless loops. DM's solution works as well, though, by going ahead and making every segment of the for() statement optional, rather than only one or two.
In response to Kaioken
"for()" is ugly and is less immediately clear as to its function than "while(1)". Therefore, I do not like it. Any reasons regarding efficiency, intent, blah blah blah are entirely irrelevant, but especially so in the face of readability, which is the number one purpose of high-level languages.

If you prefer for(), go ahead and use it, but I would suggest you stop crusading for it because I think there are maybe about two other people who agree with you and a hundred times as many who simply have no clue what you're doing when you write it and do not particularly gain much from having to have it explained to them.
In response to Garthor
Garthor wrote:
If you prefer for(), go ahead and use it, but I would suggest you stop crusading for it because I think there are maybe about two other people who agree with you

Around Byond, probably, but he's certainly in good company though. Although I agree with you and not him, the head of the computer science department at my university (Doug Lea, he's a bigwig in the computer science world and does a lot of work on developing the Java language) is another person that disagrees with you and I, Garthor. He doesn't like while() for infinite loops and prefers for, though in Java it'd generally be for(;;). He says he likes to think of for in this case as standing for "forever."

It's just one of those things he'll preach for 2 minutes about if one of us does it in a software project.

Of course, since this is more of a matter of personal preferance than anything else, I agree that while(true) just makes complete sense. It's like the difference between
int add(int a, int b) {
...
}

and
int add(int a, int b)
{
...
}

I always use the latter, and the former just looks ugly and unreadable to me. I can't understand how people can think that the former looks more readable. I think it's only because they were trained to be that way, such as that's just how it was done by whoever taught the person, and so it spreads that way as a bad habit.

But whatever, to each their own. Who am I to critisize on this topic? I sometimes use keys as screwdrivers and wrenches as hammers if I don't feel like going to get the proper tool.