Raised This Month: $12 Target: $400
 3% 

[TUT/Snippet] Doing timed stuff without CreateTimers


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Chdata
Veteran Member
Join Date: Aug 2012
Location: Computer Chair, Illinois
Old 02-04-2015 , 23:57   [TUT/Snippet] Doing timed stuff without CreateTimers
Reply With Quote #1

hi i like frog

I feel like something similar may have been posted before or something, but here's a thing I set up for myself.

As opposed to using CreateTimer() to run code in the future, there are various scenarios where you could just use a single float to do things such as, preventing code from executing until a certain amount of time has passed.

For example, all of the "m_flNext..." variables Source uses work this way. TF2 has m_flNextPrimaryAttack. This is set to a time in seconds, which is compared to the GameTime, which can be retrieved in SM via GetGameTime().

m_flNextPrimaryAttack prevents a player from attacking with +attack until the GameTime has reached or passed whatever time is stored in m_flNextPrimaryAttack.

If m_flNextPrimaryAttack is 60.0, the GameTime must reach 60 seconds before the player can attack. If at this 60 second mark you then set m_fl to 95.0, the player has to wait another 35 seconds before attacking again.

One might use that netprop by setting its value to GetGameTime()+flTime.

It's a fairly simple comparison, and it has a lot of applications. So I made a simple enum to easily track these.

For our version, we'll use GetEngineTime(). GetGameTime() resets to 0.0 when the map changes, whereas the Engine Time will keep increasing forever from the point the server started up. (Seriously, the previous sentence isn't documented anywhere where you'll find it soon).

Stocks:
Spoiler


And here's an example of where I use it.
Note: This code is actually from Advanced Weaponiser which I imported to another plugin.
Spoiler

Another example:
Spoiler

And lastly:
Spoiler

All you need to do to add a new / separate "timer" is add another entry into one of the enums above. Simple.

The m_flNext naming convention doesn't matter and isn't meant to be meaningful.
I just did that cause there's no other place I'm going to name variables like that and it gives a similar feel to the netprops in Source.

You can also use this in things like OnGameFrame() or OnThink to have times faster than 100 milliseconds (0.1 seconds), depending on what you want to do. Of course then it's still restricted to however fast OnGameFrame/OnThinkHooks fire.
__________________

Last edited by Chdata; 04-16-2016 at 13:34.
Chdata is offline
Powerlord
AlliedModders Donor
Join Date: Jun 2008
Location: Seduce Me!
Old 02-10-2015 , 11:06   Re: [TUT/Snippet] Doing timed stuff without CreateTimers
Reply With Quote #2

Quote:
Originally Posted by Chdata View Post
As opposed to using CreateTimer() to run code in the future, there are various scenarios where you could just use a single float to do things such as, preventing code from executing until a certain amount of time has passed.

For example, all of the "m_flNext..." variables Source uses work this way. TF2 has m_flNextPrimaryAttack. This is set to a time in seconds, which is compared to the GameTime, which can be retrieved in SM via GetGameTime().
This seems like a lot of work for what is essentially OnGameFrame on the game server side.
__________________
Not currently working on SourceMod plugin development.
Powerlord is offline
KyleS
SourceMod Plugin Approver
Join Date: Jul 2009
Location: Segmentation Fault.
Old 02-10-2015 , 23:42   Re: [TUT/Snippet] Doing timed stuff without CreateTimers
Reply With Quote #3

If you need GameFrame synchronization, use RequestFrame.
KyleS is offline
Chdata
Veteran Member
Join Date: Aug 2012
Location: Computer Chair, Illinois
Old 02-11-2015 , 09:12   Re: [TUT/Snippet] Doing timed stuff without CreateTimers
Reply With Quote #4

I do.

As for what Powerlord said... wot? I don't know how you're getting OnGameFrame out of that. You only need to set the next attack once, rather than multiple frames, depending on what you're doing.

For example, VSH sets your next attack to 2 seconds after you get a backstab, instead of the normal 0.6s fire rate of the knife.

And when you climb walls as a sniper it does more or less the same thing... but the plugin doesn't use OnGameFrame at all. (It does use a think hook for something else now though).

PHP Code:
stock SetNextAttack(iWeaponFloat:flSecs 0.0) {
    if (
iWeapon <= MaxClients || !IsValidEntity(iWeapon))  return;
    new 
Float:flNext GetGameTime() + flSecs;
    
SetEntPropFloat(iWeaponProp_Send"m_flNextPrimaryAttack"flNext);
    
SetEntPropFloat(iWeaponProp_Send"m_flNextSecondaryAttack"flNext);

Simple 5 line function.

If you want to delay every attack you'd just use TF2Items/TF2Attributes and use the fire rate penalty attribute.
__________________

Last edited by Chdata; 02-11-2015 at 09:14.
Chdata is offline
Powerlord
AlliedModders Donor
Join Date: Jun 2008
Location: Seduce Me!
Old 02-11-2015 , 17:07   Re: [TUT/Snippet] Doing timed stuff without CreateTimers
Reply With Quote #5

Quote:
Originally Posted by Chdata View Post
I do.

As for what Powerlord said... wot? I don't know how you're getting OnGameFrame out of that. You only need to set the next attack once, rather than multiple frames, depending on what you're doing.

For example, VSH sets your next attack to 2 seconds after you get a backstab, instead of the normal 0.6s fire rate of the knife.

And when you climb walls as a sniper it does more or less the same thing... but the plugin doesn't use OnGameFrame at all. (It does use a think hook for something else now though).

PHP Code:
stock SetNextAttack(iWeaponFloat:flSecs 0.0) {
    if (
iWeapon <= MaxClients || !IsValidEntity(iWeapon))  return;
    new 
Float:flNext GetGameTime() + flSecs;
    
SetEntPropFloat(iWeaponProp_Send"m_flNextPrimaryAttack"flNext);
    
SetEntPropFloat(iWeaponProp_Send"m_flNextSecondaryAttack"flNext);

Simple 5 line function.

If you want to delay every attack you'd just use TF2Items/TF2Attributes and use the fire rate penalty attribute.
I'm getting OnGameFrame out of that because Think hooks are called from eiface.h's GameFrame.
__________________
Not currently working on SourceMod plugin development.
Powerlord is offline
lingzhidiyu
Senior Member
Join Date: Mar 2014
Old 02-11-2015 , 21:04   Re: [TUT/Snippet] Doing timed stuff without CreateTimers
Reply With Quote #6

I want know how much performance cost in this code.

PHP Code:
PreThink(client)
{
    if (!
AllowThis1[client])
    {
        return;
    }
    if (!
AllowThis2[client])
    {
        return;
    }
        
//and more bool...........

lingzhidiyu is offline
Chdata
Veteran Member
Join Date: Aug 2012
Location: Computer Chair, Illinois
Old 02-11-2015 , 21:46   Re: [TUT/Snippet] Doing timed stuff without CreateTimers
Reply With Quote #7

Quote:
Originally Posted by lingzhidiyu View Post
I want know how much performance cost in this code.

PHP Code:
PreThink(client)
{
    if (!
AllowThis1[client])
    {
        return;
    }
    if (!
AllowThis2[client])
    {
        return;
    }
        
//and more bool...........

https://forums.alliedmods.net/showpo...09&postcount=3

Comparatively a couple of bools shouldn't be bad. Unless you have like hundreds of bools. I try to use switch cases... according to Psychonic or Asherkin they don't calculate every comparison for every switch or something, just jump to whichever case.
__________________

Last edited by Chdata; 02-11-2015 at 21:49.
Chdata is offline
Powerlord
AlliedModders Donor
Join Date: Jun 2008
Location: Seduce Me!
Old 02-12-2015 , 16:08   Re: [TUT/Snippet] Doing timed stuff without CreateTimers
Reply With Quote #8

Quote:
Originally Posted by Chdata View Post
https://forums.alliedmods.net/showpo...09&postcount=3

Comparatively a couple of bools shouldn't be bad. Unless you have like hundreds of bools. I try to use switch cases... according to Psychonic or Asherkin they don't calculate every comparison for every switch or something, just jump to whichever case.
It's pretty common for a compiler to generate a jump table for a switch instead of treating it like an if / else if / else block.
__________________
Not currently working on SourceMod plugin development.
Powerlord is offline
Chdata
Veteran Member
Join Date: Aug 2012
Location: Computer Chair, Illinois
Old 02-12-2015 , 17:54   Re: [TUT/Snippet] Doing timed stuff without CreateTimers
Reply With Quote #9

I love pointer tables

Code:
LDA !RamAdress   ;switch (!RamAdress)
PHX
ASL A
TAX
REP #$20
LDA Pointers,x
STA $0A
SEP #$20
PLX
JMP ($000A)

Pointers:
dw Action0
dw Action1
dw Action2
dw Action3
dw Action4
dw Action5

Action0:  ;case 0
RTS
Action1:  ;case 1
RTS
Action2:
RTS
Action3:
RTS
Action4:
RTS
Action5:
RTS
__________________

Last edited by Chdata; 02-12-2015 at 17:59.
Chdata is offline
asherkin
SourceMod Developer
Join Date: Aug 2009
Location: OnGameFrame()
Old 02-13-2015 , 08:00   Re: [TUT/Snippet] Doing timed stuff without CreateTimers
Reply With Quote #10

All this is doing is re-implementing CreateTimer in SourcePawn rather than C++.
__________________
asherkin is offline
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 12:22.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode