vehicle respawn problem

Started by Spice, Jul 26, 2015, 02:52 PM

Previous topic - Next topic

Spice

i am facing a problem that if player exit vehicle car does not respawn it remains there...
i am only able to do that if player exit it respawn after a specific time...by using timer
but main problem is that if player again sit back in car it will respawn but it shouldn't....
i think it will be done by Timer.start and Timer.stop but i didnt find any example of syntax of timer.start and stop
if i am right then can u explain me timer's syntax itx function and its use...?

if i am not then please tell me the right way......THANKX

MacTavish

#1
Its

Yourtimer <- NewTimer("yourfunction",5000,0);

Yourtimer.Pause = true/false
Yourtimer.Start();
Yourtimer.Stop();
Yourtimer.Delete();


Actually i created that system few months ago for my GHP script for some reason i cant host that but i can share the features

function onPlayerExitVehicle( player, vehicle )
{
NewTimer("respawn",25000,1,vehicle.ID);
}

function respawn(veh)
{
local vehicle = FindVehicle(veh), maxplayers = GetMaxPlayers();
for(local i=0; i <maxplayers; ++i)
{
local player = FindPlayer(i);
if ( player && player.Vehicle)
{
if ( player.Vehicle.ID == veh ) return 0;
 }
else if (!vehicle) return 0;
else vehicle.Respawn();
}
}


It may cause lag but i will request to @Thijn @S.L.C @Doom_Killer to take a look and if there is any problem then please tell me

Grand Hunting Project
Join #SLC, #KAKAN, #Doom, #GHP @LUnet

Retired VC:MP Player/Scripter :P

Spice

thankx for this but i also got a solution it was soo simple......just

vehicle.RespawnTimer = 60000;
it will respawn car after every 60 seconds but if player is in it. it will not respawn....thats it...Thank you

.

#3
@Betzone The only suggestion that I have for you and anyone else is to stop using function calls inside loops.

Before:
for(local i=0; i <GetMaxPlayers(); i++)
After:
local max = GetMaxPlayers();
for(local i=0; i < max; i++)

See what I did there? I cached that result to save a function call on each iteration. That value won't change unless you explicitly do so inside the loop.

Also use pre-increment instead of post-decrement to avoid a variable copy on each iteration. Variables in squirrel are not as lightweight as those in C/C++. Therefore you should avoid copies as much as possible.

Before:
local max = GetMaxPlayers();
for(local i=0; i < max; i++)

After:

local max = GetMaxPlayers();
for(local i=0; i < max; ++i)

You have the same result in both cases.
.

MacTavish

#4
Thanks @S.L.C i will keep it in my mind :)

I updated the code, is that fine now?

Grand Hunting Project
Join #SLC, #KAKAN, #Doom, #GHP @LUnet

Retired VC:MP Player/Scripter :P

DizzasTeR

Its totally fine, but its better to use vehicle.RespawnTimer.

Thijn

Quote from: S.L.C on Jul 26, 2015, 04:53 PMAlso use pre-increment instead of post-decrement to avoid a variable copy on each iteration. Variables in squirrel are not as lightweight as those in C/C++. Therefore you should avoid copies as much as possible.

Before:
local max = GetMaxPlayers();
for(local i=0; i < max; i++)

After:

local max = GetMaxPlayers();
for(local i=0; i < max; ++i)

You have the same result in both cases.
I find this very interesting, and was not known to me. Can you explain why it would work that way? Isn't ++i only returning i+1, but not setting it?

.

#7
Post and Pre increment operators in Squirrel work the same as those in C++. Except in Squirrel and almost every other scripting language out there, making variable copies is not as cheap as in C++ and you don't have an extensive optimizer(s) like C++ does.

Anyway, let's start with the post increment operator. What this means, is: Give me your current value and then add one to that. In order to do that, you need to make a copy of the current value, which means a new variable. Then add one to the original value and return the copy which still has the original value before incrementing.

Squirrel doesn't have variable references. Therefore I will use C++ and the symbol '&' to denote a reference. Let's hope it's easy to understand.
#include <cstdio>

int PostInc(int & var)
{
    int cpy = var;
    var += 1;
    return cpy;
}

int main(int argc, char **argv)
{
    int test = 4;

    printf("%d %d", PostInc(test), test);

    return 0;
}

As you can see I have to make a copy of 'var' in order to return the value before the increment happened. That's why the name Post Increment. Increment the value after you give me it's current value.

And then we reach the second one, pre increment. As the name suggests. Increments the value first and then return me the incremented value. Which means you don't have to backup the value before incrementing it.

#include <cstdio>

int & PostInc(int & var)
{
    var += 1;
    return var;
}

int main(int argc, char **argv)
{
    int test = 4;

    printf("%d %d", PostInc(test), test);

    return 0;
}

As you can see, this time I'm also returning a reference. Anyway, these things are quite cheap in C++ especially with the fundamental types. But they might not be the same in scripting languages especially the dynamically typed ones.

Now you might think: But why do I need the post increment/decrement if the pre increment/decrement is faster and does the same thing. Well, sometimes you need to get the current value and then increment it and do it so in a single expression.

Let's see how the order of these affect the code if anyone decides he doesn't want to pay attention:
local a = 5, b = 5;
print("Post decrement");
while (a--)
{
print(a);
}
print("Pre decrement");
while (--b)
{
print(b);
}

Output:
[SCRIPT]  Post decrement
[SCRIPT]  4
[SCRIPT]  3
[SCRIPT]  2
[SCRIPT]  1
[SCRIPT]  0
[SCRIPT]  Pre decrement
[SCRIPT]  4
[SCRIPT]  3
[SCRIPT]  2
[SCRIPT]  1

Notice something funny there?

tl;dr
[spoiler]
They were both supposed to stop at 0.Except the pre decrement got the value after the decrement happened and since that value was 0, it ended the loop. Which means in never got to enter the loop body and print 0. The post decrement on the other hand, it was able to print 0, because it got the value before decrementing it. And since the old value was returned in the while condition, which was 1, and then it decremented the value which reached 0 but was too late because the value 1 was already tested and it got into the loop body. And on next round when it tested the old value again, now it was 0 and the new value is actually some negative value but because the old value is 0 it never gets to the loop body.

Anyway, weird explanation. But if you play with it, and try to make sense out of it, then it will start to be clear how it goes and why they're both needed depending on the situation.
[/spoiler]

But now we reach the for loops and due to it's flow, these two make no difference.

As you can see the update part is reached at the end of each loop and either if you do post or pre increment/decrement you still have the same value by the time you reach the condition of the loop.

Example:
print("Post decrement");
for (local i = 5; i; i--)
{
print(i);
}
print("Pre decrement");
for (local i = 5; i; --i)
{
print(i);
}

Output:
[SCRIPT]  Post decrement
[SCRIPT]  5
[SCRIPT]  4
[SCRIPT]  3
[SCRIPT]  2
[SCRIPT]  1
[SCRIPT]  Pre decrement
[SCRIPT]  5
[SCRIPT]  4
[SCRIPT]  3
[SCRIPT]  2
[SCRIPT]  1

As you can see now, the effect is the same on both types of increment/decrement. The for loop is immune to the difference between these operators, as long as they're used in the update section.

But using the pre-increment could give you an advantage over many for loop statements by avoiding some copies. Anyway, I hope it explains the difference well enough and there's quite a lot of material on the internet for these two if anyone wishes to learn even more (about the minor details in some speciffic cases).
.

maxorator

#8
Quote from: S.L.C on Jul 26, 2015, 07:45 PMBut using the pre-increment could give you and advantage over many for loop statements by avoiding some copies. Anyway, I hope it explains the difference well enough and there's quite a lot of material on the internet for these two if anyone wishes to learn even more (about the minor details in some speciffic cases).
Going into details, here are the extra instructions that are executed when using post-increment:
.text$mn:00004C30                 movzx   eax, byte ptr [esi+5]
.text$mn:00004C34                 add     eax, [ebx+28h]
.text$mn:00004C37                 mov     ecx, [ebx+18h]
.text$mn:00004C3A                 mov     [ebp+arg_0], eax
.text$mn:00004C3D                 mov     edi, eax
.text$mn:00004C3F                 mov     [ebp+var_10], ecx
.text$mn:00004C42                 mov     esi, [ecx+eax*8]
.text$mn:00004C45                 mov     ecx, [ecx+eax*8+4]
.text$mn:00004C49                 mov     eax, [edx+4]
.text$mn:00004C4C                 mov     [ebp+var_14], esi
.text$mn:00004C4F                 mov     esi, [ebp+var_10]
.text$mn:00004C52                 mov     [esi+edi*8+4], eax
.text$mn:00004C56                 mov     eax, [edx]
.text$mn:00004C58                 mov     [esi+edi*8], eax
.text$mn:00004C5B                 lea     edi, [ebx+90h]
.text$mn:00004C61                 mov     esi, [ebp+var_18]
.text$mn:00004C64                 test    eax, 8000000h
.text$mn:00004C69                 jz      short loc_4C7E
<omitted because jump is always taken>
.text$mn:00004C7E
.text$mn:00004C7E loc_4C7E:                               ; CODE XREF: SQVM::Execute(SQObjectPtr &,int,int,SQObjectPtr &,uint,SQVM::ExecutionType)+1841j
.text$mn:00004C7E                 test    [ebp+var_14], 8000000h
.text$mn:00004C85                 jz      short loc_4C94
<omitted because jump is always taken>

Post-increment code pretty much just adds that part of code in the middle, when removing that it's identical to pre-increment, which is entirely handled by this set of instructions:
.text$mn:0000353C                 mov     ecx, [ebx+84h]  ; jumptable 00003558 default case
.text$mn:00003542                 mov     esi, [ecx]
.text$mn:00003544                 mov     [ebp+var_18], esi
.text$mn:00003547                 lea     eax, [esi+8]
.text$mn:0000354A                 mov     [ecx], eax
.text$mn:0000354C                 movzx   eax, byte ptr [esi+4]
.text$mn:00003550                 cmp     eax, 3Ch ; '<'  ; switch 61 cases
.text$mn:00003553                 ja      short $exception_restore$1043 ; jumptable 00003558 default case
.text$mn:00003555                 lea     ecx, [ecx+0]
.text$mn:00003558
.text$mn:00003558 loc_3558:                               ; CODE XREF: SQVM::Execute(SQObjectPtr &,int,int,SQObjectPtr &,uint,SQVM::ExecutionType)+1B8j
.text$mn:00003558                 jmp     ds:$LN1041[eax*4] ; switch jump
<jumps here>
.text$mn:00004C16                 mov     eax, [esi]      ; jumptable 00003558 case 39
.text$mn:00004C18                 mov     ecx, [ebx+28h]
.text$mn:00004C1B                 add     eax, ecx
.text$mn:00004C1D                 mov     edx, [ebx+18h]
.text$mn:00004C20                 cmp     dword ptr [edx+eax*8], 5000002h
.text$mn:00004C27                 lea     edx, [edx+eax*8]
.text$mn:00004C2A                 mov     [ebp+var_30], edx
.text$mn:00004C2D                 jnz     short loc_4CA1
<previously posted code goes in here>
.text$mn:00004C95                 movsx   eax, byte ptr [esi+7]
.text$mn:00004C99                 add     [edx+4], eax

Note that both are exactly 20 instructions (clock cycles spent on instructions vary though), which means post-increment approximately doubles the execution time compared to pre-increment.

.

Well, doing a small test to see how big the difference really is. I'd say it's not much at first look.

Post:
local t = clock();
local x = 0;
for (local i = 0; i < 10000000; i++)
{
x += 1;
}
print(clock() - t);

Pre:
local t = clock();
local x = 0;
for (local i = 0; i < 10000000; ++i)
{
x += 1;
}
print(clock() - t);

But if you add up many of these micro-optimizations (because I can't call them otherwise) over a long period of time you might start to get an idea.
.

maxorator

Well, I added the rest of the opcodes that are run for both pre and post increment to my previous post too, which showed it approximately doubles the execution time. The loop itself adds pretty much overhead though. The best way to benchmark this is to literally have a file with 10000 lines of i++;.

.

#11
Quote from: maxorator on Jul 26, 2015, 08:49 PMThe best way to benchmark this is to literally have a file with 10000 lines of i++;.

You might hit a stack overflow with that or something else ;D but it's tempting as f*. Lemme come back with one.

EDIT:

Nope, you just can't bottle neck this easily. I was able to have about 200,000 post increment statements and unable to get anything even close to a value shows a measurable amount of time difference. All I was able to get I think is mostly the start up and file loading time. Beyond that, the script had gotten ridiculously big to even resemble a real wold situation and I simply stopped trying ;D
.

Stormeus

#12
Just don't micro-optimize your code. The difference between i++ and ++i in Squirrel is miniscule to non-existent. Just make your code perform well in the aggregate and make it readable and you'll be fine.

Spice

I dont think so that post increament and pre-increament both work as same lets take a simple example....
a program that will split a number and gives itx sum...like id 4567 it should give 22.
similarly for 15 it should give 6 no here is code in java....


import java.util.*;
public class numbers
{
public static void main(String[]args)
{
Scanner input = new Scanner(System.in);
System.out.println("Enter a number");
int x = input.nextInt();
int sum=0;
for(int i=0;i<=70;i++)
{
int a = x%10;
int b = x/10;

//sum=+ a;       //case:1 
sum+=a;         //case: 2   
x=b;
}
System.out.println(sum);
}
}


well in case 1 it will give u answer 0
and in 2nd case it will give u right answer

in case 1 first it will add value of a in sum then gives value sum 0 as initialized up....
but in case 2 first it will do sum=sum(which is zero) then add a...
if loop runs u can see thhat in first case it will gives value only 0...
but in 2nd case value will be increase.......and gives answer

so we cannot say that  they both work same......ThankX

DizzasTeR

You have changed your direction from the topic, I don't recall comparing ++i with i+= since I consider those 2 something different.

- ++i will add 1 to the current value of 'i' and forward it, whereas the i += is used to add something more than 1 at the same time something like i += 10 which will add 10 directly, this can be used for gaped loops when you want to loop through order, lets say even numbers so i += 2 on each loop call, But still this is not about the += its about ++.