Vice City: Multiplayer

Server Development => Scripting and Server Management => Topic started by: Ankris on Jul 06, 2015, 10:22 PM

Title: Looping bug.
Post by: Ankris on Jul 06, 2015, 10:22 PM
I was trying to add the robbery system when I saw a issue: if there are more of 1 player, the loop bugs.

Current code is executed every 1sec (the loop starts with Foreach in "players" table)
if (players[id].mem_store["rob_countdown"] > 0) {
if (!player.Frozen) player.Frozen = true;
Announce(FormatTime(players[id].mem_store["rob_countdown"]), player, 1);
players[id].mem_store["rob_money"] += random(500);
players[id].mem_store["rob_countdown"]--;
if (players[id].mem_store["rob_countdown"] == 0) {
players[id].update_money(players[ii].mem_store["rob_money"]);
players[id].update_wanted(1);
Announce("$"+players[ii].mem_store["rob_money"], player, 1);
players[id].mem_store["rob_money"] = 0;
if (players[id].mem_store["showing_menu"] < 0 && player.Frozen) player.Frozen = false;
}
}

E.g: "00:06" and later its changed "00:04", even the message (with Announce func) it's sended to others players (+frozen, +money)
I tried everything, changing the Foreach to While and For(;;), moving the subtraction to up/down.

NOTHING!. This never bugs in LU, may be cuz it's using Squirrel v3.0.4 stable and not 3.1 beta 1.
Title: Re: Looping bug.
Post by: . on Jul 06, 2015, 10:49 PM
Any specific message? Can we see the loop? One advice I can give you is to add print() functions before each line and see where the code dies. Something like:
print("track 1");
local demo = "nasty";
print("track 2");
if (demo == "weird")
{
    print("track 2.1");
    foreach (c in demo)
    {
        print("track 2.1.1");
        if (c == 's')
        {
            print("track 2.1.1.1");
            break;
        }
        else if (c == 'y')
        {
            print("track 2.1.1.2");
            continue;
        }
        else
        {
            print("track 2.1.1.3");
            continue;
        }

        print("track 2.1.2");
        if (c < 0)
        {
            print("track 2.1.2.1");
            break;
        }
        else if (c > 200)
        {
            print("track 2.1.2.2");
            break;
        }
    }
}
else
{
    print("track 2.2");
    if (demo.len() > 4)
    {
        print("track 2.2");
        demo += ", right?";
    }
    else
    {
        print("track 2.3");
        demo += " code";
    }
}

print("track 3");

That way, you know where the code died based on what was printed last. When you pinpoint the location, print the near values that are involved in the code. So you can be sure they have the correct values. When you've found the bug, you are free to remove the print functions.

I know it's an annoying thing to do but you'll have far better chances of tracking the bug like this when the behavior is a bit unknown and the error messages are nonexistent.
Title: Re: Looping bug.
Post by: Ankris on Jul 06, 2015, 11:18 PM
I already did that trick, showing every player name+id with prints, and I don't have any "break", "return" or "continue". The weird thing is when the robbery stars for the player ID 1, 2.. when he didn't start a robbery.

This bug only appears when there are more of 2 players (as i said).

Full code of "Second" func:

function Second() {
if (server.exec_func["Second"]) return true;
server.exec_func["Second"] = true;

foreach(ii, iv in players) {
if (iv) {
local id = ii, player = players[id].instance;
if (players[id].instance.Away) players[id].idle++;
else players[id].idle = 0;

if (players[id].mem_store["rob_countdown"] > 0) {
if (!player.Frozen) player.Frozen = true;
Announce(FormatTime(players[id].mem_store["rob_countdown"]), player, 1);
players[id].mem_store["rob_money"] += random(500);
players[id].mem_store["rob_countdown"]--;
if (players[id].mem_store["rob_countdown"] == 0) {
players[id].update_money(players[ii].mem_store["rob_money"]);
players[id].update_wanted(1);
Announce("$"+players[ii].mem_store["rob_money"], player, 1);
players[id].mem_store["rob_money"] = 0;
if (players[id].mem_store["showing_menu"] < 0 && player.Frozen) player.Frozen = false;
}
}

if (players[id].busted_time > 0) {
players[id].busted_time--;
if (players[id].busted_time == 0) BustedPlayer(id);
}

if (players[id].jail_time > 0 && player.IsSpawned) {
players[id].jail_time--;
Announce("You will be released from jail in "+FormatTime(players[id].jail_time), player, 1);
if (players[id].jail_time == 0) {
mg.def("[#ffff00]"+player.Name+" was released from jail");

player.VirtualWorld = 0;
player.Pos = Vector(385.01, -507.833, 9.39902);

RestoreCamera(player);
}
}
}
}

local count = 0;
while(count < max_properties) {
if (properties[count]["unlock_buy"] > 0) properties[count]["unlock_buy"]--;
if (properties[count]["rob_unlock"] > 0) properties[count]["rob_unlock"]--;
count++;
}

server.exec_func["Second"] = false;
}
Title: Re: Looping bug.
Post by: Ankris on Jul 07, 2015, 07:34 PM
The bug stills presents, but doing a check por the pickup ID (if you picked up the pickup or not) fixed a bit the issue.

players[id].mem_store["rob_countdown"]

This is set ONLY if the players selects "Rob property" in menu, but something changes (dunno wat) it to 6 for others players, starting the countdown.