In response to Dandonfighter
Dandonfighter wrote:
    for(var/mob/M) // in what list or container? will address this next
>
>

if you are wondering, var M is a shortcut due to there are NPCs in this game. I know what I am doing with those type of things, and I humbly ask we stay on topic.

As was asked about your last post, you missed the procedure definition that contains your while loop for auto attack. Could you post this full procedure?


I think the issue is in this piece:
mob/verb/Auto_Attack()
set category="Skills"
if(!usr.AutoAttack)
usr<<"<b><font color=yellow>You start auto attacking."
usr.AutoAttack=1
return
if(usr.AutoAttack)
usr.AutoAttack=0
usr<<"<b><font color=yellow>You stop auto attacking."
return


You start and stop the AutoAttack, but doesn't look like you ever make a call to the AutoAttack that actually contains the loop, this would mean it would have to be running already prior to hitting auto-attack...so is it running, or should this call it at this point?
In response to Pirion
You start and stop the AutoAttack, but doesn't look like you ever make a call to the AutoAttack that actually contains the loop, this would mean it would have to be running already prior to hitting auto-attack...so is it running, or should this call it at this point?

eRead the top post. It clearly states that when a mob logins in, it will start auto_start()

Which makes it it when auto_attacvk is active, it will make it attack.


In response to Dandonfighter
Best response
eRead the top post. It clearly states that when a mob logins in, it will start auto_start()

Which makes it it when auto_attacvk is active, it will make it attack.

This is why I would like the full procedure. I don't know if something is missing that would be important. What I believe is going on is you're using AutoAttack as loop criteria, as soon as it evaluates to false it will stop looping, even if you set it back to true. In order to get the desired effect, you need to either call the loop again, or use an always true criteria i.e. while(1). The first would be most performant.

Method 1:
mob/var/tmp/auto_attack_looping = 0
mob/proc/auto_attack_loop()
if(auto_attack_looping) return
auto_attack_looping = !auto_attack_looping
while(AutoAttack)
//do stuff
auto_attack_looping = !auto_attack_looping

//call this when you set auto-attack on
//only effects performance when being used


Method 2:
mob/proc/auto_attack_loop()
while(1)
if(AutoAttack)
//do stuff

//doesn't need to be called except on new()/login(), but
//always affects performance

 
auto_attack_looping = !auto_attack_looping


Can you explain this part of the coding?
it is a shortcut that sets auto_attack_looping to not auto_attack_looping

ie if auto_attack_looping is true, it sets to false
if auto_attack_looping is false, it sets to true

As it is self contained (never changed anywhere else) then we always know that at the end, it will set it's prior true value to false.


Changing Auto_Attack() to the same format would look like this:
mob/verb/Auto_Attack()
set category="Skills"
usr.AutoAttack = !usr.AutoAttack
if(usr.AutoAttack)
usr<<"<b><font color=yellow>You start auto attacking."
else
usr<<"<b><font color=yellow>You stop auto attacking."
var Switch = FALSE

mob/verb/Test()
global.Switch =! Switch
world << "The Switch is [Switch ? "on" : "off"]."


Basically it can switch a variable from true to false, or false to true.
mob/var/tmp/auto_attack_looping = 0
mob/proc/auto_attack_loop()
if(auto_attack_looping) return
while(AutoAttack)
usr.MeleeAttack()

mob/verb/Auto_Attack()
set category="Skills"
usr.AutoAttack = !usr.AutoAttack
if(usr.AutoAttack)
usr<<"<b><font color=yellow>You start auto attacking."
spawn usr.auto_attack_loop()
else
usr<<"<b><font color=yellow>You stop auto attacking."


These are the changes I have made due to your explaining.

However, now when ever I used auto attack, my game freezes completely. Why?
There is a limit to how much the server can do at a time. Right now your loop says run the loop, then schedule the next run for now. The server then runs the other items it needs to run and then goes back to the loop. This will freeze the game as it is trying to do too much.

In order to prevent this, You will want some sort of delay between each auto-attack. If you add sleep(1) at the end of the while loop (which is the lowest if you don't change world.tick_delay), then you will wait 1 tick before repeating the loop. This is 1/10th second delay.

On a side note, you didn't include the auto_attack_looping = !auto_attack_looping. Without these two lines, if somehow auto_attack_loop is called again (without stopping the first), then it will have two looping, allowing the player to attack twice as much.

Also, This will also need set background = 1 in the beginning of the procedure definition, otherwise it'll be caught by the long loop detection mechanism on BYOND if it runs too many times.
Okay, so now the auto attack works. however, it will only attack once, and its done.

I need to loop (;-;)
Could you post the changed code for auto_attack_loop() please?
Actually, I managed to get it!

I happen to put the loop inside the the attack, and changed a few things, but all and all, you been huge help Pirion

Thanks a bunch!
Are you trying to create automatic turn-based combat? I would look up datums for that.

EDIT:

This is probably going to be immediately corrected by someone else, because I wrote it in 5 seconds, but this is a simple turn-based WoW style combat system.

battle
var/party1 = list()
var/party2 = list()
var/turn = 1
proc
changeturn()
switch(turn)
if(1)
turn = 2
if(2)
turn = 1
act()
switch(turn)
if(1)
for(var/mob/M in party1)
sleep(10)
M.attack()
if(2)
for(var/mob/M in party2)
sleep(10)
M.attack()
changeturn()
In response to Pirion
Oh :) I learned something new, haha. Thanks, Pirion!
In response to GamerMania
GamerMania Wrote: Are you trying to create automatic turn-based combat? I would look up datums for that.


EDIT:

This is probably going to be immediately corrected by someone else, because I wrote it in 5 seconds, but this is a simple turn-based WoW style combat system.

battle
var/party1 = list()
var/party2 = list()
var/turn = 1
proc
changeturn()
switch(turn)
if(1)
turn = 2
if(2)
turn = 1
act()
switch(turn)
if(1)
for(var/mob/M in party1)
sleep(10)
M.attack()
if(2)
for(var/mob/M in party2)
sleep(10)
M.attack()
changeturn()
>>


Wow, actually that's pretty good coding.

I understood all of that. Seems legit.
Page: 1 2