970 lines
33 KiB
C++
970 lines
33 KiB
C++
|
|
|
|
|
|
// Doing at least this because nuclide's src/server/weapons.qc
|
|
// still expects it to exist.
|
|
// Used with the Nuclide-provided player.activeweapon, not to be confused
|
|
// with player.inventoryEquippedIndex for the currently selected aryWeapon
|
|
// inventory element.
|
|
#define WEAPON_NONE 0
|
|
|
|
// Any preference for macro constants or 'enumflags', whatever does the auto-power-of-2?
|
|
// No idea, doing macros for now
|
|
|
|
|
|
#define BITS_AKIMBOCHOICE_NONE 0
|
|
#define BITS_AKIMBOCHOICE_LEFT 1
|
|
#define BITS_AKIMBOCHOICE_RIGHT 2
|
|
#define BITS_AKIMBOCHOICE_BOTH (BITS_AKIMBOCHOICE_LEFT | BITS_AKIMBOCHOICE_RIGHT)
|
|
|
|
|
|
|
|
// Firemodes, normal
|
|
// melee weapons don't really do firemode.
|
|
// Can be used for burst-fire bullets too for bypassing some requirements.
|
|
#define BITS_FIREMODE_NONE 0
|
|
#define BITS_FIREMODE_BURST 1
|
|
#define BITS_FIREMODE_FULL 2
|
|
#define BITS_FIREMODE_SEMI 4
|
|
#define BITS_FIREMODE_PUMP 8
|
|
|
|
|
|
// Akimbo firemodes
|
|
#define BITS_FIREMODE_AKIMBO_NONE 0
|
|
#define BITS_FIREMODE_AKIMBO_SEMI_AUTO 1
|
|
#define BITS_FIREMODE_AKIMBO_FREE_SEMI 2
|
|
#define BITS_FIREMODE_AKIMBO_FULL_AUTO 4
|
|
#define BITS_FIREMODE_AKIMBO_FREE_FULL 8
|
|
|
|
|
|
|
|
#define BITS_WEAPONOPT_NONE 0x00
|
|
#define BITS_WEAPONOPT_SILENCER 0x01
|
|
#define BITS_WEAPONOPT_LASERSIGHT 0x02
|
|
#define BITS_WEAPONOPT_FLASHLIGHT 0x04
|
|
#define BITS_WEAPONOPT_SCOPE 0x08
|
|
#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.
|
|
//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.
|
|
#define BITMASK_WEAPONOPT_TOGGLEABLE BITS_WEAPONOPT_LASERSIGHT | BITS_WEAPONOPT_FLASHLIGHT
|
|
// only min/max order of bits.
|
|
#define BITMASK_WEAPONOPT_TOGGLEABLE_MIN BITS_WEAPONOPT_LASERSIGHT
|
|
#define BITMASK_WEAPONOPT_TOGGLEABLE_MAX BITS_WEAPONOPT_FLASHLIGHT
|
|
|
|
|
|
#define BUYCATEGORY_NONE 0
|
|
#define BUYCATEGORY_HANDGUNS 1
|
|
#define BUYCATEGORY_SMGS 2
|
|
#define BUYCATEGORY_RIFLES 3
|
|
#define BUYCATEGORY_SHOTGUNS 4
|
|
#define BUYCATEGORY_SPECIALPURPOSE 5
|
|
|
|
|
|
|
|
#define WEAPONDATA_TYPEID_BASIC 0
|
|
#define WEAPONDATA_TYPEID_GUN 1
|
|
#define WEAPONDATA_TYPEID_IRONSIGHT 2
|
|
//#define WEAPONDATA_TYPEID_AKIMBO 3
|
|
#define WEAPONDATA_TYPEID_MELEE 3
|
|
//Note that THROWABLE is knives, not grenades.
|
|
#define WEAPONDATA_TYPEID_THROWABLE 4
|
|
|
|
|
|
|
|
#define ary_myWeapons_length 16
|
|
|
|
|
|
|
|
|
|
|
|
class player;
|
|
class weapondynamic_t;
|
|
|
|
// commonly used in akimbo-fire methods for weapon-specific firint script.
|
|
// Parameter list commonly looks like:
|
|
// player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed
|
|
typedef void(player, weapondynamic_t, int) MethodType_WeaponAttack;
|
|
|
|
|
|
//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)
|
|
// Other specifics like sound to make on hitting a surface / metal-spark effect are already
|
|
// handled in-method. For karate (something with its own custom effects), just do that in its
|
|
// own file instead.
|
|
enum MELEE_HIT_RESPONSE{
|
|
NONE = 0, //usually an air whoosh sound
|
|
SOFT = 1, //some surface like dirt that has no metal hit sound, not even a miss.
|
|
METAL = 2, //metal clink sound to go with the automatic spark effect (TODO).
|
|
FLESH = 3 //hit something living.
|
|
|
|
};
|
|
|
|
//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.
|
|
//Note that weapons that come only in akimbo (golden colts) don't
|
|
//actually get an entry here. Their "WEAPON_ID" already points
|
|
//to something that is of WEAPONDATA_TYPEID_AKIMBO type.
|
|
enum WEAPON_AKIMBO_UPGRADE_ID{
|
|
NONE = 0,
|
|
SOCOMMK23 = 1,
|
|
BERETTA = 2,
|
|
FIVESEVEN = 3,
|
|
MINIUZI = 4,
|
|
SKORPION = 5,
|
|
LAST_ID = 6
|
|
|
|
};
|
|
|
|
|
|
//For quick reference, singular and akimbo ties:
|
|
//SOKOM_MK23 = 9, SOCOMMK23_akimbo = 10
|
|
//Beretta = 2, Beretta_akimbo = 8
|
|
//FiveSeven = 14, FiveSeven_akimbo = 30
|
|
//MiniUzi = 4, MiniUzi_akimbo = 16
|
|
//Skorpion = 37, Skorpion_akimbo = 38
|
|
|
|
|
|
//NOTICE - "LAST_WEAPON_ID" must never change.
|
|
enum WEAPON_ID{
|
|
NONE = 0,
|
|
GLOCK18 = 1,
|
|
BERETTA = 2,
|
|
//SLOT2_UNUSED = 2,
|
|
MINIUZI = 3,
|
|
BENELLIM3 = 4,
|
|
M4A1 = 5,
|
|
MP5SD = 6,
|
|
MP5K = 7,
|
|
|
|
BERETTA_AKIMBO = 8,
|
|
// 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,
|
|
|
|
SOCOMMK23 = 9,
|
|
SOCOMMK23_AKIMBO = 10,
|
|
|
|
USAS12 = 11,
|
|
DESERTEAGLE = 12,
|
|
AK47 = 13,
|
|
FIVESEVEN = 14,
|
|
STEYRAUG = 15,
|
|
|
|
MINIUZI_AKIMBO = 16,
|
|
|
|
STEYRTMP = 17,
|
|
BARRETTM82 = 18,
|
|
HKPDW = 19,
|
|
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.
|
|
// 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.
|
|
MAC10 = 23,
|
|
//UMP = 23,
|
|
|
|
M61GRENADE = 24, //There's the grenade! If it's ever made purchasable.
|
|
COMBATKNIFE = 25,
|
|
MOSSBERG500 = 26,
|
|
M16A4 = 27,
|
|
RUGERMK1 = 28,
|
|
C4 = 29,
|
|
|
|
FIVESEVEN_AKIMBO = 30,
|
|
|
|
RAGINGBULL = 31,
|
|
M60 = 32,
|
|
SAWEDOFF = 33,
|
|
KATANA = 34,
|
|
SEALKNIFE = 35,
|
|
// 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.
|
|
UMP = 39,
|
|
|
|
// 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.
|
|
KEVLAR = 41,
|
|
STEALTHSHOES = 42,
|
|
|
|
|
|
LAST_ID = 43
|
|
|
|
};
|
|
|
|
|
|
// For now, a simple way to turn WEAPON_AKIMBO_UPGRADE_ID into WEAPON_ID:
|
|
int ary_AKIMBO_UPGRADE_TO_WEAPON[] = {
|
|
WEAPON_ID::NONE,
|
|
WEAPON_ID::SOCOMMK23_AKIMBO,
|
|
WEAPON_ID::BERETTA_AKIMBO,
|
|
WEAPON_ID::FIVESEVEN_AKIMBO,
|
|
WEAPON_ID::MINIUZI_AKIMBO,
|
|
WEAPON_ID::SKORPION_AKIMBO
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
//string getFiremodeName(int firemodeBit);
|
|
//string getAkimboFiremodeName(int firemodeBit);
|
|
|
|
string getFiremodeName(int firemodeBit){
|
|
if(firemodeBit == BITS_FIREMODE_SEMI){
|
|
return "Semi-auto";
|
|
}else if(firemodeBit == BITS_FIREMODE_FULL){
|
|
return "Full-auto";
|
|
}else if(firemodeBit == BITS_FIREMODE_BURST){
|
|
return "Burst";
|
|
}else if(firemodeBit == BITS_FIREMODE_PUMP){
|
|
return "Pump-action";
|
|
}else{
|
|
return "???";
|
|
}
|
|
}
|
|
|
|
string getAkimboFiremodeName(int firemodeBit){
|
|
if(firemodeBit == BITS_FIREMODE_AKIMBO_SEMI_AUTO){
|
|
return "Semi-auto";
|
|
}else if(firemodeBit == BITS_FIREMODE_AKIMBO_FREE_SEMI){
|
|
return "Free Semi";
|
|
}else if(firemodeBit == BITS_FIREMODE_AKIMBO_FULL_AUTO){
|
|
return "Full-auto";
|
|
}else if(firemodeBit == BITS_FIREMODE_AKIMBO_FREE_FULL){
|
|
return "Free Full";
|
|
}else{
|
|
return "???";
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
//NOTE - all below used to be in weapon.c TESTING
|
|
|
|
|
|
|
|
//NOTE FROM weapons_official.txt - read this in and fill weapon values.
|
|
// or just hardcode it, maybe no one cares.
|
|
//values are : weapon id | accuracy | view kickback | accuracy kickback.
|
|
//-IMPORTANT:dont change weapon id
|
|
//-accuracy cant go under 0.001.
|
|
//-if you put an accuracy kickback of 0 accuracy will not be scaled.
|
|
|
|
//If you want use different weapon settings use the "customweapons" cvar,
|
|
//like "customweapons weapons_custom.txt".
|
|
//By the way, be careful to use weapons custom values :)
|
|
//===========================================
|
|
|
|
//Glock-18
|
|
//1 0.022000 1.500000 0.007000
|
|
|
|
|
|
//var weapondata_t = {0.022000, 1.500000, 0.007000, }
|
|
//1 0.022000 1.500000 0.007000
|
|
|
|
typedef struct{
|
|
float fAccuracy;
|
|
float fViewKickback;
|
|
float fAccuracyKickback;
|
|
|
|
} weapondata_firestats_t;
|
|
|
|
|
|
|
|
// 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
|
|
|
|
|
|
// 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{
|
|
|
|
// TODO. make this a struct instead? should be feasible.
|
|
// yes this is a class... hm. fix later.
|
|
class weapondynamic_t{
|
|
PREDICTED_INT(weaponID); //what weapon is this referring to in the array of weapon data (glock, SOCOM, SMG, M4A1, etc.)
|
|
PREDICTED_INT(weaponTypeID); //what type of struct does the weapon use for convenient casting in lookups (gun, ironsight, melee, throwable)?
|
|
|
|
// what did the player actually buy?
|
|
// Also set this even for forced buyopts, such as the ruger's silencer.
|
|
PREDICTED_INT(iBitsUpgrade);
|
|
|
|
// How many of this weapon are equipped? The Akimbo BuyOpt makes this potentially 2.
|
|
// Weapons that come akimbo (golden colts) will still treat this as "1".
|
|
// This is not for whether to use iClipAkimboLeft ever, that is handled by just looking at iBitsUpgrade.
|
|
// This is for whether the current weapon should be treated as one (golden colts drop together in one
|
|
// model) or whether dropping just removes the akimbo version.
|
|
// Throwing knives can also use this iCount to stack instead.
|
|
PREDICTED_INT(iCount);
|
|
|
|
//Does keeping track of these things on an actual inventory'd weapon even makes sense?
|
|
//Ah well, lazy client-server logic compatability for now.
|
|
PREDICTED_INT(iPrice);
|
|
PREDICTED_INT(iSlots);
|
|
|
|
|
|
PREDICTED_INT(iClipLeft);
|
|
PREDICTED_INT(iClipAkimboLeft); //ammo left of the 2nd weapon if the akimbo option is present.
|
|
|
|
// Buyopts flashlight and lasersight can be toggled on/off. The rest don't need
|
|
// to be part of this bitmask to be on at all times.
|
|
PREDICTED_INT(iBitsUpgrade_on);
|
|
|
|
|
|
|
|
// What firemode is the player using for this weapon now?
|
|
PREDICTED_INT(iFireMode);
|
|
PREDICTED_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).
|
|
PREDICTED_INT(iIronSight);
|
|
|
|
// Do I force the first bodygroup's submodel to a certain choice?
|
|
// NOTE - do not set to 0 during intended use! That is only a lazy default to say, don't do anything
|
|
// to the submodel on drawing this weapon. Submodels actually start at 1, even if the only one.
|
|
// If set to 0, the change will only be noticed on undrawing/drawing the weapon as the submodel will
|
|
// not be applied then. Set to 1 to change in real time (likely the intention).
|
|
PREDICTED_INT(iForceBodygroup1Submodel);
|
|
|
|
// In pump-action mode, set to TRUE after firing the shotgun. The next click pumps
|
|
// instead.
|
|
// Note that switching to semi-fire mode and firing turns this flag off.
|
|
// Changing to semi-fire mode alone however, doesn't (changing fire modes without firing
|
|
// leaves this flag unaffected).
|
|
// Reloading also disables this flag, as it always ends in a visual pump.
|
|
// (was BOOL)
|
|
PREDICTED_FLOAT(bNeedsPump);
|
|
|
|
|
|
void(void) weapondynamic_t;
|
|
|
|
};
|
|
|
|
|
|
|
|
void weapondynamic_t::weapondynamic_t(void){
|
|
weaponID = 0;
|
|
weaponTypeID = -1;
|
|
}
|
|
|
|
|
|
|
|
typedef struct{
|
|
//These indexes can also be set to -1 to suggest, "none".
|
|
int iAnim_Change_Index;
|
|
float fAnim_Change_Duration;
|
|
int iAnim_ReChange_Index;
|
|
float fAnim_ReChange_Duration;
|
|
|
|
int iAnim_Idle_Index;
|
|
//frozen too.
|
|
|
|
int iAnim_Reload_Index;
|
|
float fAnim_Reload_Duration;
|
|
|
|
//can have different firestats from ordinary firing.
|
|
weapondata_firestats_t firestats;
|
|
|
|
//int iBitsScopeMagChoices;
|
|
|
|
|
|
} 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.
|
|
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.
|
|
|
|
void(player pl, weapondynamic_t arg_thisWeapon) funOnPrimaryAttackRelease;
|
|
void(player pl, weapondynamic_t arg_thisWeapon) funOnSecondaryAttackRelease;
|
|
|
|
// 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) funOnThink;
|
|
|
|
// 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) funOnColdCock;
|
|
|
|
// This event is for recently changing the zoom level on the player.
|
|
void(player pl) funOnSetZoomLevel;
|
|
|
|
|
|
int iAnim_Idle_Index;
|
|
//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.
|
|
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 different 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 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;
|
|
|
|
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.
|
|
int iAkimboID;
|
|
|
|
|
|
} weapondata_basic_t;
|
|
|
|
|
|
|
|
typedef struct{
|
|
int typeID;
|
|
string sDisplayName;
|
|
string sViewModelPath;
|
|
string sPlayerModelPath;
|
|
string sPlayerSilencerModelPath;
|
|
string sWorldModelPath;
|
|
string sIconFilePath;
|
|
|
|
void(player pl, weapondynamic_t arg_thisWeapon) funOnPrimaryAttackRelease;
|
|
void(player pl, weapondynamic_t arg_thisWeapon) funOnSecondaryAttackRelease;
|
|
|
|
void(player pl, weapondynamic_t arg_thisWeapon) funOnThink;
|
|
void(player pl, weapondynamic_t arg_thisWeapon) funOnColdCock;
|
|
void(player pl) funOnSetZoomLevel;
|
|
|
|
|
|
int iAnim_Idle_Index;
|
|
|
|
int iAnim_Deploy_Index;
|
|
float fAnim_Deploy_Duration;
|
|
|
|
float fAttackDelay;
|
|
float fAttackDamage;
|
|
|
|
BOOL fDrawCrosshair;
|
|
|
|
int iBitsUpgrade;
|
|
int iBitsUpgradeAuto;
|
|
|
|
//--------------------------------------------------------------------------
|
|
int iPrice;
|
|
int iSlots;
|
|
int iBuyCategory;
|
|
//--------------------------------------------------------------------------
|
|
|
|
int iInventorySlot;
|
|
|
|
//yes - even melee weapons have this.
|
|
weapondata_firestats_t firestats;
|
|
|
|
int iAkimboID;
|
|
|
|
//!!!GUN SPECIFIC BELOW!!!
|
|
int iBitsFireModes;
|
|
int iBitDefaultFireMode;
|
|
|
|
int iAmmoDataID;
|
|
int iClipMax;
|
|
|
|
int fRange;
|
|
|
|
int iAnim_Reload_Index;
|
|
float fAnim_Reload_Duration;
|
|
|
|
//unfortunately, we gotta provide these for all weapons.. sigh. feels ugly but it's simple.
|
|
// Make it -1 for things not provided. (if a buyopt still supports that _part var and it says -1,
|
|
// we just still don't attempt any attachment changes)
|
|
// ALSO keep in mind some things share the exact same attachment. That is the five_seven's
|
|
// lasersight and flashlight use the exact same attachment, so there is no difference between buying
|
|
// either or both of them. But this is not the case for all weapons, so assume these can be each
|
|
// unique. I think some rifles like the m4a1 have all of these anyway.
|
|
int silencer_part;
|
|
int lasersight_part;
|
|
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",
|
|
//the scope takes precedence (secondary fire mode no longer possible; always scopes).
|
|
typedef struct{
|
|
int typeID;
|
|
string sDisplayName;
|
|
string sViewModelPath;
|
|
string sPlayerModelPath;
|
|
string sPlayerSilencerModelPath;
|
|
string sWorldModelPath;
|
|
string sIconFilePath;
|
|
|
|
void(player pl, weapondynamic_t arg_thisWeapon) funOnPrimaryAttackRelease;
|
|
void(player pl, weapondynamic_t arg_thisWeapon) funOnSecondaryAttackRelease;
|
|
|
|
void(player pl, weapondynamic_t arg_thisWeapon) funOnThink;
|
|
void(player pl, weapondynamic_t arg_thisWeapon) funOnColdCock;
|
|
void(player pl) funOnSetZoomLevel;
|
|
|
|
|
|
int iAnim_Idle_Index;
|
|
|
|
int iAnim_Deploy_Index;
|
|
float fAnim_Deploy_Duration;
|
|
|
|
float fAttackDelay;
|
|
float fAttackDamage;
|
|
|
|
BOOL fDrawCrosshair;
|
|
|
|
int iBitsUpgrade;
|
|
int iBitsUpgradeAuto;
|
|
//--------------------------------------------------------------------------
|
|
int iPrice;
|
|
int iSlots;
|
|
int iBuyCategory;
|
|
//--------------------------------------------------------------------------
|
|
int iInventorySlot;
|
|
|
|
//yes - even melee weapons have this.
|
|
weapondata_firestats_t firestats;
|
|
|
|
int iAkimboID;
|
|
|
|
//!!!GUN SPECIFIC BELOW!!!
|
|
int iBitsFireModes;
|
|
int iBitDefaultFireMode;
|
|
|
|
int iAmmoDataID;
|
|
int iClipMax;
|
|
|
|
int fRange;
|
|
//!!!!!!!!!!!!!!!!!!!!
|
|
int iAnim_Reload_Index;
|
|
float fAnim_Reload_Duration;
|
|
|
|
int silencer_part;
|
|
int lasersight_part;
|
|
int flashlight_part;
|
|
int scope_part;
|
|
|
|
// NEW
|
|
ironsightdata_t ironsightdata;
|
|
|
|
} weapondata_ironsight_t;
|
|
|
|
|
|
|
|
typedef struct{
|
|
int typeID;
|
|
string sDisplayName;
|
|
string sViewModelPath;
|
|
string sPlayerModelPath;
|
|
string sPlayerSilencerModelPath;
|
|
string sWorldModelPath;
|
|
string sIconFilePath;
|
|
|
|
void(player pl, weapondynamic_t arg_thisWeapon) funOnPrimaryAttackRelease;
|
|
void(player pl, weapondynamic_t arg_thisWeapon) funOnSecondaryAttackRelease;
|
|
|
|
void(player pl, weapondynamic_t arg_thisWeapon) funOnThink;
|
|
void(player pl, weapondynamic_t arg_thisWeapon) funOnColdCock;
|
|
void(player pl) funOnSetZoomLevel;
|
|
|
|
|
|
int iAnim_Idle_Index;
|
|
|
|
int iAnim_Deploy_Index;
|
|
float fAnim_Deploy_Duration;
|
|
|
|
float fAttackDelay;
|
|
float fAttackDamage;
|
|
|
|
BOOL fDrawCrosshair;
|
|
|
|
int iBitsUpgrade;
|
|
int iBitsUpgradeAuto;
|
|
//--------------------------------------------------------------------------
|
|
int iPrice;
|
|
int iSlots;
|
|
int iBuyCategory;
|
|
//--------------------------------------------------------------------------
|
|
|
|
int iInventorySlot;
|
|
|
|
// 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.
|
|
|
|
} weapondata_melee_t;
|
|
|
|
|
|
|
|
typedef struct{
|
|
int typeID;
|
|
string sDisplayName;
|
|
string sViewModelPath;
|
|
string sPlayerModelPath;
|
|
string sPlayerSilencerModelPath;
|
|
string sWorldModelPath;
|
|
string sIconFilePath;
|
|
|
|
void(player pl, weapondynamic_t arg_thisWeapon) funOnPrimaryAttackRelease;
|
|
void(player pl, weapondynamic_t arg_thisWeapon) funOnSecondaryAttackRelease;
|
|
|
|
void(player pl, weapondynamic_t arg_thisWeapon) funOnThink;
|
|
void(player pl, weapondynamic_t arg_thisWeapon) funOnColdCock;
|
|
void(player pl) funOnSetZoomLevel;
|
|
|
|
|
|
int iAnim_Idle_Index;
|
|
|
|
int iAnim_Deploy_Index;
|
|
float fAnim_Deploy_Duration;
|
|
|
|
float fAttackDelay;
|
|
float fAttackDamage;
|
|
|
|
BOOL fDrawCrosshair;
|
|
|
|
int iBitsUpgrade;
|
|
int iBitsUpgradeAuto;
|
|
//--------------------------------------------------------------------------
|
|
int iPrice;
|
|
int iSlots;
|
|
int iBuyCategory;
|
|
//--------------------------------------------------------------------------
|
|
|
|
int iInventorySlot;
|
|
|
|
//yes - even melee weapons have this.
|
|
weapondata_firestats_t firestats;
|
|
|
|
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.
|
|
int iMaxCount;
|
|
// ALSO, how much damage do I do when thrown? Unsure what could change how much is dealt yet.
|
|
float fThrowDamage;
|
|
// How fast am I moving when thrown?
|
|
float fThrowSpeed;
|
|
// How fast do I fall? 1 = normal gravity, less goes further before hitting the ground.
|
|
// 0 = no gravity (straight line movement).
|
|
// Some things like crossbow bolts seem to go straight for so far, then start to fall.
|
|
// Most likely not relevant here though.
|
|
float fThrowGravity;
|
|
|
|
|
|
} weapondata_throwable_t;
|
|
|
|
|
|
|
|
|
|
// arbitrary, unreatled to weaponID's. Assign to some var in the player
|
|
// at draw (equip) time or send along shotgun-related method calls, no idea
|
|
// what route is best.
|
|
// No need for a NONE choice, leftover choice on weapon changes doesn't matter
|
|
// if the current weapon never does anything that looks at shotgun extra info.
|
|
// Also, shotguns that have ironsight need another entry for that because ironsight has
|
|
// its own set of sequences.
|
|
enum SHOTGUN_EXTRA_ID{
|
|
BENELLIM3 = 0,
|
|
MOSSBERG500,
|
|
MOSSBERG500_IRONSIGHT,
|
|
SPAS12,
|
|
LAST_ID
|
|
};
|
|
|
|
// There is no 'weapondata_shotgun'. Instead, shotguns can use some extra
|
|
// stats. Requires its own enum as there won't be one for every single weaponID.
|
|
typedef struct{
|
|
int shotgunReload1_seq;
|
|
float shotgunReload1_Duration;
|
|
|
|
int shotgunReload2_seq;
|
|
float shotgunReload2_Duration;
|
|
float shotgunReload2_ammoLoadDelay;
|
|
|
|
int shotgunReload3_seq;
|
|
float shotgunReload3_Duration;
|
|
} weapondata_shotgun_extra_t;
|
|
|
|
|
|
//TODO. Is extern'ing these earlier possible?
|
|
ammodata_t* ary_ammoData[AMMO_ID::LAST_ID];
|
|
#ifdef CLIENT
|
|
shellejectdata_t* ary_shellEjectData[SHELLEJECT_ID::LAST_ID];
|
|
muzzleflashdata_t* ary_muzzleFlashData[MUZZLEFLASH_ID::LAST_ID];
|
|
#endif
|
|
|
|
//weapondata_normal_t* ary_weaponData[WEAPON_ID::LAST_ID];
|
|
//Void pointer should be fine, right? Cast to the right weapondata_ struct above (typeID tells what that is).
|
|
//actually make it weapondata_basic_t, which at least includes the typeID and some other basic stuff
|
|
weapondata_basic_t* ary_weaponData[WEAPON_ID::LAST_ID];
|
|
weapondata_basic_t* ary_akimboUpgradeData[WEAPON_AKIMBO_UPGRADE_ID::LAST_ID];
|
|
|
|
weapondata_shotgun_extra_t* ary_shotgunExtra[SHOTGUN_EXTRA_ID::LAST_ID];
|
|
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
MELEE_HIT_RESPONSE weapon_base_coldcock(player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon, float damageToDeal, float range );
|
|
|
|
|
|
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_individual(player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon, int shellCount);
|
|
void weapon_base_onAttack_multi(player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon, int shellCount, int attackTypeUsed);
|
|
|
|
|
|
void weapon_gun_burstFire(player pl, weapondata_gun_t* basePRef, weapondynamic_t arg_thisWeapon, int attackTypeUsed, int shotCount, float shotDelay, float attackDelay);
|
|
|
|
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);
|
|
|
|
void weapon_gun_akimbo_semi_primaryAttack(MethodType_WeaponAttack arg_funAttack);
|
|
void weapon_gun_akimbo_semi_secondaryAttack(MethodType_WeaponAttack arg_funAttack);
|
|
void weapon_ironsight_akimbo_semi_secondaryAttack(MethodType_WeaponAttack arg_funAttack, int arg_weaponTypeID);
|
|
|
|
void weapon_gun_akimbo_full_primaryAttack(MethodType_WeaponAttack arg_funAttack);
|
|
void weapon_gun_akimbo_full_secondaryAttack(MethodType_WeaponAttack arg_funAttack);
|
|
|
|
BOOL weapon_akimbo_semiAttackDualHack(player pl, weapondynamic_t arg_thisWeapon, int arg_flagger, MethodType_WeaponAttack arg_funAttack);
|
|
BOOL weapon_akimbo_fullAttackDualHack(player pl, weapondynamic_t arg_thisWeapon, int arg_flagger, MethodType_WeaponAttack arg_funAttack);
|
|
BOOL weapon_akimbo_AttackDualHack(player pl, weapondynamic_t arg_thisWeapon, int arg_flagger, MethodType_WeaponAttack arg_funAttack);
|
|
|
|
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);
|
|
|
|
|
|
void 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 );
|
|
|
|
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);
|
|
|
|
|
|
void weapon_gun_onThink(player pl, weapondata_gun_t* basePRef, weapondynamic_t arg_thisWeapon );
|
|
|
|
void weapon_gun_fireBurstBullet(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 );
|
|
|
|
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 weapon_ShowMuzzleFlash(int arg_muzzleFlashType);
|
|
void weapon_ShowMuzzleFlashAkimbo(int arg_muzzleFlashType, int arg_akimboChoice);
|
|
void weapon_EjectShell(int arg_shellEjectType);
|
|
void weapon_EjectShellAkimbo(int arg_shellEjectType, int arg_akimboChoice);
|
|
void weapon_ClientEffects(int arg_muzzleFlashType, int arg_shellEjectType);
|
|
void weapon_ClientEffectsAkimbo(int arg_muzzleFlashType, int arg_shellEjectType, int arg_akimboChoice);
|
|
|
|
void weapon_precache(weapondata_basic_t* basePRef);
|
|
|
|
//void weapon_gun_updateAmmo(player pl, weapondata_gun_t* basePRef, weapondynamic_t arg_thisWeapon);
|
|
void weapon_gun_updateAmmo(player pl, int weaponTypeID);
|
|
|
|
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 - 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.
|
|
typedef struct weaponconfig_weapon_s{
|
|
//class weaponconfig_weapon_t{
|
|
|
|
// what weapon is this referring to?
|
|
int weaponID;
|
|
|
|
// quick reference for struct type.
|
|
int weaponTypeID;
|
|
|
|
// 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.
|
|
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.
|
|
int iPrice;
|
|
int iSlots;
|
|
|
|
// No methods for the wicked
|
|
//void(void) weaponconfig_weapon_t;
|
|
} weaponconfig_weapon_t;
|
|
//};
|
|
|
|
|
|
/*
|
|
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.
|
|
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.
|
|
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).
|
|
int ary_ammoTotal[AMMO_ID::LAST_ID];
|
|
|
|
//How many slots does the current order take? Provided for quick access.
|
|
int iTotalSlots;
|
|
int iTotalPrice; //ditto
|
|
|
|
// No methods for the wicked
|
|
//void(void) weaponconfig_data_t;
|
|
|
|
} weaponconfig_data_t;
|
|
//};
|
|
|
|
|
|
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
|
|
void viewEv_playShotgunInsertShellSound(void);
|
|
|
|
void viewEv_weapon_ShowMuzzleFlash(void);
|
|
void viewEv_weapon_EjectShell(void);
|
|
void viewEv_weapon_ClientEffects(void)
|
|
|
|
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
|
|
|
|
|
|
|