PDA

View Full Version : Always-Usable Impulse


klippy
01-14-2016, 07:26
This plugin is very simple and small.
Impulse commands are only executable while the player is able to shoot. More technically: only executable while gpGlobals->time is greater than m_flNextAttack. This plugin lets players execute impulse commands (like impulse 100 for flashlight) and +use during some events that it is disabled because of what's said above. These events include reloading and changing weapons.

Written because one of my Steam friends requested it. Don't really expect it to be approved, but someone might find it useful. Probably most useful for deathrun and kreedz servers with timers, as it removes the need to wait your weapon to reload to start/end the timer.

Changelog:

v1.2.0
Fixed the plugin not working on Linux servers
Added support for more games for AMXX 1.8.2 and previous versions
v1.1.0
Made plugin be more compatible with func_tank entities
v1.0.0
Initial release

icimaro1337
01-14-2016, 07:34
Thank you a lot

addons_zz
01-14-2016, 07:35
but someone might find it useful. Probably most useful for deathrun and kreedz servers with timers, as it removes the need to wait your weapon to reload to start/end the timer.
Nice sharing, thank you very much.

Don't really expect it to be approved, but someone might find it useful.
So, Code Snippets/Tutorials (https://forums.alliedmods.net/forumdisplay.php?f=83) is the best place to share, 'cuz it is a more a snippet.

klippy
01-14-2016, 07:38
So, Code Snippets/Tutorials (https://forums.alliedmods.net/forumdisplay.php?f=83) is the best place to share, 'cuz it is a more a snippet.

Not really, as it is more of a real usable plugin than a code snippet. Code snippets are usually stock functions that help other scripters deal with a problem more easily.

Arkshine
01-14-2016, 09:05
This will enable impulse while you're using a func_tank entity ; I'm not sure if it's a good idea (might creates issues, but really don't know what would be the behavior).
Minimum you can do is at least documenting this. There are probably not that much map with func_tank.
And actually, you could directly hooking ItemPostFrame I guess (this is not called when you are dead or game is over).


void CBasePlayer::ItemPostFrame(void)
{
if (m_pTank)
{
return;
}

if (m_pActiveItem)
{
if (HasShield() && IsReloading())
{
if (pev->button & IN_ATTACK2)
{
m_flNextAttack = UTIL_WeaponTimeBase();
}
}
}

#ifdef CLIENT_WEAPONS
if (m_flNextAttack > 0)
#else
if (gpGlobals->time < m_flNextAttack)
#endif
{
return;
}

ImpulseCommands();

if (m_pActiveItem)
{
m_pActiveItem->ItemPostFrame();
}
}

klippy
01-14-2016, 13:30
I just updated code, and now it avoids calling ImpulseCommands if the player is using a func_tank entity. However, I tested the previous plugin version with a func_tank entity, and in my opinion, it is better the way it is with my plugin. Without it, to quit using a func_tank, you have to walk away, but my plugin would allow players to press +use to stop using it. No issues observed.

I knew I could hook CBasePlayer::ItemPostFrame, but it is not a virtual function, so it's not possible with Hamsandwich. It's good as it is in my opinion, no need for adding Orpheu or Okapi (unless they (or similar new module) become default modules in AMXX). Just avoiding dependencies here.

Arkshine
01-14-2016, 18:42
About tank, you do what you want really, just documenting if not implemented is fine too.
About ItemPostFrame, for some reasons, I thought they were virtual; so nevermind.

ujjl
01-28-2016, 13:45
Great work! Some notes:
m_pTank = find_ent_data_info("CBasePlayer", "m_pTank"); will return the OS actual offset, using this in get_pdata_ent(this, m_pTank) will crash the server on linux or mac, as extra 20 will be added to it.
m_pTank = 1408; is for cstrike only.

klippy
01-28-2016, 15:08
Great work! Some notes:
m_pTank = find_ent_data_info("CBasePlayer", "m_pTank"); will return the OS actual offset, using this in get_pdata_ent(this, m_pTank) will crash the server on linux or mac, as extra 20 will be added to it.
m_pTank = 1408; is for cstrike only.

Oh, I didn't know it returns OS specific offset. I guess I will just subtract 20 from it if it's a Linux server. I'll fix it soon, not today though, got some work to do. Had someone tell me the plugin didn't work for them. They were probably running a Linux server, and that was the cause of it.

ujjl
01-29-2016, 05:07
public Player_PostThink_Post(this) {

if( !g_hasExecuted[this] ) {
static m_pTank; m_pTank = get_ent_data_entity(this, "CBasePlayer", "m_pTank")
set_ent_data_entity(this, "CBasePlayer", "m_pTank", 0)
ExecuteHamB( Ham_Player_ImpulseCommands, this )
set_ent_data_entity(this, "CBasePlayer", "m_pTank", m_pTank)
}
}
This will not stop controlling the tank, when use pressed.

klippy
01-29-2016, 13:17
I can't just use get_ent_data_entity() like that, because I want to support both 1.8.3 and previous versions.

Anyway, I updated the code and tested it on Windows listen server with AMXX 1.8.3 and Linux dedicated server with AMXX 1.8.2 (both CS 1.6). Worked flawlessly.

1.8.2 version is a bit more hardcoded though, but I made sure to support multiple games. It contains such data (copied from AMXX 1.8.3 gamedata files):

new const g_SupportedMods[][modinfo_t] = {
{"cstrike", 1408},
{"czero", 1408},
{"dod", 1440},
{"valve", 1148},
{"tfc", 2196},
{"gearbox", 1200}
};

so adding more games is easy.
Should that data be read from a text file or is this good enough? Some thoughts on that please.

ujjl
01-29-2016, 13:35
I can't just use get_ent_data_entity() like that, because I want to support both 1.8.3 and previous versions.
The logic is the same: skip this branch
https://github.com/ValveSoftware/halflife/blob/5d761709a31ce1e71488f2668321de05f791b405/dlls/player.cpp#L1504
by setting tank to NULL
public Player_PostThink_Post(this) {
if(!g_hasExecuted[this]) {
static oldTank; oldTank = get_pdata_ent(this, m_pTank);
set_pdata_ent(this, m_pTank, 0); //This will skip the tank re-use when controlling tank
ExecuteHamB(Ham_Player_ImpulseCommands, this);
set_pdata_ent(this, m_pTank, oldTank); //Everything back to normal
}
}
Should that data be read from a text file or is this good enough? Some thoughts on that please.
I think who needs to add new offset there, will understand where to modify the script. Who do not need new offset will just be confused with extra text file.

klippy
01-29-2016, 14:17
My intention was to make ImpulseCommands() (https://github.com/ValveSoftware/halflife/blob/5d761709a31ce1e71488f2668321de05f791b405/dlls/player.cpp#L3429) called every frame, even if the game decides it shouldn't be. I made what I wanted, and I am happy with it. In my opinion, the first version was all good anyway, but I made it take tanks into account.