weapons base cleanup, throwing knife early unequip fix

This commit is contained in:
Christopher Dawalt 2021-08-03 16:36:46 -04:00
parent 45b8c241b3
commit 7753285cfb
14 changed files with 411 additions and 475 deletions

View File

@ -12,6 +12,11 @@
// the MoTD or the buysidemenu screens.
// Do not give me child elements! Behavior for handling children removed.
// assuming these are provided elsewhere, works for now.
extern var BOOL VGUI_BuySideMenu_InitDone;
void BuySideMenu_onInputEvent(void);
class CUIEventGrabber:CUIWidget
{
//void(void) CUIEventGrabber;
@ -27,9 +32,6 @@ CUIEventGrabber::Draw(void)
}
void BuySideMenu_onInputEvent(void);
extern var BOOL VGUI_BuySideMenu_InitDone;
void
CUIEventGrabber::Input(float flEVType, float flKey, float flChar, float flDevID)
{
@ -47,6 +49,9 @@ CUIEventGrabber::Input(float flEVType, float flKey, float flChar, float flDevID)
pSeatLocal->m_inputKeyDown = flKey;
pSeatLocal->m_inputKeyTapped = flKey; //lasts only this frame
// TODO TODO TODO! Check for mouse-clicks (K_MOUSE1) and key presses by separate methods?
// Checking for keypresses on a mouse-click or for mouse-coords on a keypress on every
// single button (even a mouse, yes/no check every time) is unnecessary.
if(pSeatLocal->fVGUI_Display == BUYSIDEMENU){
BuySideMenu_onInputEvent();
}

View File

@ -19,6 +19,8 @@
// floating around. Most of the codebase is FreeHL inspired but this is an exception.
// TODO - move someplace better perhaps?
#define MAX_SPAWN_POINTS 32
extern TS_GameMode currentGameMode;
@ -42,8 +44,6 @@ extern float global_nextBreakableRespawn;
//TAGGG - move someplace better perhaps?
#define MAX_SPAWN_POINTS 32
var entity ary_spawnStart_start[MAX_SPAWN_POINTS];
var int ary_spawnStart_start_softMax = 0;
var entity ary_spawnStart_deathmatch[MAX_SPAWN_POINTS];

View File

@ -1,7 +1,7 @@
BOOL TS_Weapon_PrimaryAttackRelease(player pl, BOOL hasAmmo);
BOOL TS_Weapon_SecondaryAttackRelease(player pl, BOOL hasAmmo);
void TS_Weapon_PrimaryAttackRelease(player pl, BOOL hasAmmo);
void TS_Weapon_SecondaryAttackRelease(player pl, BOOL hasAmmo);
void TS_Weapon_Draw_extra(void);

View File

@ -1,6 +1,6 @@
BOOL
void
TS_Weapon_PrimaryAttackRelease(player pl, BOOL hasAmmo){
// WARNING! This comment is really out of date, fWeaponEventPlayer is no longer a thing
// ------------------------------
@ -9,27 +9,27 @@ TS_Weapon_PrimaryAttackRelease(player pl, BOOL hasAmmo){
// "fWeaponEventPlayer" is in "ts/client/defs.h". its assigned a lot in "ts/client/event.c".
// at least "player_localentnum" is part of the builtins.
if(pl.inventoryEquippedIndex == -1){
return FALSE;
return;
}
weapondynamic_t dynaRef = pl.ary_myWeapons[pl.inventoryEquippedIndex];
weapondata_basic_t* basicP = pl.getEquippedWeaponData();
return (*basicP).vOnPrimaryAttackRelease(pl, dynaRef, hasAmmo);
(*basicP).vOnPrimaryAttackRelease(pl, dynaRef, hasAmmo);
}
BOOL
void
TS_Weapon_SecondaryAttackRelease(player pl, BOOL hasAmmo){
if(pl.inventoryEquippedIndex == -1){
return FALSE;
return;
}
weapondynamic_t dynaRef = pl.ary_myWeapons[pl.inventoryEquippedIndex];
weapondata_basic_t* basicP = pl.getEquippedWeaponData();
return (*basicP).vOnSecondaryAttackRelease(pl, dynaRef, hasAmmo);
}// TS_Weapon_SecondaryAttackRelease
(*basicP).vOnSecondaryAttackRelease(pl, dynaRef, hasAmmo);
}
@ -370,6 +370,8 @@ void _TS_playerDropWeapon(player pl){
}
*/
// TODO. Do anything clientside here too, maybe? Unsure.
// Could call the player's DropWeapon method here, but it's hard to trust FTE with prediction
// when it comes to altering inventories it seems.
void
TS_playerDropWeapon(void){
sendevent("TS_playerDropWeapon", "");

View File

@ -234,7 +234,7 @@ Game_Input(void)
TS_Weapon_SecondaryAttackRelease(pl, TRUE);
}
#endif INPUT_TAP_DETECT_CHOICE
#endif// INPUT_TAP_DETECT_CHOICE
//pl.callWeaponThink();

View File

@ -76,34 +76,34 @@
#ifdef CLIENT
extern BOOL canBuyWeapon(int arg_weaponID, int arg_extraPrice, int arg_extraSlots, int iPurchaseCount);
extern int fullLoadCountToBuy(int arg_weaponID);
extern int determineThrowableBuyCount(int arg_weaponID, int arg_iSlotsAvailable, int arg_iMoneyAvailable);
extern int findWeaponInConfig(int arg_searchWeaponID);
extern BOOL CON_anyWeaponUsingAmmoType(int arg_ammoType, int arg_excludedWeaponID);
BOOL canBuyWeapon(int arg_weaponID, int arg_extraPrice, int arg_extraSlots, int iPurchaseCount);
int fullLoadCountToBuy(int arg_weaponID);
int determineThrowableBuyCount(int arg_weaponID, int arg_iSlotsAvailable, int arg_iMoneyAvailable);
int findWeaponInConfig(int arg_searchWeaponID);
BOOL CON_anyWeaponUsingAmmoType(int arg_ammoType, int arg_excludedWeaponID);
#endif
extern int findWeaponInInventory(player pl, int arg_searchWeaponID);
extern BOOL INV_anyWeaponUsingAmmoType(player pl, int arg_ammoType, int arg_excludedWeaponID);
int findWeaponInInventory(player pl, int arg_searchWeaponID);
BOOL INV_anyWeaponUsingAmmoType(player pl, int arg_ammoType, int arg_excludedWeaponID);
#ifdef CLIENT
extern void swapConfigElements(int arg_index1, int arg_index2);
extern void removeWeaponFromConfig(int arg_removeIndex);
extern BOOL attemptAddWeaponToConfig(int arg_weaponID, int arg_iBitsUpgrade, int iCount);
void swapConfigElements(int arg_index1, int arg_index2);
void removeWeaponFromConfig(int arg_removeIndex);
BOOL attemptAddWeaponToConfig(int arg_weaponID, int arg_iBitsUpgrade, int iCount);
#endif
extern void swapInventoryElements(player pl, int arg_index1, int arg_index2);
void swapInventoryElements(player pl, int arg_index1, int arg_index2);
extern void removeWeaponFromInventory(player pl, int arg_removeIndex);
void removeWeaponFromInventory(player pl, int arg_removeIndex);
#ifdef SERVER
extern BOOL attemptBuyWeapon(player pl, int arg_weaponID, int arg_iBitsUpgrade, int iCount);
BOOL attemptBuyWeapon(player pl, int arg_weaponID, int arg_iBitsUpgrade, int iCount);
#endif
#ifdef SERVER
extern int addWeaponToInventory(player pl, TSWorldGun arg_pickupRef);
int addWeaponToInventory(player pl, TSWorldGun arg_pickupRef);
#endif
#ifdef CLIENT
extern void deployConfig(void);
void deployConfig(void);
#endif

View File

@ -41,7 +41,8 @@ class player:base_player
//TAGGG - I'm not messing around with that memory issue from last time.
// But try again with this removed whenever it turns out ok, see if this is needed anymore.
// But try again with this removed whenever it turns out ok, see if this is needed
// anymore.
//virtual void (void)dummyBufferMethod;
@ -68,9 +69,10 @@ class player:base_player
//int ingame;
// Keep a record of the most recently seen viewmodel frame for this player for sendoffs.
// That way, if the server/client go out-of-synch in the middle of an animation, or something that should
// have started playing according to the server doesn't at clientside, clientside can receive the frame
// (really sequence, or animation choice) it should be and correct that.
// That way, if the server/client go out-of-synch in the middle of an animation, or
// something that should have started playing according to the server doesn't at
// clientside, clientside can receive the frame (really sequence, or animation choice)
// it should be and correct that.
// UNUSED FOR NOW, just an idea.
int flViewModelFrame;
@ -104,34 +106,40 @@ class player:base_player
int recentLaserDistanceDisplay;
BOOL forceViewModelUpdate;
// NOTICE - individual dynamic weapons have "forceBodygroup1Submodel". "prev_forceBodygroup1Submodel" is player-wide
// (here) instead because we only need to keep track of changes in a weapon's forceBodygroup1Submodel while that weapon
// is equipped. Not that it could ever change while not equipped anyway.
// NOTICE - individual dynamic weapons have "forceBodygroup1Submodel".
// "prev_forceBodygroup1Submodel" is player-wide (here) instead because we only need to
// keep track of changes in a weapon's forceBodygroup1Submodel while that weapon is
// equipped. Not that it could ever change while not equipped anyway.
int prev_forceBodygroup1Submodel;
// WEAPON KICKBACK STUFF.
// Way it works is a little different from the average (Half-Life and Counterstrike).
// We do have a crosshair that can grow with repeated fire to show increased inaccuracy with firing
// too often (this is not related to the offset of the camera from firing recently, but often just happens
// at the same time)
// ANYWAY. Base (HL / CS) kickback behavior for firing is to throw the player camera off seemingly by a small angle
// in any direction quickly (slightly upward-biased?, unsure), but it will return to the default position on its own
// over time, more quickly the further away it is from the intended aim angle.
// In TS, it's similar but instead lerps quickly to a new position somewhere between +- 45 degrees (maybe more?)
// from the very top. Continuous firing likely adds to the new angle to lerp to.
// So you over time get closer to looking at the very top with continuous firing without moving the mouse,
// and then further firing will just start rotating left/right a tiny bit once it's at the very top.
// We do have a crosshair that can grow with repeated fire to show increased inaccuracy
// with firing too often (this is not related to the offset of the camera from firing
// recently, but often just happens at the same time)
// ANYWAY. Base (HL / CS) kickback behavior for firing is to throw the player camera
// off seemingly by a small angle in any direction quickly (slightly upward-biased?,
// unsure), but it will return to the default position on its own over time, more quickly
// the further away it is from the intended aim angle.
// In TS, it's similar but instead lerps quickly to a new position somewhere between
// +- 45 degrees (maybe more?) from the very top. Continuous firing likely adds to the
// new angle to lerp to.
// So you over time get closer to looking at the very top with continuous firing without
// moving the mouse, and then further firing will just start rotating left/right a tiny
// bit once it's at the very top.
//
// Way this works is, it's vector(0,0,0) by default, and on firing, it gets a constant amount added, like
// (-0.1, 0.1, 0). Next frame we will move the view angle by 40% of what's left:
// (-0.04, 0.04, 0) and subtract that from the OffsetTarget, leaving it (-0.06, 0.06, 0).
// Way this works is, it's vector(0,0,0) by default, and on firing, it gets a constant
// amount added, like (-0.1, 0.1, 0). Next frame we will move the view angle by 40% of
// what's left: (-0.04, 0.04, 0) and subtract that from the OffsetTarget, leaving it
// (-0.06, 0.06, 0).
// Repeat until OffsetTarget gets so low we just 0 it out.
// Firing further only adds to OffsetTarget as it is, so we approach the 0 point in neglibly more time /
// the angle moves faster during that time to reach the increased offset.
//...also, this variable will be shared. Serverside since it must be presistent
// (not just something to step away from after it happens the first frame), and clientside
// to keep track of how to behave in case the connection is broken since.
// Firing further only adds to OffsetTarget as it is, so we approach the 0 point in
// neglibly more time / the angle moves faster during that time to reach the increased
// offset.
// ...also, this variable will be shared. Serverside since it must be presistent
// (not just something to step away from after it happens the first frame), and
// clientside to keep track of how to behave in case the connection is broken since.
//vector vViewAngleOffsetTarget;
@ -155,8 +163,8 @@ class player:base_player
// from server time.
float fAccuracyKickbackStartCooldown;
// The client can keep its own in mind as prediction between frames if needed. Server time and client time aren't
// really compatible to send b/w like this.
// The client can keep its own in mind as prediction between frames if needed. Server
// time and client time aren't really compatible to send like this.
@ -197,14 +205,22 @@ class player:base_player
// When should the viewmodel anim switch to the frozen idle anim?
float w_freeze_idle_next;
//In the weapon select menu, what is currently being highlighted & picked if fire is pressed?
//Also used as a base for finding the "previous" or "next" weapon while mouse wheeling through
//In the weapon select menu, what is currently being highlighted & picked if fire is
// pressed? Also used as a base for finding the "previous" or "next" weapon while mouse
// wheeling through
int weaponSelectHighlightID;
//This var gets a chance to turn on after the player goes through all weapons in slots 1-4 to see if any weapons have akimbo. If so, weaponSelectHighlightID goes to that weapon (the first with akimbo) and this variable turns on. Going to the next/previous weapon goes through all weapons to see the next akimbo one until there are no other choices in that direction (like last akimb weapon --> next goes back to akimbo-less slot 1's first weapon... and so on if empty). Note that slot 5 is imaginary; it is only made of weapons from slots 1-4 with akimbo choices.
//This var gets a chance to turn on after the player goes through all weapons in slots
// 1-4 to see if any weapons have akimbo. If so, weaponSelectHighlightID goes to that
// weapon (the first with akimbo) and this variable turns on. Going to the next/previous
// weapon goes through all weapons to see the next akimbo one until there are no other
// choices in that direction (like last akimb weapon --> next goes back to akimbo-less
// slot 1's first weapon... and so on if empty). Note that slot 5 is imaginary; it is
// only made of weapons from slots 1-4 with akimbo choices.
//Then, selecting a next weapon looks for the next
BOOL weaponSelectHighlightAkimbo;
//used for telling what the most recently equipped weapon's akimbo status was - no or yes.
// used for telling what the most recently equipped weapon's akimbo status was - no or
// yes.
BOOL flag_lastWeaponAkimbo;
float flViewShake;
@ -225,12 +241,11 @@ class player:base_player
BOOL inputPrimaryReleasedQueue;
BOOL inputSecondaryReleasedQueue;
// -1 means not using a scope, regardless of whether the weapon has it.
// We'll keep this serverside too, since that's the one relaying the decisions to the client.
// We'll keep this serverside too, since that's the one relaying the decisions to the
// client.
int currentZoomChoice;
// Shared, but don't network! I think?
int aryNextBurstShotTime_softLength;
float aryNextBurstShotTime[5];
@ -243,18 +258,20 @@ class player:base_player
//NOTICE - all networked now, testing.
// serverside
//What animation is the shotgun in?
// What animation is the shotgun in?
// -1 = not reloading
// 0 = doing reload1 (start)
// 1 = doing reload2 (intermediate; ammo loading)
// 2 = doing reload3 (end)
// ALSO! Call Byte vars 'floats' because FTE makes 'readbvte' give a float. I... just, don't, know.
// ALSO! Call Byte vars 'floats' because FTE makes 'readbyte' give a float.
PREDICTED_FLOAT(shotgunReloadIndex);
// Not networked! For keeping track of changes to shotgunReloadIndex outside of the client directly,
// like if the client and server are waiting for a reload anim to finish, but the server finishes first
// and gives the client the new shotgunReloadIndex. This leaves the client to skip picking the new
// shotgunReloadIndex itself and the viewmodel animation call that goes with it.
// Not networked! For keeping track of changes to shotgunReloadIndex outside of the
// client directly, like if the client and server are waiting for a reload anim to finish,
// but the server finishes first and gives the client the new shotgunReloadIndex. This
// leaves the client to skip picking the new shotgunReloadIndex itself and the viewmodel
// animation call that goes with it.
// (NOT INVOLVED YET. Is this even a good idea?)
float shotgunReloadIndexPrev;
// Same as shotgunReloadIndex, but for keeping track of the next
@ -331,8 +348,8 @@ class player:base_player
//for pmove to set
BOOL viewAboveWater;
//TODO - could this just be an entity flag just as well? Unfortunately I don't know for sure what
//flags are guaranteed open / nonconflicting with anything else.
//TODO - could this just be an entity flag just as well? Unfortunately I don't know for
// sure what flags are guaranteed open / nonconflicting with anything else.
// was BOOL
PREDICTED_FLOAT(isReloading);
@ -354,37 +371,38 @@ class player:base_player
// The fireMode controls whether this variable is relevant at all
// (another firemode makes primary / secondary fire use either akimbo weapon consistently)
PREDICTED_FLOAT(recentAkimboAttackChoice);
//What is the next way I want to try firing if only primary is supposed to be used?
//Only used for certain firemode(s).
// What is the next way I want to try firing if only primary is supposed to be used?
// Only used for certain firemode(s).
PREDICTED_FLOAT(nextAkimboAttackPreference);
//The client needs to know whether our recent attack had ammo while firing.
//In case the client needs to play a click sound clientside in response to a failed fire attempt
//TAGGG - TODO. Remove this I think? AKimbo still uses it a tiny bit though, maybe not.
// Only used by akimbo to tell something about a recently chosen attack.
// Pending a rename to make that more clear
BOOL recentAttackHadAmmo;
//What particular choice of "ary_myWeapons" is equipped?
// NOPE! Rely on the nuclide-provided activeweapon "float".
// ...not quite though, use a new var in its place instead.
// 'activeweapon' is used by Nuclide to access info about a weapon in g_weapons (list of weapons in the Nuclide weapon_t format).
// It can't be used to access inventory places in our own system, so just use another var for that completely.
// On changing the currently equipped weapon, set 'activeweapon' to the type of weapon in that inventory space to let Nuclide
// tap into weapon info as needed, best of both worlds.
// 'activeweapon' is used by Nuclide to access info about a weapon in g_weapons (list of
// weapons in the Nuclide weapon_t format). It can't be used to access inventory places
// in our own system, so just use another var for that completely. On changing the
// currently equipped weapon, set 'activeweapon' to the type of weapon in that inventory
// space to let Nuclide tap into weapon info as needed, best of both worlds.
//int activeweapon;
PREDICTED_INT(inventoryEquippedIndex);
// for akimbo weapons, the ID of the singular version for easy reference.
float activeweapon_singular;
// which one was equipped previously? For easily swapping back/forth weapons by some hotkey or console handle linked to a key, I forget.
// which one was equipped previously? For easily swapping back/forth weapons by some
// hotkey or console handle linked to a key, I forget.
// I think this is redundant with pSeat->m_iOldWeapon or something similar to that,
// try using that instead. Remove this if so.
int inventoryEquippedIndex_previous;
//This will tell us whether we intend to equip the akimbo version of hte currently equipped weapon.
//This is done since akimso variants, although selected separately in weapon select, are still
//tied to the exact same element in ary_myWeapons.
//This will tell us whether we intend to equip the akimbo version of hte currently
// equipped weapon. This is done since akimso variants, although selected separately in
// weapon select, are still tied to the exact same element in ary_myWeapons.
// was BOOL.
PREDICTED_FLOAT(weaponEquippedAkimbo);
@ -393,16 +411,18 @@ class player:base_player
weapondynamic_t ary_myWeapons[ary_myWeapons_length];
int ary_myWeapons_softMax;
//Have one space for each type of ammo available.
//If there were a large number of ammunitions and a low likelihood that all/most were going to be used
//in most loadouts, this could similarly store a list of the max number of ammunitions expected and
//keep track of which one an index (0, 1, 2, 3, etc.) refers to.
//Sounds like a lot of extra work for a single ammo counter per type of ammo which is all this is.
// Have one space for each type of ammo available.
// If there were a large number of ammunitions and a low likelihood that all/most were
// going to be used in most loadouts, this could similarly store a list of the max number
// of ammunitions expected and keep track of which one an index (0, 1, 2, 3, etc.) refers
// to. Sounds like a lot of extra work for a single ammo counter per type of ammo which
// is all this is.
int ary_ammoTotal[AMMO_ID::LAST_ID];
//Provided for quick reference. How many slots does the current loadout take?
//There is a record of how much money has been spent, similar to config, but that isn't too important.
//The attached "money" (variable) is much more important (only pay attention to it serverside, fetch it from clientside: GetStatF(...) or something.
// Provided for quick reference. How many slots does the current loadout take?
// There is a record of how much money has been spent, similar to config, but that isn't
// too important.
// The attached "money" (variable) is much more important (only pay attention to it serverside, fetch it from clientside: GetStatF(...) or something.
int iTotalSlots;
int iTotalPrice;
@ -411,8 +431,8 @@ class player:base_player
// from FreeHL, probaby good to use here too then?
//TAGGG - TODO. See if these need other lines to be supported & actually used, remove if not
// needed at all for what TS does.
//TAGGG - TODO. See if these need other lines to be supported & actually used, remove
// if not needed at all for what TS does.
#ifdef CLIENT
/* External model */
entity p_model;
@ -474,16 +494,17 @@ class player:base_player
#ifdef SERVER
// !!! SPECIAL CASE? not built-in but is what the "think" method is set to early on.
// (REMOVED: the ".think" pointer will likely be set by other stuff like so much as a reload delay,
// let's not expect this to stay as it's set)s
// (REMOVED: the ".think" pointer will likely be set by other stuff like so much as a
// reload delay, let's not expect this to stay as it's set)
//virtual void () frameThink;
//TAGGG - QUESTION. Does this need to be separate from postThink at all? Same for above, forget what these are for
//TAGGG - QUESTION. Does this need to be separate from postThink at all? Same for above,
// forget what these are for
virtual void () frameThink_fromServer;
virtual BOOL(TSWorldGun arg_pickup) attemptAddWeaponFromPickup;
virtual void(int arg_weaponID, BOOL completeDrop) dropWeapon;
virtual BOOL() anyAmmoPoolNonEmpty;
virtual void() dropAmmo;
virtual BOOL(void) anyAmmoPoolNonEmpty;
virtual void(void) dropAmmo;
#endif

View File

@ -225,7 +225,8 @@ player::ReceiveEntity(float new, float fl)
//UNNECESSARY. This array is of fixed length, so known at all times.
//WriteByte(MSG_ENTITY, ary_ammoTotal_softMax);
for(int i = 0; i < AMMO_ID::LAST_ID; i++){
// See serverside equivalent, too much info was lost from some pools being over 255 (well I guess that's all there is to it)
// See serverside equivalent, too much info was lost from some pools being over 255
// (well I guess that's all there is to it)
ary_ammoTotal[i] = readlong();
}
@ -654,7 +655,8 @@ player::SendEntity(entity ePEnt, float fChanged)
//UNNECESSARY. This array is of fixed length, so known at all times.
//WriteByte(MSG_ENTITY, ary_ammoTotal_softMax);
for(int i = 0; i < AMMO_ID::LAST_ID; i++){
// using 'WriteLong' instead of 'WriteByte', because SOME AMMO POOL just had to exceed 255, didn't it.
// using 'WriteLong' instead of 'WriteByte', because SOME AMMO POOL just had to
// exceed 255, didn't it.
WriteLong(MSG_ENTITY, ary_ammoTotal[i] );
}
@ -767,7 +769,8 @@ player::player(void){
// use TRUE for clean respawns,
// FALSE for only resetting some weapons-related vars between weapon changes, nothing too significant
// FALSE for only resetting some weapons-related vars between weapon changes, nothing too
// significant
void
player::reset(BOOL resetInventory){
@ -905,8 +908,10 @@ player::reset(BOOL resetInventory){
// TODO - FIGURE THIS OUT, for gamemodes that involve money.
// do a check. If we didn't die last time, we don't need to delete this stuff.
// is this good? See that this reliable to check at the time "reset" is called in the spawning method!
// or just send a parameter here (preserve weapons: yes/no BOOL) to determine that instead.
// is this good? See that this reliable to check at the time "reset" is called in the
// spawning method!
// or just send a parameter here (preserve weapons: yes/no BOOL) to determine that
// instead.
if(resetInventory){
@ -930,7 +935,9 @@ player::reset(BOOL resetInventory){
multicast( [0,0,0], MULTICAST_ONE );
#endif
ary_myWeapons_softMax = 0; //effectively says, no weapons. Any other info in there is to be overwritten as needed.
// effectively says, no weapons. Any other info in there is to be overwritten as
// needed.
ary_myWeapons_softMax = 0;
//All ammo counters, goodbye.
for(int i = 0; i < AMMO_ID::LAST_ID; i++){
@ -1062,7 +1069,7 @@ player::setInventoryEquippedIndex_Akimbo(int arg_newIndex, BOOL useAkimbo)
}
// NOTE, IMPORTANT.
// !!! Is this necessary?
// Is this necessary?
// Makes a decent example for paying attention to SAVE and ROLLBACKs in player script
// (see activeweapon SAVE_STATE/ROLLBACK's in Nuclide's src/shared/player.qc).
// ALSO - for this demo to work, remove the karate call in 'deployConfig',
@ -1070,12 +1077,13 @@ player::setInventoryEquippedIndex_Akimbo(int arg_newIndex, BOOL useAkimbo)
// When nothing is here instead (comment out), try throwing the last throwing knife.
// Often, you'll still hear the 'draw' noise because a rollback sets activeweapon back
// to the previous value, even though you want it to be nothing from having nothing equipped.
// But if this is enabled all the time (client and serverside), the weapon set by the server
// exclusively, such as player-spawn, does not get sent off..
// to the previous value, even though you want it to be nothing from having nothing
// equipped.
// But if this is enabled all the time (client and serverside), the weapon set by the
// server exclusively, such as player-spawn, does not get sent off..
// This seems to be the best case scenario: setting this clientside stops the rollback
// to undo setting the current equipped weapon to 'nothing' back to the throwing knife, which
// would not even be equipped anymore.
// to undo setting the current equipped weapon to 'nothing' back to the throwing knife,
// which would not even be equipped anymore.
// If this is the wrong way to go thinking about this, I need to know more.
// ALSO - see other uses of SAVE_STATE, most are for both client & server,
// especially the w_attack_next, or w_next_attack, in ts/shared/weapons.qc.
@ -1145,6 +1153,7 @@ BOOL
player::equippedWeaponDeleteCheck(void){
weapondynamic_t arg_thisWeapon = this.ary_myWeapons[this.inventoryEquippedIndex];
if(arg_thisWeapon.iCount == 0){
printfline("!!! Auto delete check, equipping a new weapon");
// remove this weapon, pick another one.
removeWeaponFromInventory(this, this.inventoryEquippedIndex);
playerEquipIdealSafe(this);
@ -1187,11 +1196,11 @@ player::callWeaponThink(void){
#ifdef SERVER
// runs every frame server-side. postthink, oddly enough, does not.
// Even cumulative 'frametime' readings do not at all add up to the real passage of time.
// Looks like we have to do this with server calling our think instead... it's own frame logic
// method does add up to something that resmebles the passage of time at least.
// The "frameThink_fromServer" further below is actually called from the server and runs every
// single logic frame of the server, as evidenced by its frametime's summing up to the passage of
// time.
// Looks like we have to do this with server calling our think instead... it's own frame
// logic method does add up to something that resmebles the passage of time at least.
// The "frameThink_fromServer" further below is actually called from the server and runs
// every single logic frame of the server, as evidenced by its frametime's summing up to the
// passage of time.
// Strangely, setting the ".think" method of the player clientside, even with nextThink set,
// does nothing at all. Even though other clientside-programmed entities like the ts_powerup
// work fine with it... I. DONT. KNOW.
@ -1218,9 +1227,10 @@ player::frameThink_fromServer(void){
#ifdef CLIENT
// Note that these pre/postThink's aren't game events, they're just called by _base/entry.c before/after
// prediction accordingly, and every single rendered frame.
// Unlike serverside preThink / postThink, which (I think?) are called independent of any logic frame-rate on the server.
// Note that these pre/postThink's aren't game events, they're just called by _base/entry.c
// before/after prediction accordingly, and every single rendered frame.
// Unlike serverside preThink / postThink, which (I think?) are called independent of any
// logic frame-rate on the server.
void
player::preThink(void){
weapondynamic_t dynaRef;
@ -1242,8 +1252,8 @@ player::preThink(void){
// TAGGG - TODO.
// maybe rename this to "viewModelAnimationDuration"
// and let "nextViewModelAnimationTime" be re-used if we ever support idle animations like HL does?
// doubt that really though.
// and let "nextViewModelAnimationTime" be re-used if we ever support idle animations
// like HL does? doubt that really though.
// When a viewmodel's w_freeze_idle_next has expired, force to the frozen idle frame.
if(w_freeze_idle_next == 0){
@ -1264,8 +1274,9 @@ player::preThink(void){
BOOL usingIronSight;
// Usually we can depend on iIronSight, but not always.
// If using switch - ironsight calls, we need to be able to tell what the intended iIronSight is,
// since it changes at the end on the server and might not've reached us (the client) in time.
// If using switch - ironsight calls, we need to be able to tell what the
// intended iIronSight is, since it changes at the end on the server and
// might not've reached us (the client) in time.
if(pSeat->m_eViewModel.frame == ironsightRef.ironsightdata.iAnim_Change_Index){
usingIronSight = TRUE; //assuming the end of this. Pick the opposite.
@ -1277,8 +1288,8 @@ player::preThink(void){
}
// idle anims don't really have any length. Let's just say "2" seconds if we ever care about
// some delay for this in the future.
// idle anims don't really have any length. Let's just say "2" seconds if
// we ever care about some delay for this in the future.
if(!usingIronSight){
// use this one (plain)
TS_Weapons_ViewAnimation(ironsightRef.iAnim_Idle_Index, 2 );

View File

@ -1,4 +1,16 @@
// GENERAL FTE NOTE!
// Don't use 'extern' on method prototypes, it makes no difference and the compiler prints
// a spammy warning "Only global functions may be defined as external (yet)" without a line
// number when it sees it.
// Or it happens anyway and I have no clue what I'm going on about.
// Maybe even externing var's does it.
// also, FTE needs a space after a preprocessor macro name for a slash to drop-down to the
// rest of the definition, like "#define thing \".
#define NULL __NULL__
@ -87,6 +99,7 @@
#if INPUT_TAP_DETECT_CHOICE == 1
///////////////////////////////////////////////////////////////////////////////////////////
// Standard way.
#define INPUT_PRIMARY_TAP_GATE \
if (pl.gflags & GF_SEMI_TOGGLED)\
@ -103,6 +116,7 @@
arg_pl.gflags |= GF_SEMI_SECONDARY_TOGGLED;
#else
///////////////////////////////////////////////////////////////////////////////////////////
// ALTERNATE WAY: check pl.inputTapFrameCount for primary/secondary.
// Lets setting an extra frame for a little more tolerance work, these are
// set to 1 on a fresh key press to work exactly like above or over 1 for
@ -127,13 +141,10 @@ if (pl.inputSecondaryTapFrameCount == 0)\
arg_pl.inputPrimaryReleasedQueue = FALSE;\
arg_pl.inputSecondaryReleasedQueue = FALSE;
///////////////////////////////////////////////////////////////////////////////////////////
#endif// INPUT_TAP_DETECT_CHOICE
// FTE needs a space after a preprocessor macro name for a slash to drop-down to the
// rest of the definition, like "#define thing \".
// OLD WAY TO DO CLICK SOUNDS
/*
// Let's make click sounds clientside-only for now

View File

@ -12,7 +12,6 @@ class player;
#define WEAPON_NONE 0
//returned by weapon_base_onPrimaryAttack_melee to tell what type of thing was hit, since some
// aspects of a hit depend on knowing this (knives & katana have different sounds for each of
// these three scenarios)
@ -27,7 +26,6 @@ enum MELEE_HIT_RESPONSE{
};
//These ID's exist separately of WEAPON_ID, are not corresponding,
//and are here only to keep track of the stats for the akimbo
//version of the weapon.
@ -46,7 +44,6 @@ enum WEAPON_AKIMBO_UPGRADE_ID{
};
//For quick reference, singular and akimbo ties:
//SOKOM_MK23 = 9, SOCOM_MK23_akimbo = 10
//Beretta = 2, Beretta_akimbo = 8
@ -68,8 +65,9 @@ enum WEAPON_ID{
MP5K = 7,
Beretta_akimbo = 8,
//TAGGG - Berettas will support the singular form and be upgradable into akimbo instead.
// ...no, keep akimbo's with their own ID's in here, spawning should know how to handle this.
// Berettas will support the singular form and be upgradable into akimbo instead.
// ...no, keep akimbo's with their own ID's in here, spawning should know how to handle
// this.
//Beretta = 8,
SOCOM_MK23 = 9,
@ -89,12 +87,12 @@ enum WEAPON_ID{
SPAS12 = 20,
AkimboColts = 21,
Glock20 = 22,
//NOTICE!!! This (below) used to be "MAC10", but we're pretty sure this ID is really for the UMP.
// There is no Mac10 in the specialists 2.1, or whatever I've been using.
//NOTICE!!! This (below) used to be "MAC10", but we're pretty sure this ID is really for
// the UMP. There is no Mac10 in the specialists 2.1, or whatever I've been using.
// This weapon likely replaced what used to be the MAC10 and its ID never got updated.
// A new ID for the Mac10 has been provided further below under "NEW WEAPONS".
// REVERSE. We'll keep this as Mac10, the new ID will go to the UMP instead. Requested preference
// to fit with the first one expected of 2.0 or slightly earlier maps.
// REVERSE. We'll keep this as Mac10, the new ID will go to the UMP instead. Requested
// preference to fit with the first one expected of 2.0 or slightly earlier maps.
MAC10 = 23,
//UMP = 23,
@ -112,22 +110,22 @@ enum WEAPON_ID{
SawedOff = 33,
Katana = 34,
SealKnife = 35,
//TAGGG - NEW WEAPONS
// NEW WEAPONS
ContenderG2 = 36,
Skorpion = 37,
Skorpion_akimbo = 38,
//could also be MAC10 ? any order for our unofficial weapon ID's is not regulated by maps
//made for the original The Specialists.
// could also be MAC10 ? any order for our unofficial weapon ID's is not regulated by maps
// made for the original The Specialists.
UMP = 39,
//SEPARATE. Contained in the same system for convenience. May not be recognized by the map.
// SEPARATE. Contained in the same system for convenience. May not be recognized by the map.
//Not pickup-able but has to be stored the same way as other weapons.
Karate = 40,
//These are items that can be purchased in the team-based game mode in original TS
//Not weapons, just here for spawn convenience. Or maybe these ID's will never be used.
// These are items that can be purchased in the team-based game mode in original TS
// Not weapons, just here for spawn convenience. Or maybe these ID's will never be used.
Kevlar = 41,
StealthShoes = 42,
@ -230,12 +228,13 @@ string getAkimboFiremodeName(int firemodeBit){
#define BITS_WEAPONOPT_AKIMBO 0x10
#define BITS_WEAPONOPT_FULLLOAD 0x20
//This is a special flag to say, skip showing buyoptions altogether. The buy button goes straight to buying the weapon.
// This is a special flag to say, skip showing buyoptions altogether. The buy button goes straight to
// buying the weapon.
//good for items (stealh shoes, kevlar)
#define BITS_WEAPONOPT_INSTANT 0x80000000
//Types of weapons that, if present, can be toggled on/off by the player. Only some can.
//A lot of other behavior about this isn't automatic though, a change here does little elsewhere.
// Types of weapons that, if present, can be toggled on/off by the player. Only some can.
// A lot of other behavior about this isn't automatic though, a change here does little elsewhere.
#define BITMASK_WEAPONOPT_TOGGLEABLE BITS_WEAPONOPT_LASERSIGHT | BITS_WEAPONOPT_FLASHLIGHT
// only min/max order of bits.
#define BITMASK_WEAPONOPT_TOGGLEABLE_MIN BITS_WEAPONOPT_LASERSIGHT
@ -263,22 +262,20 @@ string getAkimboFiremodeName(int firemodeBit){
#define ASSIGN_WEAPONDATA(arg_constName) ary_weaponData[WEAPON_ID::##arg_constName] = (weapondata_basic_t*) &weapon_##arg_constName;
//NOTICE - the ID lacks the "_akimbo" suffix. The actual variable name has the "_akimbo" suffix.
//Just provide the name of the weapon without the "_akimbo" suffix and it will be added as needed automatically.
// NOTICE - the ID lacks the "_akimbo" suffix. The actual variable name has the "_akimbo" suffix.
// Just provide the name of the weapon without the "_akimbo" suffix and it will be added as needed
// automatically.
#define ASSIGN_AKIMBOUPGRADEDATA(arg_constName) ary_akimboUpgradeData[WEAPON_AKIMBO_UPGRADE_ID::##arg_constName] = (weapondata_basic_t*) &weapon_##arg_constName##_akimbo;
///////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////
#define ary_myWeapons_length 16
/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
//NOTE - all below used to be in weapon.c TESTING
@ -311,32 +308,22 @@ typedef struct{
//weapon_##arg_varSuffix
//#define DECLARE_WEAPONDATA_NORMAL(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10)\
// arg1 + arg2 + arg3 + arg4 + arg5 + arg6 + arg7 + arg8 + arg9 + arg10;
// HANDLING AKIMBO.
/*
Since ingame treats akimbo usage as its own separate selectable
(that is, selecting the "Akimbo" BuyOption when buying a weapon adds a new selectable choie under slot #5 IN
ADDITION TO giving the ordinary solo version of the weapon given even if Akimbo wasn't bought),
it might be best to still consider
*/
// Since ingame treats akimbo usage as its own separate selectable
// (that is, selecting the "Akimbo" BuyOption when buying a weapon adds a new selectable choie under
// slot #5 IN ADDITION TO giving the ordinary solo version of the weapon given even if Akimbo wasn't
// bought), it might be best to still consider
//This stores information related to a place in the inventory to keep track of things about a weapon
//that are set at buy time or may change throughout its use such as clip size, buy options purchased,
//the delay until firing is possible again, fire mode picked, etc.
//Has a link to the weapondata_t to get information from, and its type for faster casting.
// This stores information related to a place in the inventory to keep track of things about a weapon
// that are set at buy time or may change throughout its use such as clip size, buy options purchased,
// the delay until firing is possible again, fire mode picked, etc.
// Has a link to the weapondata_t to get information from, and its type for faster casting.
//typedef struct{
//TAGGG - TODO. make this a struct instead? should be feasible.
//yes this is a class... hm. fix later.
// TODO. make this a struct instead? should be feasible.
// yes this is a class... hm. fix later.
class weapondynamic_t{
int weaponID; //what weapon is this referring to in the array of weapon data (glock, SOCOM, SMG, M4A1, etc.)
int weaponTypeID; //what type of struct does the weapon use for convenient casting in lookups (gun, ironsight, melee, throwable)?
@ -372,10 +359,10 @@ class weapondynamic_t{
int iFireMode;
int iFireModeAkimbo;
// Is the player using ironsight (right-click)? Also include checks for scoping / drawing overlays in logic
// later if needed.
// This is usually a boolean (0 or 1... off or on), but weapons with multiple magnifications can use this
// to count too, such as for 2times or 10times. 0(off), 1(2x), 2(10x).
// Is the player using ironsight (right-click)? Also include checks for scoping / drawing overlays
// in logic later if needed.
// This is usually a boolean (0 or 1... off or on), but weapons with multiple magnifications can use
// this to count too, such as for 2times or 10times. 0(off), 1(2x), 2(10x).
int iIronSight;
// Do I force the first bodygroup's submodel to a certain choice?
@ -421,11 +408,20 @@ typedef struct{
} ironsightdata_t;
//This struct only contains the bare minimum variables a class needs. Any other behavior should be handled
//by the custom methods.
//But note that weapondata_melee_t is identical for adding absolutely nothing.
//This may change of that type of weapon (really the katana, the rest are weapondata_throwable_t)
//ever need more specifics / variables.
// TODO - PENDING! Remove vOnPrimaryAttack and vOnSecondaryAttack here and from all weapons,
// Nudlie's Primary/Secondary fire calls work in place of those.
// vOnPrimaryAttackRelease and vOnSecondaryAttackRelease are still useless it turns out,
// but they can just lose the "hasAmmo" parameters at least.
// ALSO: vOnEquip, vOnUnEquip, vOnDrawHUD, and vOnReload will be removed, Nuclide calls mean these are
// no longer used.
// AND: remove BOOL return types from the remaining methods, those will never be used.
// This struct only contains the bare minimum variables a class needs. Any other behavior should be
// handled by the custom methods.
// But note that weapondata_melee_t is identical for adding absolutely nothing.
// This may change of that type of weapon (really the katana, the rest are weapondata_throwable_t)
// ever need more specifics / variables.
typedef struct{
int typeID;
string sDisplayName;
@ -435,10 +431,9 @@ typedef struct{
string sWorldModelPath; //a pickup that sits in the map; separated from any players.
string sIconFilePath; //icon for the inventory and buy menu.
//!!!!!!!!!
BOOL(player pl, weapondynamic_t arg_thisWeapon, BOOL hasAmmo) vOnPrimaryAttack; //Pressed the primary fire button. Typically fires a gun or uses melee.
BOOL(player pl, weapondynamic_t arg_thisWeapon, BOOL hasAmmo) vOnPrimaryAttack;
BOOL(player pl, weapondynamic_t arg_thisWeapon, BOOL hasAmmo) vOnPrimaryAttackRelease;
BOOL(player pl, weapondynamic_t arg_thisWeapon, BOOL hasAmmo) vOnSecondaryAttack; //Pressed the secondary fire button. Typically uses ironsight/scope if available.
BOOL(player pl, weapondynamic_t arg_thisWeapon, BOOL hasAmmo) vOnSecondaryAttack;
BOOL(player pl, weapondynamic_t arg_thisWeapon, BOOL hasAmmo) vOnSecondaryAttackRelease;
void(player pl, weapondynamic_t arg_thisWeapon) vOnEquip; //picked from inventory; now active weapon
@ -448,55 +443,59 @@ typedef struct{
//See if two think methods, for earlier or later (preframe / postframe) are needed.
void(player pl, weapondynamic_t arg_thisWeapon) vOnDrawHUD; //any special behavior for rendering 2D graphics on the player's screen while equipped?
void(player pl, weapondynamic_t arg_thisWeapon) vOnReload; //Called on starting a reload. Sounds to play after a delay?
//This event is for a gun's melee attack, if supported. Actual melee weapons still use PrimaryAttack.
//To see it in The Specialists (original beta 2), use this in console to bind cold cocking to the "c" key:
// bind "c" "+alt2"
// This event is for a gun's melee attack, if supported. Actual melee weapons still use PrimaryAttack.
// To see it in The Specialists (original beta 2), use this in console to bind cold cocking to the "c" key:
// bind "c" "+alt2"
void(player pl, weapondynamic_t arg_thisWeapon) vOnColdCock;
//We'll handle firing animations (weapon recoil mainly) in their own methods.
//Little too much going on. Number of animations to cylce through (shoot1, shoot2)?
//separate batch for firing in semi-auto mode (sshoot1, sshoot2)?
//and new ones for ironsight firing sometimes?
// We'll handle firing animations (weapon recoil mainly) in their own methods.
// Little too much going on. Number of animations to cylce through (shoot1, shoot2)?
// separate batch for firing in semi-auto mode (sshoot1, sshoot2)?
// and new ones for ironsight firing sometimes?
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
int iAnim_Idle_Index;
//no idle duration, they're all frozen. probably.
//no idle duration, they're all frozen.
int iAnim_Deploy_Index;
float fAnim_Deploy_Duration;
float fAttackDelay;
//How much damage a basic direct hit does. How this is reduced / increased with range will
//depend on the weapon's own attack method.
// How much damage a basic direct hit does. How this is reduced / increased with range
// will depend on the weapon's own attack method.
float fAttackDamage;
//Can crosshairs be custom per weapon? unsure yet.
//I think all weapon lasersights at the same behavor though. Measure distance and change the crosshair a little.
// Can crosshairs be custom per weapon? unsure yet.
// I think all weapon lasersights at the same behavor though. Measure distance and
// change the crosshair a little.
BOOL fDrawCrosshair;
int iBitsUpgrade;
int iBitsUpgradeAuto; // same choices as UpgradeOptions but this comes with the weapon on purchase.
// TODO - it might be a good idea to make the buy's upgrade options convey
// automatic upgrades.
int iBitsUpgradeAuto; // same choices as UpgradeOptions but this comes with the weapon
// on purchase.
// TODO - it might be a good idea to make the buy's upgrade
// options convey automatic upgrades.
//These may be overridden by a differnet buy config file later (TODO).
//--------------------------------------------------------------------------
int iPrice;
int iSlots; //same idea as "Weight". More slots slows the player down and counts toward a limit.
//Under what category in the buy menu will a button for buying this weapon be placed?
int iSlots; // same idea as "Weight". More slots slows the player down and counts toward
// a limit.
// Under what category in the buy menu will a button for buying this weapon be placed?
int iBuyCategory;
//--------------------------------------------------------------------------
//What slot (number: 1, 2, 3, 4, 5... column of things) do I want to go to in the player's inventory?
// What slot (number: 1, 2, 3, 4, 5... column of things) do I want to go to in the player's
// inventory?
int iInventorySlot;
weapondata_firestats_t firestats;
//If non-negative 1, which of WEAPON_AKIMBO_UPGRADE_ID (weapon.h) will I provide if Akimbo is purchased?
//NOTICE - akimbo-only weapons (golden colts) do NOT use this. Those weapondata's are already set up
//to refer to things for the akimbo version such as shop icon, price, and worldmodel.
// If non-negative 1, which of WEAPON_AKIMBO_UPGRADE_ID (weapon.h) will I provide if
// Akimbo is purchased?
// NOTICE - akimbo-only weapons (golden colts) do NOT use this. Those weapondata's are
// already set up to refer to things for the akimbo version such as shop icon, price,
// and worldmodel.
int iAkimboID;
@ -504,78 +503,47 @@ typedef struct{
//weapondata_gun_t weapon_glock18 = {};
//
typedef struct{
int typeID;
string sDisplayName;
string sViewModelPath; //1st person viewmodel
string sPlayerModelPath; //as attached to the player from a 3rd person view (or as seen by other players).
string sPlayerSilencerModelPath; //Separate player model to use if the silencer is an option. Yes. Really.
string sWorldModelPath; //a pickup that sits in the map; separated from any players.
string sIconFilePath; //icon for the inventory and buy menu.
string sViewModelPath;
string sPlayerModelPath;
string sPlayerSilencerModelPath;
string sWorldModelPath;
string sIconFilePath;
//!!!!!!!!!
BOOL(player pl, weapondynamic_t arg_thisWeapon, BOOL hasAmmo) vOnPrimaryAttack; //Pressed the primary fire button. Typically fires a gun or uses melee.
BOOL(player pl, weapondynamic_t arg_thisWeapon, BOOL hasAmmo) vOnPrimaryAttack;
BOOL(player pl, weapondynamic_t arg_thisWeapon, BOOL hasAmmo) vOnPrimaryAttackRelease;
BOOL(player pl, weapondynamic_t arg_thisWeapon, BOOL hasAmmo) vOnSecondaryAttack; //Pressed the secondary fire button. Typically uses ironsight/scope if available.
BOOL(player pl, weapondynamic_t arg_thisWeapon, BOOL hasAmmo) vOnSecondaryAttack;
BOOL(player pl, weapondynamic_t arg_thisWeapon, BOOL hasAmmo) vOnSecondaryAttackRelease;
void(player pl, weapondynamic_t arg_thisWeapon) vOnEquip; //picked from inventory; now active weapon
BOOL(player pl, weapondynamic_t arg_thisWeapon) vOnUnEquip; //selected a different weapon, use for quick cleanup/resetting. Cleanup. Holster anims themselves not supported or present.
void(player pl, weapondynamic_t arg_thisWeapon) vOnThink; //Run every frame this weapon is equipped.
//See if two think methods, for earlier or later (preframe / postframe) are needed.
void(player pl, weapondynamic_t arg_thisWeapon) vOnDrawHUD; //any special behavior for rendering 2D graphics on the player's screen while equipped?
void(player pl, weapondynamic_t arg_thisWeapon) vOnReload; //Called on starting a reload. Sounds to play after a delay?
void(player pl, weapondynamic_t arg_thisWeapon) vOnEquip;
BOOL(player pl, weapondynamic_t arg_thisWeapon) vOnUnEquip;
void(player pl, weapondynamic_t arg_thisWeapon) vOnThink;
void(player pl, weapondynamic_t arg_thisWeapon) vOnDrawHUD;
void(player pl, weapondynamic_t arg_thisWeapon) vOnReload;
void(player pl, weapondynamic_t arg_thisWeapon) vOnColdCock;
//We'll handle firing animations (weapon recoil mainly) in their own methods.
//Little too much going on. Number of animations to cylce through (shoot1, shoot2)?
//separate batch for firing in semi-auto mode (sshoot1, sshoot2)?
//and new ones for ironsight firing sometimes?
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
int iAnim_Idle_Index;
//always frozen for now but who knows if that will change.
//Any deeper behavior should be covered in custom methods instead. Unknown how many idle anims or what the chances
//of picking one over another would be if there are more than one.
int iAnim_Deploy_Index;
float fAnim_Deploy_Duration;
float fAttackDelay;
//How much damage a basic direct hit does. How this is reduced / increased with range will
//depend on the weapon's own attack method.
float fAttackDamage;
//Can crosshairs be custom per weapon? unsure yet.
//I think all weapon lasersights at the same behavor though. Measure distance and change the crosshair a little.
BOOL fDrawCrosshair;
int iBitsUpgrade;
int iBitsUpgradeAuto; // same choices as UpgradeOptions but this comes with the weapon on purchase.
// TODO - it might be a good idea to make the buy's upgrade options convey
// automatic upgrades.
int iBitsUpgradeAuto;
//These may be overridden by a differnet buy config file later (TODO).
//--------------------------------------------------------------------------
int iPrice;
int iSlots; //same idea as "Weight". More slots slows the player down and counts toward a limit.
//Under what category in the buy menu will a button for buying this weapon be placed?
int iSlots;
int iBuyCategory;
//--------------------------------------------------------------------------
//What slot (number: 1, 2, 3, 4, 5... column of things) do I want to go to in the player's inventory?
int iInventorySlot;
//yes - even melee weapons have this.
@ -607,15 +575,11 @@ typedef struct{
int flashlight_part;
int scope_part;
//!!!!!!!!!!!!!!!!!!!!
} weapondata_gun_t;
//started as a clone of weapondata_gun_t. Adds a firestats struct.
//Can hold this weapon to the side by right-clicking
//Note that if a weapon both has a scope and has a "secondary fire mode",
@ -623,71 +587,42 @@ typedef struct{
typedef struct{
int typeID;
string sDisplayName;
string sViewModelPath; //1st person viewmodel
string sPlayerModelPath; //as attached to the player from a 3rd person view (or as seen by other players).
string sPlayerSilencerModelPath; //Separate player model to use if the silencer is an option. Yes. Really.
string sWorldModelPath; //a pickup that sits in the map; separated from any players.
string sIconFilePath; //icon for the inventory and buy menu.
string sViewModelPath;
string sPlayerModelPath;
string sPlayerSilencerModelPath;
string sWorldModelPath;
string sIconFilePath;
//!!!!!!!!!
BOOL(player pl, weapondynamic_t arg_thisWeapon, BOOL hasAmmo) vOnPrimaryAttack; //Pressed the primary fire button. Typically fires a gun or uses melee.
BOOL(player pl, weapondynamic_t arg_thisWeapon, BOOL hasAmmo) vOnPrimaryAttack;
BOOL(player pl, weapondynamic_t arg_thisWeapon, BOOL hasAmmo) vOnPrimaryAttackRelease;
BOOL(player pl, weapondynamic_t arg_thisWeapon, BOOL hasAmmo) vOnSecondaryAttack; //Pressed the secondary fire button. Typically uses ironsight/scope if available.
BOOL(player pl, weapondynamic_t arg_thisWeapon, BOOL hasAmmo) vOnSecondaryAttack;
BOOL(player pl, weapondynamic_t arg_thisWeapon, BOOL hasAmmo) vOnSecondaryAttackRelease;
void(player pl, weapondynamic_t arg_thisWeapon) vOnEquip; //picked from inventory; now active weapon
BOOL(player pl, weapondynamic_t arg_thisWeapon) vOnUnEquip; //selected a different weapon, use for quick cleanup/resetting. Cleanup. Holster anims themselves not supported or present.
void(player pl, weapondynamic_t arg_thisWeapon) vOnThink; //Run every frame this weapon is equipped.
//See if two think methods, for earlier or later (preframe / postframe) are needed.
void(player pl, weapondynamic_t arg_thisWeapon) vOnDrawHUD; //any special behavior for rendering 2D graphics on the player's screen while equipped?
void(player pl, weapondynamic_t arg_thisWeapon) vOnReload; //Called on starting a reload. Sounds to play after a delay?
void(player pl, weapondynamic_t arg_thisWeapon) vOnEquip;
BOOL(player pl, weapondynamic_t arg_thisWeapon) vOnUnEquip;
void(player pl, weapondynamic_t arg_thisWeapon) vOnThink;
void(player pl, weapondynamic_t arg_thisWeapon) vOnDrawHUD;
void(player pl, weapondynamic_t arg_thisWeapon) vOnReload;
void(player pl, weapondynamic_t arg_thisWeapon) vOnColdCock;
//We'll handle firing animations (weapon recoil mainly) in our own event methods (vOnWhatever above)
//Little too much going on. Number of animations to cylce through (shoot1, shoot2)?
//separate batch for firing in semi-auto mode (sshoot1, sshoot2)?
//and new ones for ironsight firing sometimes?
//Also, burst fire's different fire delay will be handled in the event methods.
//Not cloning everything just to make a "fBurstFireDelay".
//ammodata_t* ammoRef;
//int iAmmoDataID; !!!
//int iClipMax; !!!
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
int iAnim_Idle_Index;
//no idle duration, they're all frozen. probably.
int iAnim_Deploy_Index;
float fAnim_Deploy_Duration;
float fAttackDelay;
//How much damage a basic direct hit does. How this is reduced / increased with range will
//depend on the weapon's own attack method.
float fAttackDamage;
//Can crosshairs be custom per weapon? unsure yet.
//I think all weapon lasersights at the same behavor though. Measure distance and change the crosshair a little.
BOOL fDrawCrosshair;
int iBitsUpgrade;
int iBitsUpgradeAuto; // same choices as UpgradeOptions but this comes with the weapon on purchase.
// TODO - it might be a good idea to make the buy's upgrade options convey
// automatic upgrades.
//These may be overridden by a differnet buy config file later (TODO).
int iBitsUpgradeAuto;
//--------------------------------------------------------------------------
int iPrice;
int iSlots; //same idea as "Weight". More slots slows the player down and counts toward a limit.
//Under what category in the buy menu will a button for buying this weapon be placed?
int iSlots;
int iBuyCategory;
//--------------------------------------------------------------------------
//What slot (number: 1, 2, 3, 4, 5... column of things) do I want to go to in the player's inventory?
int iInventorySlot;
//yes - even melee weapons have this.
@ -712,83 +647,63 @@ typedef struct{
int flashlight_part;
int scope_part;
//***NEW*********************************************
// NEW
ironsightdata_t ironsightdata;
} weapondata_ironsight_t;
typedef struct{
int typeID;
string sDisplayName;
string sViewModelPath; //1st person viewmodel
string sPlayerModelPath; //as attached to the player from a 3rd person view (or as seen by other players).
string sPlayerSilencerModelPath; //Separate player model to use if the silencer is an option. Yes. Really.
string sWorldModelPath; //a pickup that sits in the map; separated from any players.
string sIconFilePath; //icon for the inventory and buy menu.
string sViewModelPath;
string sPlayerModelPath;
string sPlayerSilencerModelPath;
string sWorldModelPath;
string sIconFilePath;
//!!!!!!!!!
BOOL(player pl, weapondynamic_t arg_thisWeapon, BOOL hasAmmo) vOnPrimaryAttack; //Pressed the primary fire button. Typically fires a gun or uses melee.
BOOL(player pl, weapondynamic_t arg_thisWeapon, BOOL hasAmmo) vOnPrimaryAttack;
BOOL(player pl, weapondynamic_t arg_thisWeapon, BOOL hasAmmo) vOnPrimaryAttackRelease;
BOOL(player pl, weapondynamic_t arg_thisWeapon, BOOL hasAmmo) vOnSecondaryAttack; //Pressed the secondary fire button. Typically uses ironsight/scope if available.
BOOL(player pl, weapondynamic_t arg_thisWeapon, BOOL hasAmmo) vOnSecondaryAttack;
BOOL(player pl, weapondynamic_t arg_thisWeapon, BOOL hasAmmo) vOnSecondaryAttackRelease;
void(player pl, weapondynamic_t arg_thisWeapon) vOnEquip; //picked from inventory; now active weapon
BOOL(player pl, weapondynamic_t arg_thisWeapon) vOnUnEquip; //selected a different weapon, use for quick cleanup/resetting. Cleanup. Holster anims themselves not supported or present.
void(player pl, weapondynamic_t arg_thisWeapon) vOnThink; //Run every frame this weapon is equipped.
//See if two think methods, for earlier or later (preframe / postframe) are needed.
void(player pl, weapondynamic_t arg_thisWeapon) vOnDrawHUD; //any special behavior for rendering 2D graphics on the player's screen while equipped?
void(player pl, weapondynamic_t arg_thisWeapon) vOnReload; //Called on starting a reload. Sounds to play after a delay?
void(player pl, weapondynamic_t arg_thisWeapon) vOnEquip;
BOOL(player pl, weapondynamic_t arg_thisWeapon) vOnUnEquip;
void(player pl, weapondynamic_t arg_thisWeapon) vOnThink;
void(player pl, weapondynamic_t arg_thisWeapon) vOnDrawHUD;
void(player pl, weapondynamic_t arg_thisWeapon) vOnReload;
void(player pl, weapondynamic_t arg_thisWeapon) vOnColdCock;
//We'll handle firing animations (weapon recoil mainly) in their own methods.
//Little too much going on. Number of animations to cylce through (shoot1, shoot2)?
//separate batch for firing in semi-auto mode (sshoot1, sshoot2)?
//and new ones for ironsight firing sometimes?
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
int iAnim_Idle_Index;
//no idle duration, they're all frozen. probably.
int iAnim_Deploy_Index;
float fAnim_Deploy_Duration;
float fAttackDelay;
//How much damage a basic direct hit does. How this is reduced / increased with range will
//depend on the weapon's own attack method.
float fAttackDamage;
//Can crosshairs be custom per weapon? unsure yet.
//I think all weapon lasersights at the same behavor though. Measure distance and change the crosshair a little.
BOOL fDrawCrosshair;
int iBitsUpgrade;
int iBitsUpgradeAuto; // same choices as UpgradeOptions but this comes with the weapon on purchase.
// TODO - it might be a good idea to make the buy's upgrade options convey
// automatic upgrades.
//These may be overridden by a differnet buy config file later (TODO).
int iBitsUpgradeAuto;
//--------------------------------------------------------------------------
int iPrice;
int iSlots; //same idea as "Weight". More slots slows the player down and counts toward a limit.
//Under what category in the buy menu will a button for buying this weapon be placed?
int iSlots;
int iBuyCategory;
//--------------------------------------------------------------------------
//What slot (number: 1, 2, 3, 4, 5... column of things) do I want to go to in the player's inventory?
int iInventorySlot;
//yes - even melee weapons have this.
// yes - even melee weapons have this.
weapondata_firestats_t firestats;
int iAkimboID;
//nothing else needed.
//But the katana does seem to cause some sweeping animation (slow down/stop player movement) on attacking while crouching. However that's to be integrated.
// nothing else needed.
// But the katana does seem to cause some sweeping animation (slow down/stop player movement) on
// attacking while crouching. However that's to be integrated.
} weapondata_melee_t;
@ -797,64 +712,45 @@ typedef struct{
typedef struct{
int typeID;
string sDisplayName;
string sViewModelPath; //1st person viewmodel
string sPlayerModelPath; //as attached to the player from a 3rd person view (or as seen by other players).
string sPlayerSilencerModelPath; //Separate player model to use if the silencer is an option. Yes. Really.
string sWorldModelPath; //a pickup that sits in the map; separated from any players.
string sIconFilePath; //icon for the inventory and buy menu.
string sViewModelPath;
string sPlayerModelPath;
string sPlayerSilencerModelPath;
string sWorldModelPath;
string sIconFilePath;
//!!!!!!!!!
BOOL(player pl, weapondynamic_t arg_thisWeapon, BOOL hasAmmo) vOnPrimaryAttack; //Pressed the primary fire button. Typically fires a gun or uses melee.
BOOL(player pl, weapondynamic_t arg_thisWeapon, BOOL hasAmmo) vOnPrimaryAttack;
BOOL(player pl, weapondynamic_t arg_thisWeapon, BOOL hasAmmo) vOnPrimaryAttackRelease;
BOOL(player pl, weapondynamic_t arg_thisWeapon, BOOL hasAmmo) vOnSecondaryAttack; //Pressed the secondary fire button. Typically uses ironsight/scope if available.
BOOL(player pl, weapondynamic_t arg_thisWeapon, BOOL hasAmmo) vOnSecondaryAttack;
BOOL(player pl, weapondynamic_t arg_thisWeapon, BOOL hasAmmo) vOnSecondaryAttackRelease;
void(player pl, weapondynamic_t arg_thisWeapon) vOnEquip; //picked from inventory; now active weapon
BOOL(player pl, weapondynamic_t arg_thisWeapon) vOnUnEquip; //selected a different weapon, use for quick cleanup/resetting. Cleanup. Holster anims themselves not supported or present.
void(player pl, weapondynamic_t arg_thisWeapon) vOnThink; //Run every frame this weapon is equipped.
//See if two think methods, for earlier or later (preframe / postframe) are needed.
void(player pl, weapondynamic_t arg_thisWeapon) vOnDrawHUD; //any special behavior for rendering 2D graphics on the player's screen while equipped?
void(player pl, weapondynamic_t arg_thisWeapon) vOnReload; //Called on starting a reload. Sounds to play after a delay?
void(player pl, weapondynamic_t arg_thisWeapon) vOnEquip;
BOOL(player pl, weapondynamic_t arg_thisWeapon) vOnUnEquip;
void(player pl, weapondynamic_t arg_thisWeapon) vOnThink;
void(player pl, weapondynamic_t arg_thisWeapon) vOnDrawHUD;
void(player pl, weapondynamic_t arg_thisWeapon) vOnReload;
void(player pl, weapondynamic_t arg_thisWeapon) vOnColdCock;
//We'll handle firing animations (weapon recoil mainly) in their own methods.
//Little too much going on. Number of animations to cylce through (shoot1, shoot2)?
//separate batch for firing in semi-auto mode (sshoot1, sshoot2)?
//and new ones for ironsight firing sometimes?
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
int iAnim_Idle_Index;
//no idle duration, they're all frozen. probably.
int iAnim_Deploy_Index;
float fAnim_Deploy_Duration;
float fAttackDelay;
//How much damage a basic direct hit does. How this is reduced / increased with range will
//depend on the weapon's own attack method.
float fAttackDamage;
//Can crosshairs be custom per weapon? unsure yet.
//I think all weapon lasersights at the same behavor though. Measure distance and change the crosshair a little.
BOOL fDrawCrosshair;
int iBitsUpgrade;
int iBitsUpgradeAuto; // same choices as UpgradeOptions but this comes with the weapon on purchase.
// TODO - it might be a good idea to make the buy's upgrade options convey
// automatic upgrades.
//These may be overridden by a differnet buy config file later (TODO).
int iBitsUpgradeAuto;
//--------------------------------------------------------------------------
int iPrice;
int iSlots; //same idea as "Weight". More slots slows the player down and counts toward a limit.
//Under what category in the buy menu will a button for buying this weapon be placed?
int iSlots;
int iBuyCategory;
//--------------------------------------------------------------------------
//What slot (number: 1, 2, 3, 4, 5... column of things) do I want to go to in the player's inventory?
int iInventorySlot;
//yes - even melee weapons have this.
@ -863,9 +759,9 @@ typedef struct{
int iAkimboID;
//THROWABLE INFO.
//Really just the max count of this weapon allowed for throwing (secondary fire) to work.
//The same iCount var in the dynamic player weapon info, weapondynamic_t, will work for counting
//how many the player actually has at the time & unequip itself if the last knife is thrown.
// Really just the max count of this weapon allowed for throwing (secondary fire) to work.
// The same iCount var in the dynamic player weapon info, weapondynamic_t, will work for counting
// how many the player actually has at the time & unequip itself if the last knife is thrown.
int iMaxCount;
// ALSO, how much damage do I do when thrown? Unsure what could change how much is dealt yet.
float fThrowDamage;
@ -894,101 +790,92 @@ weapondata_basic_t* ary_akimboUpgradeData[WEAPON_AKIMBO_UPGRADE_ID::LAST_ID];
extern void weapon_base_setWholeAttackDelay(player pl, float amount);
extern void weapon_base_setLeftAttackDelay(player pl, float amount);
extern void weapon_base_setRightAttackDelay(player pl, float amount);
extern void weapon_base_setLeftAttackDelay_AtLeast(player pl, float amount);
extern void weapon_base_setRightAttackDelay_AtLeast(player pl, float amount);
void weapon_base_setWholeAttackDelay(player pl, float amount);
void weapon_base_setLeftAttackDelay(player pl, float amount);
void weapon_base_setRightAttackDelay(player pl, float amount);
void weapon_base_setLeftAttackDelay_AtLeast(player pl, float amount);
void weapon_base_setRightAttackDelay_AtLeast(player pl, float amount);
extern MELEE_HIT_RESPONSE weapon_base_coldcock(player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon, float damageToDeal, float range );
MELEE_HIT_RESPONSE weapon_base_coldcock(player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon, float damageToDeal, float range );
extern void weapon_base_onEquip(player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon);
void weapon_base_onEquip(player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon);
MELEE_HIT_RESPONSE weapon_base_onPrimaryAttack_melee(player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon, float damageToDeal, float range);
MELEE_HIT_RESPONSE weapon_base_onPrimaryAttack_melee_fromCustomDirection(player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon, float damageToDeal, float range, vector customAngle );
void weapon_base_onAttack(player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon, int attackTypeUsed);
void weapon_base_onAttack_multi(player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon, int shellCount, int attackTypeUsed);
extern MELEE_HIT_RESPONSE weapon_base_onPrimaryAttack_melee(player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon, float damageToDeal, float range);
extern MELEE_HIT_RESPONSE weapon_base_onPrimaryAttack_melee_fromCustomDirection(player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon, float damageToDeal, float range, vector customAngle );
extern void weapon_base_onAttack(player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon, int attackTypeUsed);
extern void weapon_base_onAttack_multi(player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon, int shellCount, int attackTypeUsed);
extern void weapon_base_burstFire(player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon, int attackTypeUsed, int shotCount, float shotDelay);
void weapon_base_burstFire(player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon, int attackTypeUsed, int shotCount, float shotDelay);
BOOL weapon_shotgun_onInterrupt(player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon);
void weapon_shotgun_reload(player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon);
void weapon_shotgun_onThink_reloadLogic(player pl, weapondata_gun_t* basePRef, weapondynamic_t arg_thisWeapon);
BOOL weapon_akimbo_semiAttackDualHack(player pl, weapondynamic_t arg_thisWeapon, int arg_flagger, int* arg_akimboFireCallback);
BOOL weapon_akimbo_fullAttackDualHack(player pl, weapondynamic_t arg_thisWeapon, int arg_flagger, int* arg_akimboFireCallback);
BOOL weapon_akimbo_AttackDualHack(player pl, weapondynamic_t arg_thisWeapon, int arg_flagger, int* arg_akimboFireCallback);
extern BOOL weapon_akimbo_semiAttackDualHack(player pl, weapondynamic_t arg_thisWeapon, int arg_flagger, int* arg_akimboFireCallback);
extern BOOL weapon_akimbo_fullAttackDualHack(player pl, weapondynamic_t arg_thisWeapon, int arg_flagger, int* arg_akimboFireCallback);
extern BOOL weapon_akimbo_AttackDualHack(player pl, weapondynamic_t arg_thisWeapon, int arg_flagger, int* arg_akimboFireCallback);
extern int weapon_akimbo_semiAttackChoice(player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon, int attackTypeUsed);
extern int weapon_akimbo_fullAttackChoice(player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon, int attackTypeUsed);
int weapon_akimbo_semiAttackChoice(player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon, int attackTypeUsed);
int weapon_akimbo_fullAttackChoice(player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon, int attackTypeUsed);
extern BOOL weapon_ironsight_ToggleIronsight(player pl, weapondata_ironsight_t* basePRef, weapondynamic_t arg_thisWeapon);
BOOL weapon_ironsight_ToggleIronsight(player pl, weapondata_ironsight_t* basePRef, weapondynamic_t arg_thisWeapon);
void weapon_gun_Reload(player pl, weapondata_gun_t* basePRef, weapondynamic_t arg_thisWeapon );
void weapon_gun_Reload_CustomSequence(player pl, weapondata_gun_t* basePRef, weapondynamic_t arg_thisWeapon, int arg_iReloadSeq, float arg_flReloadSeqTime);
void weapon_ironsight_Reload(player pl, weapondata_ironsight_t* basePRef, weapondynamic_t arg_thisWeapon );
extern void weapon_gun_Reload(player pl, weapondata_gun_t* basePRef, weapondynamic_t arg_thisWeapon );
extern void weapon_gun_Reload_CustomSequence(player pl, weapondata_gun_t* basePRef, weapondynamic_t arg_thisWeapon, int arg_iReloadSeq, float arg_flReloadSeqTime);
extern void weapon_ironsight_Reload(player pl, weapondata_ironsight_t* basePRef, weapondynamic_t arg_thisWeapon );
extern void weapon_gun_endOfReload(player pl, weapondata_gun_t* basePRef, weapondynamic_t arg_thisWeapon );
extern void weapon_gun_endOfIronSight(player pl, weapondata_gun_t* basePRef, weapondynamic_t arg_thisWeapon);
void weapon_gun_endOfReload(player pl, weapondata_gun_t* basePRef, weapondynamic_t arg_thisWeapon );
void weapon_gun_endOfIronSight(player pl, weapondata_gun_t* basePRef, weapondynamic_t arg_thisWeapon);
extern void weapon_gun_onThink(player pl, weapondata_gun_t* basePRef, weapondynamic_t arg_thisWeapon );
void weapon_gun_onThink(player pl, weapondata_gun_t* basePRef, weapondynamic_t arg_thisWeapon );
extern void weapon_gun_fireBurstBullet(player pl, weapondata_gun_t* basePRef, weapondynamic_t arg_thisWeapon);
void weapon_gun_fireBurstBullet(player pl, weapondata_gun_t* basePRef, weapondynamic_t arg_thisWeapon);
extern void weapon_gun_onThink_burstFireLogic(player pl, weapondata_gun_t* basePRef, weapondynamic_t arg_thisWeapon );
void weapon_gun_onThink_burstFireLogic(player pl, weapondata_gun_t* basePRef, weapondynamic_t arg_thisWeapon );
extern void weapon_gun_onDrawHUD(player pl, weapondata_gun_t* basePRef, weapondynamic_t arg_thisWeapon);
extern void weapon_throwable_onDrawHUD(player pl, weapondata_throwable_t* basePRef, weapondynamic_t arg_thisWeapon);
extern void weapon_melee_onDrawHUD(player pl, weapondata_melee_t* basePRef, weapondynamic_t arg_thisWeapon);
extern void setupWeaponData(void);
//Config stuff?
//eh, can just go here.
#define ary_myWeapons_length 16
void weapon_gun_onDrawHUD(player pl, weapondata_gun_t* basePRef, weapondynamic_t arg_thisWeapon);
void weapon_throwable_onDrawHUD(player pl, weapondata_throwable_t* basePRef, weapondynamic_t arg_thisWeapon);
void weapon_melee_onDrawHUD(player pl, weapondata_melee_t* basePRef, weapondynamic_t arg_thisWeapon);
void setupWeaponData(void);
// simplified form of dynamic weapon info that only records buy upgrades purchased for a weapon.
// Note that, for akimbo-upgraded weapons, the extra akimbo version will be displayed in the inventory in addition to the singular version,
// but for removing items this still counts as a single item in the inventory. The akimbo version cannot be separately selected / removed
// to make only the singular version appear in the inventory like dropping can.
// For akimbo-only weapons, works as epxected.
// Note that, for akimbo-upgraded weapons, the extra akimbo version will be displayed in the inventory
// in addition to the singular version, but for removing items this still counts as a single item in the
// inventory. The akimbo version cannot be separately selected / removed to make only the singular
// version appear in the inventory like dropping can. For akimbo-only weapons, works as epxected.
// NOTE - the "full load" upgrade for throwables isn't really a permanent option, it's just a signal
// to buy enough throwables to raise the count to the max. If that can be affored in price/slots of course.
// to buy enough throwables to raise the count to the max. If that can be affored in price/slots of
// course.
typedef struct weaponconfig_weapon_s{
//class weaponconfig_weapon_t{
//what weapon is this referring to?
// what weapon is this referring to?
int weaponID;
//quick reference for struct type.
// quick reference for struct type.
int weaponTypeID;
//what upgrades have been purchased?
// what upgrades have been purchased?
int iBitsUpgrade;
//How many are purchased? Can be used to tell whether an akimbo weapon was upgraded (include its singular version) or akimbo-only.
//Also used by throwables to see how many have been purchased yet.
//Removing an item, regardless of its existing count, removes it entirely, does not drop the count by 1 and adjust.
// How many are purchased? Can be used to tell whether an akimbo weapon was upgraded (include its
// singular version) or akimbo-only. Also used by throwables to see how many have been purchased yet.
// Removing an item, regardless of its existing count, removes it entirely, does not drop the count
// by 1 and adjust.
int iCount;
//what is the total cost of this weapon yet including upgrades (excludes extra from buying ammo)
//Also including akimbo and extra throwables of the same type.
// what is the total cost of this weapon yet including upgrades (excludes extra from buying ammo)
// Also including akimbo and extra throwables of the same type.
int iPrice;
int iSlots;
@ -1006,29 +893,29 @@ void weaponconfig_weapon_t::weaponconfig_weapon_t(void){
//This struct stores info for a single config in the buy menu. It records weapons, their purchased upgrades,
//and ammo types purchased.
// This struct stores info for a single config in the buy menu. It records weapons, their purchased
// upgrades, and ammo types purchased.
typedef struct weaponconfig_data_s{
//class weaponconfig_data_t{
//What weapons has the user purchased?
//Note that purchasing the same weapon removes the existing and all upgrades not re-purchased.
//It may be best to subtract the one to be replaced's price before deciding that the change is
//too expensive or not.
//That is, if there are 1800 dollars available, and a 1000 glock has been purchased,
//going akimbo for that same glock is still affordable. That's 2800 available excluding the to-be-replaced glock,
//so there is enough to buy the akimbo version (2000).
//Suspiciously other upgrades like lasersight / silencer per weapon are not doubled per akimbo (verify?) but it's
//a good thing no one cares.
// What weapons has the user purchased?
// Note that purchasing the same weapon removes the existing and all upgrades not re-purchased.
// It may be best to subtract the one to be replaced's price before deciding that the change is
// too expensive or not.
// That is, if there are 1800 dollars available, and a 1000 glock has been purchased,
// going akimbo for that same glock is still affordable. That's 2800 available excluding the
// to-be-replaced glock, so there is enough to buy the akimbo version (2000).
// Suspiciously other upgrades like lasersight / silencer per weapon are not doubled per akimbo
// (verify?) but it's a good thing no one cares.
weaponconfig_weapon_t ary_myWeapons[ary_myWeapons_length];
int ary_myWeapons_softMax;
//How much ammo of each of the pools do I store?
//Picking a weapon that uses a type of ammo for the first time (such as the first 9x19mm-using weapon)
//will cost extra compared to the expected buyprice, even without upgrades, because this includes the
//cost of buying max ammunition for that ammo pool.
//Buying any more weapons using the same type of ammunition will not incur the same extra price (already
//have its ammo purchased).
// How much ammo of each of the pools do I store?
// Picking a weapon that uses a type of ammo for the first time (such as the first 9x19mm-using
// weapon) will cost extra compared to the expected buyprice, even without upgrades, because this
// includes the cost of buying max ammunition for that ammo pool.
// Buying any more weapons using the same type of ammunition will not incur the same extra price
// (already have its ammo purchased).
int ary_ammoTotal[AMMO_ID::LAST_ID];
//How many slots does the current order take? Provided for quick access.
@ -1042,18 +929,18 @@ typedef struct weaponconfig_data_s{
//};
extern void weaponconfig_data_init(weaponconfig_data_t* arg_this);
extern weapondata_basic_t* getWeaponData(int arg_weaponID, BOOL arg_akimbo);
extern weapondata_basic_t* getWeaponData_Singular(int arg_weaponID);
extern int getAmmoTypeOfWeapon(int arg_weaponID);
void weaponconfig_data_init(weaponconfig_data_t* arg_this);
weapondata_basic_t* getWeaponData(int arg_weaponID, BOOL arg_akimbo);
weapondata_basic_t* getWeaponData_Singular(int arg_weaponID);
int getAmmoTypeOfWeapon(int arg_weaponID);
#ifdef CLIENT
extern void w_ejectshell_pistol(void);
void w_ejectshell_pistol(void);
extern void copyWeaponConfig(weaponconfig_weapon_t* arg_dest, weaponconfig_weapon_t* arg_src);
extern void copyConfig(weaponconfig_data_t* arg_dest, weaponconfig_data_t* arg_src);
void copyWeaponConfig(weaponconfig_weapon_t* arg_dest, weaponconfig_weapon_t* arg_src);
void copyConfig(weaponconfig_data_t* arg_dest, weaponconfig_data_t* arg_src);
#endif

View File

@ -1403,7 +1403,6 @@ weapon_base_onEquip(
pl.recentAkimboAttackChoice = BITS_AKIMBOCHOICE_NONE;
pl.nextAkimboAttackPreference = BITS_AKIMBOCHOICE_LEFT;
pl.recentAttackHadAmmo = FALSE;
arg_thisWeapon.iIronSight = 0; //reset ironsight each time.
//TAGGG TODO - decision
@ -1442,7 +1441,6 @@ weapon_gun_fireBurstBullet(
float oldFireDelay = pl.w_attack_next;
pl.w_attack_next = 0;
pl.aryNextBurstShotTime_listenIndex++;
BOOL hasAmmo = (arg_thisWeapon.iClipLeft != 0);
#ifdef CLIENT
//printfline("What now2 %i m:%i", pl.aryNextBurstShotTime_listenIndex, pl.aryNextBurstShotTime_softLength);
@ -1977,20 +1975,18 @@ getWeaponData_Singular(int arg_weaponID)
return basicP;
}
//If this weapon does not use ammo, this returns -1.
// If this weapon does not use ammo, this returns -1.
int
getAmmoTypeOfWeapon(int arg_weaponID)
{
weapondata_basic_t* basicPointer = (weapondata_basic_t*)ary_weaponData[arg_weaponID];
weapondata_basic_t basicRef = *basicPointer;
if(basicRef.typeID == WEAPONDATA_TYPEID_GUN || basicRef.typeID == WEAPONDATA_TYPEID_IRONSIGHT){
//and the type of ammo is?
weapondata_gun_t gunRef = *((weapondata_gun_t*)basicPointer);
return gunRef.iAmmoDataID;
}else{
return -1; //does not use ammo for all we care.
return -1; // does not use ammo for all we care.
}
}// getAmmoTypeOfWeapon
@ -2049,10 +2045,8 @@ w_ejectshell_pistol(void)
void
copyWeaponConfig(weaponconfig_weapon_t* arg_dest, weaponconfig_weapon_t* arg_src)
{
arg_dest->weaponID = arg_src->weaponID;
arg_dest->weaponTypeID = arg_src->weaponTypeID;
arg_dest->iBitsUpgrade = arg_src->iBitsUpgrade;
arg_dest->iCount = arg_src->iCount;
arg_dest->iPrice = arg_src->iPrice;
@ -2067,14 +2061,11 @@ copyConfig(weaponconfig_data_t* arg_dest, weaponconfig_data_t* arg_src)
for(int i = 0; i < arg_src->ary_myWeapons_softMax; i++){
copyWeaponConfig(&arg_dest.ary_myWeapons[i], &arg_src.ary_myWeapons[i]);
}
for(int i = 0; i < AMMO_ID::LAST_ID; i++){
arg_dest->ary_ammoTotal[i] = arg_src->ary_ammoTotal[i];
}
arg_dest->iTotalSlots = arg_src->iTotalSlots;
arg_dest->iTotalPrice = arg_src->iTotalPrice;
}//copyConfig
#endif // CLIENT

View File

@ -235,16 +235,22 @@ w_combatknife_secondary(void)
#endif
}
// TODO - Beware! This method may be called many many times for a single knife throw
// especially with packet delays. So this draw may not even happen, not sure the
// best way around that yet.
printfline("IM A KNIFE I GOT THROWN YES current count: %i", arg_thisWeapon.iCount);
if(arg_thisWeapon.iCount > 0){
// another knife left? Bring it up with a draw animation.
TS_Weapons_ViewAnimation(weaponseq_combatknife::draw, (31.0f / 30.0f) );
}else{
#ifdef SERVER
// No knives left? Unequip, pick something else.
printfline("REMOVED, PRE. invcount:%i", pl.ary_myWeapons_softMax);
removeWeaponFromInventory(pl, pl.inventoryEquippedIndex);
printfline("REMOVED, POST. invcount:%i", pl.ary_myWeapons_softMax);
playerEquipIdealSafe(pl);
#endif
return FALSE;
}

View File

@ -7,8 +7,8 @@ enum weaponseq_m61grenade{
throw_slide
};
extern BOOLEAN weapon_grenade_onInputPress(player localPlayer, weapondynamic_t arg_thisWeapon, int attackTypeUsed);
//extern BOOLEAN weapon_grenade_onInputRelease(player localPlayer, weapondynamic_t arg_thisWeapon);
BOOLEAN weapon_grenade_onInputPress(player localPlayer, weapondynamic_t arg_thisWeapon, int attackTypeUsed);
//BOOLEAN weapon_grenade_onInputRelease(player localPlayer, weapondynamic_t arg_thisWeapon);
BOOLEAN weapon_M61Grenade_onPrimaryAttack(player localPlayer, weapondynamic_t arg_thisWeapon, BOOLEAN hasAmmo){

View File

@ -212,9 +212,11 @@ w_sealknife_secondary(void)
// another knife left? Bring it up with a draw animation.
TS_Weapons_ViewAnimation(weaponseq_sealknife::draw, (31.0f / 30.0f) );
}else{
#ifdef SERVER
// No knives left? Unequip, pick something else.
removeWeaponFromInventory(pl, pl.inventoryEquippedIndex);
playerEquipIdealSafe(pl);
#endif
return FALSE;
}