diff --git a/src/client/progs.src b/src/client/progs.src index efdb149..b8649d5 100644 --- a/src/client/progs.src +++ b/src/client/progs.src @@ -14,6 +14,7 @@ // NEW. When present, the origin is exactly at the center of the player, no further offsets. // Keeps the view identical on the player dying and becoming spectator in place. +// Requires some hack-ins to Nuclide in order to work, but hey, it is a debug feature //#define DEBUG_FORCE_NO_VIEW_OFFSET diff --git a/src/client/ui.qc b/src/client/ui.qc index 81463d3..9acee1b 100644 --- a/src/client/ui.qc +++ b/src/client/ui.qc @@ -99,7 +99,7 @@ UI_ChangeScreen(UI_SCREEN arg_NewScreenID) printfline("UI_ChangeScreen:: arg_NewScreenID? %d", arg_NewScreenID); if(arg_NewScreenID == UI_SCREEN::NONE){ - // If at NONE or below, also do nothing. This has no "vOnInit" behavior. + // If at NONE or below, also do nothing. This has no "funInit" behavior. // Besides obligatory cleanup if we choose (which may as well be done right here) // And turn the cursor lock off. setcursormode(FALSE, "gfx/cursor", [0,0,0], 1.0f); @@ -117,7 +117,7 @@ UI_ChangeScreen(UI_SCREEN arg_NewScreenID) return; } - // If this screen has a vOnInit, do it! + // If this screen has a funInit, do it! // This is done for the new screen once as soon as it becomes the active one. // Also, turn the cursor lock on, clearly this needs user input. // src/client/entry.qc already has this check too for having any UI widget, but @@ -327,7 +327,7 @@ UI_Draw(void) { if ( pSeatLocal->m_flUI_Display == UI_SCREEN::NONE ) { setcursormode( FALSE ); - return FALSE; + return; } if(g_UI_queueInit){ @@ -337,7 +337,7 @@ UI_Draw(void) if(!ary_UI_Screen[pSeatLocal->m_flUI_Display-1].bInitializedYet){ // no drawing uninitialized UI. Is this even possible? - return FALSE; + return; } UI_determineDrawGlobals(); @@ -354,7 +354,7 @@ UI_Draw(void) // Display the contents of whatever we have selected ary_UI_Screen[pSeatLocal->m_flUI_Display-1].funDraw(); - return TRUE; + return; } diff --git a/src/client/ui_buymenu.qc b/src/client/ui_buymenu.qc index ceadc4f..86c876a 100644 --- a/src/client/ui_buymenu.qc +++ b/src/client/ui_buymenu.qc @@ -15,18 +15,18 @@ -#define INITIALIZE_BASICBUTTON(arg_varName, arg_sName, arg_sHotkeyDisplay, arg_clr, arg_vOnClick_Custom) buymenu_btn_##arg_varName = spawn(CBuyMenu_BasicButton);\ +#define INITIALIZE_BASICBUTTON(arg_varName, arg_sName, arg_sHotkeyDisplay, arg_clr, arg_funOnClick_Custom) buymenu_btn_##arg_varName = spawn(CBuyMenu_BasicButton);\ flDeterminedHotkey = determineHotkeyFromChar(arg_sHotkeyDisplay);\ buymenu_btn_##arg_varName.setThisPointer(&buymenu_btn_##arg_varName);\ - buymenu_btn_##arg_varName.create(sprintf("%s %s", arg_sHotkeyDisplay, arg_sName), flDeterminedHotkey, arg_clr, arg_vOnClick_Custom);\ + buymenu_btn_##arg_varName.create(sprintf("%s %s", arg_sHotkeyDisplay, arg_sName), flDeterminedHotkey, arg_clr, arg_funOnClick_Custom);\ buymenu_addbuttonToTotal(&buymenu_btn_##arg_varName); -#define INITIALIZE_WEAPONBUTTON(arg_varName, arg_sHotkeyDisplay, arg_clr, arg_vOnClick_Custom, arg_parentName) buymenu_btn_Buy_##arg_varName = spawn(CBuyMenu_WeaponButton);\ +#define INITIALIZE_WEAPONBUTTON(arg_varName, arg_sHotkeyDisplay, arg_clr, arg_parentName) buymenu_btn_Buy_##arg_varName = spawn(CBuyMenu_WeaponButton);\ flDeterminedHotkey = determineHotkeyFromChar(arg_sHotkeyDisplay);\ buymenu_btn_Buy_##arg_varName.setThisPointer(&buymenu_btn_Buy_##arg_varName);\ tempWeapRef = *ary_weaponData[WEAPON_ID::##arg_varName];\ - buymenu_btn_Buy_##arg_varName.create_WeaponButton(sprintf("%s %s", arg_sHotkeyDisplay, tempWeapRef.sDisplayName), flDeterminedHotkey, arg_clr, arg_vOnClick_Custom, tempWeapRef.sIconFilePath, tempWeapRef.iPrice, tempWeapRef.iSlots, tempWeapRef.iBitsUpgrade & ~tempWeapRef.iBitsUpgradeAuto);\ + buymenu_btn_Buy_##arg_varName.create_WeaponButton(sprintf("%s %s", arg_sHotkeyDisplay, tempWeapRef.sDisplayName), flDeterminedHotkey, arg_clr, NULL, tempWeapRef.sIconFilePath, tempWeapRef.iPrice, tempWeapRef.iSlots, tempWeapRef.iBitsUpgrade & ~tempWeapRef.iBitsUpgradeAuto);\ buymenu_addbuttonToTotal(&buymenu_btn_Buy_##arg_varName);\ buymenu_btn_Buy_##arg_varName.iWeaponPurchaseID = WEAPON_ID::##arg_varName;\ buymenu_addbutton(&buymenu_btn_Buy_##arg_parentName, &buymenu_btn_Buy_##arg_varName); @@ -201,22 +201,22 @@ class CBuyMenu_BasicButton{ // Special behavior for this button (optional). Good for buttons that will interact // with something in the game like adding a weapon or adding an accessory (Silencer) to an existing one. - //virtual void(CBuyMenu_BasicButton* arg_this) vOnClick_Custom = NULL; - int* vOnClick_Custom; - //virtual void(CBuyMenu_BasicButton* arg_this) vOnShow_Custom = NULL; - int* vOnShow_Custom; + virtual void(CBuyMenu_BasicButton* arg_this) funOnClick_Custom = NULL; + //int* funOnClick_Custom; + virtual void(CBuyMenu_BasicButton* arg_this) funOnShow_Custom = NULL; + //int* funOnShow_Custom; void(void) CBuyMenu_BasicButton; virtual void(CBuyMenu_BasicButton* arg_this) setThisPointer; - virtual void(string arg_sName, float arg_flHotkey, vector arg_clr, void(CBuyMenu_BasicButton* arg_this)* arg_vOnClick_Custom ) create; + virtual void(string arg_sName, float arg_flHotkey, vector arg_clr, void(CBuyMenu_BasicButton* arg_this) arg_funOnClick_Custom ) create; - virtual void(vector arg_suggestedDrawPos, int arg_iLayer, int arg_iButtonRow, BOOL arg_fIsSelected) vOnRender_Base; - virtual void(void) vOnClick_Base; + virtual void(vector arg_suggestedDrawPos, int arg_iLayer, int arg_iButtonRow, BOOL arg_fIsSelected) funOnRender_Base; + virtual void(void) funOnClick_Base; - virtual void(void) vOnShow_Base; + virtual void(void) funOnShow_Base; // This is set separately from any "create" methods or constructors since it is rarely used. // If set, this method will run anytime this button is shown. This lets it do a quick calculation @@ -243,14 +243,13 @@ class CBuyMenu_WeaponButton : CBuyMenu_BasicButton{ void(void) CBuyMenu_WeaponButton; // after arg_clr: int arg_ary_btn_index[16] - virtual void(string arg_sName, float arg_flHotkey, vector arg_clr, void(CBuyMenu_BasicButton* arg_this)* arg_vOnClick_Custom, string arg_sWeaponImagePath, int arg_iWeaponPrice, int arg_iWeaponSlots, int arg_iBitsWeaponOpt ) create_WeaponButton; + virtual void(string arg_sName, float arg_flHotkey, vector arg_clr, void(CBuyMenu_BasicButton* arg_this) arg_funOnClick_Custom, string arg_sWeaponImagePath, int arg_iWeaponPrice, int arg_iWeaponSlots, int arg_iBitsWeaponOpt ) create_WeaponButton; - virtual void(vector arg_suggestedDrawPos, int arg_iLayer, int arg_iButtonRow, BOOL arg_fIsSelected) vOnRender_Base; - virtual void(void) vOnClick_Base; + virtual void(vector arg_suggestedDrawPos, int arg_iLayer, int arg_iButtonRow, BOOL arg_fIsSelected) funOnRender_Base; + virtual void(void) funOnClick_Base; - virtual void(void) vOnShow_Base; - //virtual void(CBuyMenu_BasicButton* arg_this) vOnShow_Custom = NULL; + virtual void(void) funOnShow_Base; }; @@ -282,11 +281,11 @@ checkBuyMenuButtonClicked( { CBuyMenu_BasicButton deref = *arg_someBtn; - if(UI_CheckMouse( vPosition, vSize )){ + if(UI_CheckMouse(vPosition, vSize)){ // What button is being hovered over? iHoveredButtonIndex = deref.iGlobalIndex; - (*arg_someBtn).vOnClick_Base(); + (*arg_someBtn).funOnClick_Base(); pSeatLocal->m_inputMouseClicked = FALSE; return TRUE; @@ -305,7 +304,7 @@ checkBuyMenuButtonHotKeyPressed( // Check for the button's hotkey. if(deref.flHotkey != -1 && pSeatLocal->m_inputKeyDown == deref.flHotkey){ - (*arg_someBtn).vOnClick_Base(); + (*arg_someBtn).funOnClick_Base(); pSeatLocal->m_inputKeyDown = 0; return TRUE; } @@ -550,8 +549,8 @@ CBuyMenu_BasicButton::CBuyMenu_BasicButton(void) { iType = BUTTON_TYPEID_BASIC; bActive = TRUE; - vOnClick_Custom = NULL; - vOnShow_Custom = NULL; + funOnClick_Custom = NULL; + funOnShow_Custom = NULL; } void CBuyMenu_BasicButton::setThisPointer(CBuyMenu_BasicButton* arg_this) @@ -559,46 +558,48 @@ CBuyMenu_BasicButton::setThisPointer(CBuyMenu_BasicButton* arg_this) _this = arg_this; } void -CBuyMenu_BasicButton::create(string arg_sName, float arg_flHotkey, vector arg_clr, void(CBuyMenu_BasicButton* arg_this)* arg_vOnClick_Custom ) -{ +CBuyMenu_BasicButton::create( + string arg_sName, float arg_flHotkey, vector arg_clr, + void(CBuyMenu_BasicButton* arg_this) arg_funOnClick_Custom +){ sName = arg_sName; flHotkey = arg_flHotkey; clr = arg_clr; clr_render = arg_clr; //good default. - vOnClick_Custom = arg_vOnClick_Custom; //(int*)&arg_vOnClick_Custom; - vOnShow_Custom = NULL; + funOnClick_Custom = arg_funOnClick_Custom; //(int*)&arg_funOnClick_Custom; + funOnShow_Custom = NULL; }//create void -CBuyMenu_BasicButton::vOnRender_Base +CBuyMenu_BasicButton::funOnRender_Base ( vector arg_suggestedDrawPos, int arg_iLayer, int arg_iButtonRow, BOOL arg_fIsSelected ) { drawBuyButton(this.iGlobalIndex, this.sName, arg_suggestedDrawPos, arg_iLayer, arg_iButtonRow, arg_fIsSelected, this.clr_render); -}//vOnRender_Base +}//funOnRender_Base void -CBuyMenu_BasicButton::vOnShow_Base(void) +CBuyMenu_BasicButton::funOnShow_Base(void) { - if(vOnShow_Custom != NULL){ - void(CBuyMenu_BasicButton* arg_this)* tempRef = vOnShow_Custom; - (*tempRef)(_this); - //vOnShow_Custom(_this); + if(funOnShow_Custom != NULL){ + //void(CBuyMenu_BasicButton* arg_this)* tempRef = funOnShow_Custom; + //(*tempRef)(_this); + funOnShow_Custom(_this); } -}// vOnShow_Base +}// funOnShow_Base // When this button is clicked, what does it do? void -CBuyMenu_BasicButton::vOnClick_Base(void) +CBuyMenu_BasicButton::funOnClick_Base(void) { // basic button behavior. Only if our array has a non-zero length. @@ -620,7 +621,7 @@ CBuyMenu_BasicButton::vOnClick_Base(void) // Also: go through each button that I'm going to show and set its "bAtive" to TRUE // (all buttons like weapon upgrades are visible - // unless purchased in that showing of the weapon). And call each one's "vOnShow" + // unless purchased in that showing of the weapon). And call each one's "funOnShow" // since there may be some logic such as // coloring the text red if the player can't afford that upgrade or weapon (in the // case of entire weapons by name buttons too). @@ -630,27 +631,27 @@ CBuyMenu_BasicButton::vOnClick_Base(void) if(someButton.iType == BUTTON_TYPEID_WEAPON){ CBuyMenu_WeaponButton someButto = *((CBuyMenu_WeaponButton*)ary_btnTotal[nextButtonIndex]); someButto.bActive = TRUE; - someButto.vOnShow_Base(); + someButto.funOnShow_Base(); }else{ someButton.bActive = TRUE; - someButton.vOnShow_Base(); + someButton.funOnShow_Base(); } } }// button length check - if(vOnClick_Custom != NULL){ + if(funOnClick_Custom != NULL){ // If we have a custom click method, do it. - void(CBuyMenu_BasicButton* arg_this)* tempRef = vOnClick_Custom; - (*tempRef)(_this); - //vOnClick_Custom(_this); + //void(CBuyMenu_BasicButton* arg_this)* tempRef = funOnClick_Custom; + //(*tempRef)(_this); + funOnClick_Custom(_this); } //Regardless, most buttons are bound to change the current layer and //possibly what the Cancel/Go Back button says (one of those two). buymenu_btn_Back_updateText(); -}//vOnClick_Base +}//funOnClick_Base void @@ -664,11 +665,10 @@ void CBuyMenu_WeaponButton::create_WeaponButton ( string arg_sName, float arg_flHotkey, vector arg_clr, - void(CBuyMenu_BasicButton* arg_this)* arg_vOnClick_Custom, + void(CBuyMenu_BasicButton* arg_this) arg_funOnClick_Custom, string arg_sWeaponImagePath, int arg_iWeaponPrice, int arg_iWeaponSlots, int arg_iBitsWeaponOpt -) -{ +){ //defaults. //_this_deref.iLayer = 0i; @@ -681,8 +681,8 @@ CBuyMenu_WeaponButton::create_WeaponButton clr = arg_clr; clr_render = arg_clr; //good default. - vOnClick_Custom = arg_vOnClick_Custom; //(int*)&arg_vOnClick_Custom; - vOnShow_Custom = NULL; //paranoia? + funOnClick_Custom = arg_funOnClick_Custom; //(int*)&arg_funOnClick_Custom; + funOnShow_Custom = NULL; //paranoia? // Why do we add "_0.tga" to a .spr reference for the draw to work? // The world may never know. @@ -727,13 +727,13 @@ CBuyMenu_WeaponButton::create_WeaponButton void -CBuyMenu_WeaponButton::vOnRender_Base +CBuyMenu_WeaponButton::funOnRender_Base ( vector arg_suggestedDrawPos, int arg_iLayer, int arg_iButtonRow, BOOL arg_fIsSelected ) { - CBuyMenu_BasicButton::vOnRender_Base( + CBuyMenu_BasicButton::funOnRender_Base( arg_suggestedDrawPos, arg_iLayer, arg_iButtonRow, arg_fIsSelected ); //call the parent's. @@ -766,7 +766,7 @@ CBuyMenu_WeaponButton::vOnRender_Base Gfx_Text( [textDrawOrigin.x, textDrawOrigin.y + (vButtonSizStandard.y+1) ], drawString2, vButtonFontSize, this.clr * 0.98f, (1.0f-(1.0f - arg_opac)*0.88) - 0.02f, DRAWFLAG_NORMAL, FONT_ARIAL_STD ); } -}//vOnRender_Base +}//funOnRender_Base // convenient way to reset these globals for keeping track of a purchase in progress. @@ -783,9 +783,9 @@ UI_BuyMenu_ResetTempVariables(void) void -CBuyMenu_WeaponButton::vOnShow_Base(void) +CBuyMenu_WeaponButton::funOnShow_Base(void) { - CBuyMenu_BasicButton::vOnShow_Base(); + CBuyMenu_BasicButton::funOnShow_Base(); // See if this weapon can be afforded. if(canBuyWeapon(iWeaponPurchaseID, 0, 0, 1)){ clr_render = clr; @@ -793,10 +793,10 @@ CBuyMenu_WeaponButton::vOnShow_Base(void) // same, but draw it red to show we can't afford it at a glance. clr_render = clrRed; } -}//vOnShow_Base +}//funOnShow_Base void -CBuyMenu_WeaponButton::vOnClick_Base(void) +CBuyMenu_WeaponButton::funOnClick_Base(void) { weapondata_basic_t weaponRef; // Just one thing. Let's reset this to be safe (new weapon opened for seeing @@ -810,7 +810,7 @@ CBuyMenu_WeaponButton::vOnClick_Base(void) if(!(iBitsWeaponOpt & BITS_WEAPONOPT_INSTANT)){ // normal behavior. iWeaponTempID = iWeaponPurchaseID; - CBuyMenu_BasicButton::vOnClick_Base(); + CBuyMenu_BasicButton::funOnClick_Base(); }else{ // has the instant flag? that's it, apply it if we can. if(canBuyWeapon(iWeaponPurchaseID, 0, 0, 1) ){ @@ -822,7 +822,7 @@ CBuyMenu_WeaponButton::vOnClick_Base(void) } } } -}//vOnClick_Base +}//funOnClick_Base void @@ -954,7 +954,7 @@ buymenu_btn_RemoveItem_clicked(CBuyMenu_BasicButton* arg_this) } //INITIALIZE_BASICBUTTON(ary_btn_removeButton[i], "7 Buy Random", 48+7,clrGreen, NULL) - ary_btn_removeButton[i].create(buttonDisplayText, hotKeyCode, clrPaleBlue, &buymenu_btn_removeButton_clicked); + ary_btn_removeButton[i].create(buttonDisplayText, hotKeyCode, clrPaleBlue, buymenu_btn_removeButton_clicked); ary_btn_removeButton[i].bActive = TRUE; //CBuyMenu_RemoveWeaponButton removeWeaponButtonRef2 = (CBuyMenu_RemoveWeaponButton)ary_btn_removeButton[i]; @@ -968,8 +968,8 @@ buymenu_btn_RemoveItem_clicked(CBuyMenu_BasicButton* arg_this) -// Take all buttons and call their "vOnShow". See what we can and can't afford -// (color red when we can't). vOnShow should handle this appropriately per button. +// Take all buttons and call their "funOnShow". See what we can and can't afford +// (color red when we can't). funOnShow should handle this appropriately per button. void refreshButtons(void) { @@ -983,7 +983,7 @@ refreshButtons(void) //CBuyMenu_BasicButton tempButton = *ary_layerFirstButton[i2]; for(i2 = 0; i2 < ary_layerFirstButton_softLength; i2++){ tempButton = *ary_layerFirstButton[i2]; - tempButton.vOnShow_Base(); + tempButton.funOnShow_Base(); }// for i2 in ary_layerFirstButton }else{ @@ -993,7 +993,7 @@ refreshButtons(void) //btnToRender = &previousLayerButton.ary_btn[i2]; int btnToRender_index_global = previousLayerButton.ary_btn_index[i2]; tempButton = *ary_btnTotal[btnToRender_index_global]; - tempButton.vOnShow_Base(); + tempButton.funOnShow_Base(); } } } @@ -1326,12 +1326,12 @@ UI_BuyMenu_Init(void) // if the 1st layer is active (drawn to that one). Says "Cancel" there, but if on any deeper layer it reads "Go Back". //buymenu_btn_Back.create("0 Cancel", 48, NULL, buymenu_btn_Back_clicked); - INITIALIZE_BASICBUTTON(Back, "Cancel", "0", clrPaleBluePurple, &buymenu_btn_Back_clicked) + INITIALIZE_BASICBUTTON(Back, "Cancel", "0", clrPaleBluePurple, buymenu_btn_Back_clicked) //INITIALIZE_BASICBUTTON(Buy, "2 Buy", 48+2, NULL, 0, NULL) - INITIALIZE_BASICBUTTON(Recentconfig, "Use New Config", "1", clrGreen, &buymenu_btn_UseNewConfig_clicked) + INITIALIZE_BASICBUTTON(Recentconfig, "Use New Config", "1", clrGreen, buymenu_btn_UseNewConfig_clicked) INITIALIZE_BASICBUTTON(Buy, "Buy", "2", clrPaleBlue, NULL) - INITIALIZE_BASICBUTTON(RemoveItem, "Remove Item", "3", clrPaleBlue, &buymenu_btn_RemoveItem_clicked) + INITIALIZE_BASICBUTTON(RemoveItem, "Remove Item", "3", clrPaleBlue, buymenu_btn_RemoveItem_clicked) INITIALIZE_BASICBUTTON(ResetConfig, "Reset Config", "4", clrPaleBlue, NULL) INITIALIZE_BASICBUTTON(SaveConfig, "Save Config", "5", clrPaleBlue, NULL) INITIALIZE_BASICBUTTON(LoadConfig, "Load Config", "6", clrPaleBlue, NULL) @@ -1344,27 +1344,27 @@ UI_BuyMenu_Init(void) // !!! INITIALIZE THE WEAPON-UPGRADE BUTTONS BEFORE THE WEAPONS THEMSELVES. Or else these will be missing at that point. - INITIALIZE_BASICBUTTON(WeaponOpt_Buy, "Buy", "1", clrGreen, &buymenu_btn_Buy_Weapon_clicked) - INITIALIZE_BASICBUTTON(WeaponOpt_Silencer, sprintf("Silencer %i", WEAPONOPT_SILENCER_COST), "2", clrPaleBlue, &buymenu_btn_Silencer_clicked) - INITIALIZE_BASICBUTTON(WeaponOpt_Lasersight, sprintf("Lasersight %i", WEAPONOPT_LASERSIGHT_COST), "3", clrPaleBlue, &buymenu_btn_Lasersight_clicked) - INITIALIZE_BASICBUTTON(WeaponOpt_Flashlight, sprintf("Flashlight %i", WEAPONOPT_FLASHLIGHT_COST), "4", clrPaleBlue, &buymenu_btn_Flashlight_clicked) - INITIALIZE_BASICBUTTON(WeaponOpt_Scope, sprintf("Scope %i", WEAPONOPT_SCOPE_COST), "5", clrPaleBlue, &buymenu_btn_Scope_clicked) + INITIALIZE_BASICBUTTON(WeaponOpt_Buy, "Buy", "1", clrGreen, buymenu_btn_Buy_Weapon_clicked) + INITIALIZE_BASICBUTTON(WeaponOpt_Silencer, sprintf("Silencer %i", WEAPONOPT_SILENCER_COST), "2", clrPaleBlue, buymenu_btn_Silencer_clicked) + INITIALIZE_BASICBUTTON(WeaponOpt_Lasersight, sprintf("Lasersight %i", WEAPONOPT_LASERSIGHT_COST), "3", clrPaleBlue, buymenu_btn_Lasersight_clicked) + INITIALIZE_BASICBUTTON(WeaponOpt_Flashlight, sprintf("Flashlight %i", WEAPONOPT_FLASHLIGHT_COST), "4", clrPaleBlue, buymenu_btn_Flashlight_clicked) + INITIALIZE_BASICBUTTON(WeaponOpt_Scope, sprintf("Scope %i", WEAPONOPT_SCOPE_COST), "5", clrPaleBlue, buymenu_btn_Scope_clicked) // Yes, Akimbo and FullLoad use the same hotkey (number 6). They never appear on the same weapon, // since Akimbo is only meant for some guns, and FullLoad is only meant for some melee weapons. // TODO? And if these two were to support flexible prices (show what it costs for the currently selected weapon... akimbo & fullLoad can't be fixed to // one constant for all weapons), their display text + prices would have to be shown as they're shown to the user. - INITIALIZE_BASICBUTTON(WeaponOpt_Akimbo, "Akimbo", "6", clrPaleBlue, &buymenu_btn_Akimbo_clicked) - INITIALIZE_BASICBUTTON(WeaponOpt_FullLoad, "FullLoad", "6", clrGreen, &buymenu_btn_FullLoad_clicked) + INITIALIZE_BASICBUTTON(WeaponOpt_Akimbo, "Akimbo", "6", clrPaleBlue, buymenu_btn_Akimbo_clicked) + INITIALIZE_BASICBUTTON(WeaponOpt_FullLoad, "FullLoad", "6", clrGreen, buymenu_btn_FullLoad_clicked) - buymenu_btn_WeaponOpt_Buy.vOnShow_Custom = &buymenu_btn_Buy_onShow; + buymenu_btn_WeaponOpt_Buy.funOnShow_Custom = buymenu_btn_Buy_onShow; - buymenu_btn_WeaponOpt_Silencer.vOnShow_Custom = &buymenu_btn_Silencer_onShow; - buymenu_btn_WeaponOpt_Lasersight.vOnShow_Custom = &buymenu_btn_Lasersight_onShow; - buymenu_btn_WeaponOpt_Flashlight.vOnShow_Custom = &buymenu_btn_Flashlight_onShow; - buymenu_btn_WeaponOpt_Scope.vOnShow_Custom = &buymenu_btn_Scope_onShow; - buymenu_btn_WeaponOpt_Akimbo.vOnShow_Custom = &buymenu_btn_Akimbo_onShow; - buymenu_btn_WeaponOpt_FullLoad.vOnShow_Custom = &buymenu_btn_FullLoad_onShow; + buymenu_btn_WeaponOpt_Silencer.funOnShow_Custom = buymenu_btn_Silencer_onShow; + buymenu_btn_WeaponOpt_Lasersight.funOnShow_Custom = buymenu_btn_Lasersight_onShow; + buymenu_btn_WeaponOpt_Flashlight.funOnShow_Custom = buymenu_btn_Flashlight_onShow; + buymenu_btn_WeaponOpt_Scope.funOnShow_Custom = buymenu_btn_Scope_onShow; + buymenu_btn_WeaponOpt_Akimbo.funOnShow_Custom = buymenu_btn_Akimbo_onShow; + buymenu_btn_WeaponOpt_FullLoad.funOnShow_Custom = buymenu_btn_FullLoad_onShow; // TODO - ONGOING. As more weapons are entered, use this new condensed way @@ -1376,51 +1376,51 @@ UI_BuyMenu_Init(void) weapondata_basic_t tempWeapRef; - INITIALIZE_WEAPONBUTTON(GLOCK18, "1", clrPaleBlue, NULL, Handguns) - INITIALIZE_WEAPONBUTTON(SOCOMMK23, "2", clrPaleBlue, NULL, Handguns) - INITIALIZE_WEAPONBUTTON(DESERTEAGLE, "3", clrPaleBlue, NULL, Handguns) - INITIALIZE_WEAPONBUTTON(FIVESEVEN, "4", clrPaleBlue, NULL, Handguns) - INITIALIZE_WEAPONBUTTON(BERETTA, "5", clrPaleBlue, NULL, Handguns) - INITIALIZE_WEAPONBUTTON(AKIMBOCOLTS, "6", clrPaleBlue, NULL, Handguns) - INITIALIZE_WEAPONBUTTON(GLOCK20, "7", clrPaleBlue, NULL, Handguns) - INITIALIZE_WEAPONBUTTON(RUGERMK1, "8", clrPaleBlue, NULL, Handguns) - INITIALIZE_WEAPONBUTTON(RAGINGBULL, "9", clrPaleBlue, NULL, Handguns) - INITIALIZE_WEAPONBUTTON(CONTENDERG2, "A", clrPaleBlue, NULL, Handguns) + INITIALIZE_WEAPONBUTTON(GLOCK18, "1", clrPaleBlue, Handguns) + INITIALIZE_WEAPONBUTTON(SOCOMMK23, "2", clrPaleBlue, Handguns) + INITIALIZE_WEAPONBUTTON(DESERTEAGLE, "3", clrPaleBlue, Handguns) + INITIALIZE_WEAPONBUTTON(FIVESEVEN, "4", clrPaleBlue, Handguns) + INITIALIZE_WEAPONBUTTON(BERETTA, "5", clrPaleBlue, Handguns) + INITIALIZE_WEAPONBUTTON(AKIMBOCOLTS, "6", clrPaleBlue, Handguns) + INITIALIZE_WEAPONBUTTON(GLOCK20, "7", clrPaleBlue, Handguns) + INITIALIZE_WEAPONBUTTON(RUGERMK1, "8", clrPaleBlue, Handguns) + INITIALIZE_WEAPONBUTTON(RAGINGBULL, "9", clrPaleBlue, Handguns) + INITIALIZE_WEAPONBUTTON(CONTENDERG2, "A", clrPaleBlue, Handguns) - INITIALIZE_WEAPONBUTTON(MINIUZI, "1", clrPaleBlue, NULL, SMGs) - INITIALIZE_WEAPONBUTTON(MP5SD, "2", clrPaleBlue, NULL, SMGs) - INITIALIZE_WEAPONBUTTON(MP5K, "3", clrPaleBlue, NULL, SMGs) + INITIALIZE_WEAPONBUTTON(MINIUZI, "1", clrPaleBlue, SMGs) + INITIALIZE_WEAPONBUTTON(MP5SD, "2", clrPaleBlue, SMGs) + INITIALIZE_WEAPONBUTTON(MP5K, "3", clrPaleBlue, SMGs) - INITIALIZE_WEAPONBUTTON(STEYRTMP, "4", clrPaleBlue, NULL, SMGs) - INITIALIZE_WEAPONBUTTON(HKPDW, "5", clrPaleBlue, NULL, SMGs) - INITIALIZE_WEAPONBUTTON(UMP, "6", clrPaleBlue, NULL, SMGs) + INITIALIZE_WEAPONBUTTON(STEYRTMP, "4", clrPaleBlue, SMGs) + INITIALIZE_WEAPONBUTTON(HKPDW, "5", clrPaleBlue, SMGs) + INITIALIZE_WEAPONBUTTON(UMP, "6", clrPaleBlue, SMGs) - INITIALIZE_WEAPONBUTTON(SKORPION, "7", clrPaleBlue, NULL, SMGs) - INITIALIZE_WEAPONBUTTON(MAC10, "8", clrPaleBlue, NULL, SMGs) + INITIALIZE_WEAPONBUTTON(SKORPION, "7", clrPaleBlue, SMGs) + INITIALIZE_WEAPONBUTTON(MAC10, "8", clrPaleBlue, SMGs) - INITIALIZE_WEAPONBUTTON(M4A1, "1", clrPaleBlue, NULL, Rifles) - INITIALIZE_WEAPONBUTTON(AK47, "2", clrPaleBlue, NULL, Rifles) - INITIALIZE_WEAPONBUTTON(STEYRAUG, "3", clrPaleBlue, NULL, Rifles) - INITIALIZE_WEAPONBUTTON(M16A4, "4", clrPaleBlue, NULL, Rifles) - INITIALIZE_WEAPONBUTTON(BARRETTM82, "5", clrPaleBlue, NULL, Rifles) + INITIALIZE_WEAPONBUTTON(M4A1, "1", clrPaleBlue, Rifles) + INITIALIZE_WEAPONBUTTON(AK47, "2", clrPaleBlue, Rifles) + INITIALIZE_WEAPONBUTTON(STEYRAUG, "3", clrPaleBlue, Rifles) + INITIALIZE_WEAPONBUTTON(M16A4, "4", clrPaleBlue, Rifles) + INITIALIZE_WEAPONBUTTON(BARRETTM82, "5", clrPaleBlue, Rifles) - INITIALIZE_WEAPONBUTTON(BENELLIM3, "1", clrPaleBlue, NULL, Shotguns) - INITIALIZE_WEAPONBUTTON(USAS12, "2", clrPaleBlue, NULL, Shotguns) - INITIALIZE_WEAPONBUTTON(SPAS12, "3", clrPaleBlue, NULL, Shotguns) - INITIALIZE_WEAPONBUTTON(MOSSBERG500, "4", clrPaleBlue, NULL, Shotguns) - INITIALIZE_WEAPONBUTTON(SAWEDOFF, "5", clrPaleBlue, NULL, Shotguns) + INITIALIZE_WEAPONBUTTON(BENELLIM3, "1", clrPaleBlue, Shotguns) + INITIALIZE_WEAPONBUTTON(USAS12, "2", clrPaleBlue, Shotguns) + INITIALIZE_WEAPONBUTTON(SPAS12, "3", clrPaleBlue, Shotguns) + INITIALIZE_WEAPONBUTTON(MOSSBERG500, "4", clrPaleBlue, Shotguns) + INITIALIZE_WEAPONBUTTON(SAWEDOFF, "5", clrPaleBlue, Shotguns) // LATER - make purchaseable only if the gamemode is team/scenario. (mercs vs specialists) - INITIALIZE_WEAPONBUTTON(M61GRENADE, "1", clrPaleBlue, NULL, SpecialPurpose) + INITIALIZE_WEAPONBUTTON(M61GRENADE, "1", clrPaleBlue, SpecialPurpose) - INITIALIZE_WEAPONBUTTON(COMBATKNIFE, "2", clrPaleBlue, NULL, SpecialPurpose) - INITIALIZE_WEAPONBUTTON(M60, "3", clrPaleBlue, NULL, SpecialPurpose) - INITIALIZE_WEAPONBUTTON(KATANA, "4", clrPaleBlue, NULL, SpecialPurpose) - INITIALIZE_WEAPONBUTTON(SEALKNIFE, "5", clrPaleBlue, NULL, SpecialPurpose) + INITIALIZE_WEAPONBUTTON(COMBATKNIFE, "2", clrPaleBlue, SpecialPurpose) + INITIALIZE_WEAPONBUTTON(M60, "3", clrPaleBlue, SpecialPurpose) + INITIALIZE_WEAPONBUTTON(KATANA, "4", clrPaleBlue, SpecialPurpose) + INITIALIZE_WEAPONBUTTON(SEALKNIFE, "5", clrPaleBlue, SpecialPurpose) //TODO - set these up. items are simpler than weapons and have no default behavior. // in fact the kevlar just puts armor on the player at spawn, stealthshoes may as well @@ -1428,8 +1428,8 @@ UI_BuyMenu_Init(void) // Last parameter is the cost instead of the buy category, since we don't have // any weapondata to get the cost from. // ...we still need the category too though. - //INITIALIZE_ITEMBUTTON_ADV(KEVLAR, "1", 48+1, clrPaleBlue, NULL, PlayerAccessory, 1900); - //INITIALIZE_ITEMBUTTON_ADV(STEALTHSHOES, "2", 48+2, clrPaleBlue, NULL, PlayerAccessory, 700); + //INITIALIZE_ITEMBUTTON_ADV(KEVLAR, "1", 48+1, clrPaleBlue, PlayerAccessory, 1900); + //INITIALIZE_ITEMBUTTON_ADV(STEALTHSHOES, "2", 48+2, clrPaleBlue, PlayerAccessory, 700); buymenu_btn_Back_updateText(); //just in case. @@ -1474,7 +1474,7 @@ UI_BuyMenu_Draw(void) int btnToRender_index_global; CBuyMenu_BasicButton someThing; CBuyMenu_BasicButton previousLayerButton; - BOOL fIsSelected; + BOOL fIsSelected = FALSE; // Checks for clicks be done separately @@ -1514,7 +1514,7 @@ UI_BuyMenu_Draw(void) CBuyMenu_BasicButton tempButton = *ary_layerFirstButton[i2]; fIsSelected = (tempButton.iGlobalIndex == currentLayerSelectedIndex); - (*ary_layerFirstButton[i2]).vOnRender_Base(vBtnPos, i, i2, fIsSelected); + (*ary_layerFirstButton[i2]).funOnRender_Base(vBtnPos, i, i2, fIsSelected); vBtnPos.y += (vButtonSizStandard.y + 1); @@ -1548,7 +1548,7 @@ UI_BuyMenu_Draw(void) fIsSelected = (btnToRender_index_global == currentLayerSelectedIndex); - (*ary_btnTotal[btnToRender_index_global]).vOnRender_Base(vBtnPos, i, i2, fIsSelected); + (*ary_btnTotal[btnToRender_index_global]).funOnRender_Base(vBtnPos, i, i2, fIsSelected); vBtnPos.y += (vButtonSizStandard.y + 1); }// for i2 in this layer's buttons. @@ -1568,7 +1568,7 @@ UI_BuyMenu_Draw(void) backButtonRow = ary_layerFirstButton_softLength; } - buymenu_btn_Back.vOnRender_Base(vBtnPos, i, backButtonRow, fIsSelected); + buymenu_btn_Back.funOnRender_Base(vBtnPos, i, backButtonRow, fIsSelected); vBtnPos.y += (vButtonSizStandard.y + 1); } diff --git a/src/server/progs.src b/src/server/progs.src index 09bfdb8..56fd150 100644 --- a/src/server/progs.src +++ b/src/server/progs.src @@ -38,7 +38,7 @@ - +/////////////////////////////////////////////////////////////////////////////// #includelist ../../../src/shared/fteextensions.qc ../../../src/gs-entbase/server/defs.h diff --git a/src/shared/ammo.h b/src/shared/ammo.h index 9997499..5e2428e 100644 --- a/src/shared/ammo.h +++ b/src/shared/ammo.h @@ -2,6 +2,8 @@ #define ASSIGN_AMMODATA(arg_constName) ary_ammoData[AMMO_ID::##arg_constName] = (ammodata_t*) &ammo_##arg_constName; #define DECLARE_AMMODATA(arg_varName, arg_sDisplayName, arg_fPricePerBullet, arg_iMax) ammodata_t ammo_##arg_varName = {arg_sDisplayName, arg_fPricePerBullet, arg_iMax}; +#define ASSIGN_SHELLEJECTDATA(arg_constName) ary_shellEjectData[SHELLEJECT_ID::##arg_constName] = (shellejectdata_t*) &shelleject_##arg_constName; +#define DECLARE_SHELLEJECTDATA(arg_varName, arg_sModelPath, arg_sTouchSound) shellejectdata_t shelleject_##arg_varName = {arg_sModelPath, arg_sTouchSound}; enum AMMO_ID{ @@ -38,3 +40,40 @@ typedef struct{ } ammodata_t; + + +// for shell ejection effects. +// Some are identical or near-identical, could have been intended to be unique +// models at some point but never happened? +enum SHELLEJECT_ID{ + NONE = 0, + + // Nearly identical, lighting looks to be the only difference, could even be + // randomly picked for all I know. + // Weapons will only use _56 of the two for now + _56, + _556, + + // These are identical, exact same filesize. + // _GENERIC refers to shell.mdl + // _22 is most likely referring to the luger's ammo, _9MM from the similarly named + // ammo type. Still using those first in weapons involving those + _22, + _9MM, + _GENERIC, + + _SHOTGUN, // red + _SHOTGUN_BLUE, + _SHOTGUN_GOLD, + LAST_ID +}; + + +// any other info tied to shell choice? +typedef struct{ + string sModelPath; + // script file (.sndshd) for hitting something, not a direct .wav file + string sTouchSound; + +} shellejectdata_t; + diff --git a/src/shared/ammo.qc b/src/shared/ammo.qc index 49dde8d..8a927f5 100644 --- a/src/shared/ammo.qc +++ b/src/shared/ammo.qc @@ -13,3 +13,15 @@ DECLARE_AMMODATA(_50BMG, "50BMG", 100, 20) DECLARE_AMMODATA(_SHELLS, "SHELLS", 16, 60) DECLARE_AMMODATA(_32ACP, ".32 ACP", 0.5, 300) DECLARE_AMMODATA(_7P62X51MM, "7.62 x 51mm", 30, 35) + + +DECLARE_SHELLEJECTDATA(NONE, "", "") +DECLARE_SHELLEJECTDATA(_56, "models/56_shell.mdl", "modelevent_shell.land") +DECLARE_SHELLEJECTDATA(_556, "models/556_shell.mdl", "modelevent_shell.land") +DECLARE_SHELLEJECTDATA(_22, "models/22_shell.mdl", "modelevent_shell.land") +DECLARE_SHELLEJECTDATA(_9MM, "models/9mm_shell.mdl", "modelevent_shell.land") +DECLARE_SHELLEJECTDATA(_GENERIC, "models/shell.mdl", "modelevent_shell.land") +DECLARE_SHELLEJECTDATA(_SHOTGUN, "models/shotgun_shell.mdl", "modelevent_shotgunshell.land") +DECLARE_SHELLEJECTDATA(_SHOTGUN_BLUE, "models/shotgun_shell_blue.mdl", "modelevent_shotgunshell.land") +DECLARE_SHELLEJECTDATA(_SHOTGUN_GOLD, "models/shotgun_shell_gold.mdl", "modelevent_shotgunshell.land") + diff --git a/src/shared/defs.h b/src/shared/defs.h index 29e066d..b40ee80 100644 --- a/src/shared/defs.h +++ b/src/shared/defs.h @@ -75,21 +75,11 @@ enum TS_Team{ //TAGGG - Still need to remove some irrelevant ones like BUYZONE,, ESCAPEZONE, WON_T, etc. // Also starting at stat 34? Feel some constant would be more comfortable for that, might not be an option though. enum { - STAT_BUYZONE = STAT_BUILTIN_SEPARATOR, + STAT_MONEY = STAT_BUILTIN_SEPARATOR, - STAT_MONEY, - STAT_FLAGS, - - STAT_PROGRESS, - STAT_TEAM, + //STAT_TEAM, // will we ever need that? STAT_GAMETIME, STAT_GAMESTATE, - /* - STAT_WON_T, - STAT_WON_CT, - */ - - // NEW. STAT_RULE_MONEYALLOWED, STAT_RULE_MAXWEIGHTSLOTS diff --git a/src/shared/include.src b/src/shared/include.src index 22066fb..b7d2089 100644 --- a/src/shared/include.src +++ b/src/shared/include.src @@ -1,4 +1,18 @@ - #includelist + + + +// If enabled, pressing left and right fire within a small amount of time +// (more forgiving than the default "same-frame only" timing) lets firing +// immediately change into the akimbo dual-fire animation. +// Should not cause any more than the net number of bullets expected for +// firing both weapons. That is, left-fire, 80 milliseconds, right-fire will +// mean the left-play anim plays (fired once), then the dual-fire anim plays, +// but it should remember that the left weapon already fired, and so only fire +// the right weapon on the tolerance-allowed dual-fire anim. 2 bullet holes, +// not 3. +//#define AKIMBO_SEMI_DUAL_TOLERANCE + +#includelist //TAGGG - NEW diff --git a/src/shared/player.h b/src/shared/player.h index 98e49d1..0dddf37 100644 --- a/src/shared/player.h +++ b/src/shared/player.h @@ -125,6 +125,9 @@ class player:base_player // equipped. Not that it could ever change while not equipped anyway. int prev_forceBodygroup1Submodel; + // During a shell-eject event, what member of aryShellEjectData do I use for the model + // and hitsound script file to use? Set on setting the event + int iShellEjectType; // WEAPON KICKBACK STUFF. // Way it works is a little different from the average (Half-Life and Counterstrike). diff --git a/src/shared/powerup.h b/src/shared/powerup.h index faaa320..a16c371 100644 --- a/src/shared/powerup.h +++ b/src/shared/powerup.h @@ -53,7 +53,7 @@ typedef struct{ int typeID; string sDisplayName; int iSubmodelChoice; - void(void) vOnTouch; + void(void) funOnTouch; // SPECIFIC TO INSTANT EFFECT // ...nothing. Think about it, it's touched and it's gone. @@ -69,17 +69,17 @@ typedef struct{ int typeID; string sDisplayName; int iSubmodelChoice; - void(void) vOnTouch; + void(void) funOnTouch; // SPECIFIC TO USABLE // How long do I last once used? float fActiveDuration; // What do I do when used? Generally set some stat(s)/flag(s) to get the effect, // like telling bullets, player movement, etc. how much to be slowed down by for instance. - void(player pl) vOnUse; + void(player pl) funOnUse; // At the end of my duration, how do I reset the things I set to act as though nothing happened? // Should run on player death or disconnect (if necessary) too as to not leave lingering effects. - void(player pl) vOnEnd; + void(player pl) funOnEnd; // Note that we have no think effect. Nothing could be done frame-by-frame that would help // any of the powerups do what it needs to. Speed modifiers of any sort (slow-mo) can't force // nearby stuff to move slower directly, it sets a flag on use that tells physics to move that stuff diff --git a/src/shared/precache.qc b/src/shared/precache.qc index 2f6c15c..7d692cf 100644 --- a/src/shared/precache.qc +++ b/src/shared/precache.qc @@ -18,6 +18,9 @@ void SharedGame_Precache(void){ precache_model("models/powerup.mdl"); + // In FreeTS, looks like shell eject effects are precached both client & serverside + // (so here in shared/precache.qc is good). + // nearly identical..? precache_model("models/56_shell.mdl"); precache_model("models/556_shell.mdl"); @@ -34,7 +37,8 @@ void SharedGame_Precache(void){ // physics-related / slow-mo? precache_model("models/bullet.mdl"); precache_model("models/long_bullet.mdl"); - + + // some model for dirt effects? precache_model("models/pellet.mdl"); diff --git a/src/shared/weapons.h b/src/shared/weapons.h index fe1850c..3cbf53d 100644 --- a/src/shared/weapons.h +++ b/src/shared/weapons.h @@ -772,6 +772,7 @@ typedef struct{ //TODO. Is extern'ing these earlier possible? ammodata_t* ary_ammoData[AMMO_ID::LAST_ID]; +shellejectdata_t* ary_shellEjectData[SHELLEJECT_ID::LAST_ID]; //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). @@ -804,22 +805,28 @@ void weapon_base_onAttack(player pl, weapondata_basic_t* basePRef, weapondynamic void weapon_base_onAttack_multi(player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon, int shellCount, int attackTypeUsed); -void weapon_base_burstFire(player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon, int attackTypeUsed, int shotCount, float shotDelay); +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(void(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed) arg_funAttack); +void weapon_gun_akimbo_semi_secondaryAttack(void(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed) arg_funAttack); +void weapon_ironsight_akimbo_semi_secondaryAttack(void(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed) arg_funAttack, int arg_weaponTypeID); -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); +void weapon_gun_akimbo_full_primaryAttack(void(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed) arg_funAttack); +void weapon_gun_akimbo_full_secondaryAttack(void(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed) arg_funAttack); + +BOOL weapon_akimbo_semiAttackDualHack(player pl, weapondynamic_t arg_thisWeapon, int arg_flagger, void(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed) arg_funAttack); +BOOL weapon_akimbo_fullAttackDualHack(player pl, weapondynamic_t arg_thisWeapon, int arg_flagger, void(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed) arg_funAttack); +BOOL weapon_akimbo_AttackDualHack(player pl, weapondynamic_t arg_thisWeapon, int arg_flagger, void(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed) 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); -BOOL weapon_ironsight_ToggleIronsight(player pl, weapondata_ironsight_t* basePRef, weapondynamic_t arg_thisWeapon); +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 ); @@ -840,6 +847,8 @@ void weapon_gun_onDrawHUD(player pl, weapondata_gun_t* basePRef, weapondynamic_t 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_ejectShell(int arg_shellEjectType); + void weapon_precache(weapondata_basic_t* basePRef); //void weapon_gun_updateAmmo(player pl, weapondata_gun_t* basePRef, weapondynamic_t arg_thisWeapon); diff --git a/src/shared/weapons.qc b/src/shared/weapons.qc index dca3765..f031b0b 100644 --- a/src/shared/weapons.qc +++ b/src/shared/weapons.qc @@ -383,20 +383,21 @@ weapon_base_onAttack_multi(player pl, weapondata_basic_t* basePRef, weapondynami }// weapon_base_onAttack +// shotCount is how many consecutive shots to fire (no more than 3 expected), +// shotDelay is the time between them, and +// attackDelay is the time that must pass before firing is allowed again +// (as in left-click), not including the delays between shots after the 1st. void -weapon_base_burstFire( - player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon, - int attackTypeUsed, int shotCount, float shotDelay +weapon_gun_burstFire( + player pl, weapondata_gun_t* basePRef, weapondynamic_t arg_thisWeapon, + int attackTypeUsed, int shotCount, float shotDelay, float attackDelay ){ - weapondata_basic_t baseRef = *basePRef; - - float thatStuff = shotDelay * (shotCount-1) + baseRef.fAttackDelay; - weapon_base_setWholeAttackDelay(pl, thatStuff); + float totalAttackDelay = shotDelay * (shotCount-1) + attackDelay; + weapon_base_setWholeAttackDelay(pl, totalAttackDelay); - //printfline("??? %.2f ", thatStuff); pl.aryNextBurstShotTime_softLength = shotCount; for(int i = 0; i < shotCount; i++){ - pl.aryNextBurstShotTime[i] = thatStuff - shotDelay*(i); + pl.aryNextBurstShotTime[i] = totalAttackDelay - shotDelay*(i); //printfline("WELL #%i: %.2f", i, pl.aryNextBurstShotTime[i]); } @@ -405,7 +406,7 @@ weapon_base_burstFire( // and fire this very first frame. weapon_gun_fireBurstBullet(pl, basePRef, arg_thisWeapon); -}//weapon_base_burstFire +}//weapon_gun_burstFire @@ -620,10 +621,172 @@ weapon_shotgun_onThink_reloadLogic(player pl, weapondata_gun_t* basePRef, weapon +// Handles the primaryAttack method for akimbo weapons, mostly checking whether to +// use the semiAttackDualHack or skip straight to funAttack. +// arg_funAttack is what handles firing for the akimbo weapon, something like +// "weapon_socommk23_akimbo_attack". +// No need for a separate version for ironsight for primary, nothing different +// happens there. +void +weapon_gun_akimbo_semi_primaryAttack( + void(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed) arg_funAttack +){ + player pl = (player)self; + weapondynamic_t arg_thisWeapon = pl.ary_myWeapons[pl.inventoryEquippedIndex]; + + // reset + pl.akimboTest = 0; + +#ifndef AKIMBO_SEMI_DUAL_TOLERANCE + if(input_buttons & INPUT_BUTTON3){ + arg_funAttack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_BOTH); + }else{ + arg_funAttack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_LEFT); + } +#else + + // in addition to the primary input, which lead to '_primary' being called at all. + if(input_buttons & INPUT_BUTTON3){ + if(!weapon_akimbo_semiAttackDualHack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_BOTH, arg_funAttack)){ + // nothing unusual here. + pl.akimboTest = 0; + arg_funAttack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_BOTH); + }else{ + } + }else{ + if(!weapon_akimbo_semiAttackDualHack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_RIGHT, arg_funAttack)){ + arg_funAttack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_LEFT); + pl.akimboFirePrev = BITS_AKIMBOCHOICE_LEFT; + } + } +#endif +} + +// Same as above but for akimbo semi secondary, has a separate ironsight version that +// needs to be used by ironsights. +// That version also needs the weapon type ID given for the ironsight-toggle call +void +weapon_gun_akimbo_semi_secondaryAttack( + void(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed) arg_funAttack +){ + player pl = (player)self; + weapondynamic_t arg_thisWeapon = pl.ary_myWeapons[pl.inventoryEquippedIndex]; + + // reset + pl.akimboTest = 0; + +#ifndef AKIMBO_SEMI_DUAL_TOLERANCE + if(arg_thisWeapon.iFireModeAkimbo == BITS_FIREMODE_AKIMBO_SEMI_AUTO){ + // no ironsights, nothing to do here. + }else{ + // fires the right weapon always + arg_funAttack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_RIGHT); + } +#else + + // NOTE - holding primary is impossible, would've called _primary above if so. + // Only secondary could possibly be held (and, is). + if(arg_thisWeapon.iFireModeAkimbo == BITS_FIREMODE_AKIMBO_SEMI_AUTO){ + // no ironsights, nothing to do here. + }else{ + // fires the right weapon always + + //weapon_socommk23_akimbo_attack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_RIGHT); + //return; + + if(!weapon_akimbo_semiAttackDualHack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_LEFT, arg_funAttack)){ + arg_funAttack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_RIGHT); + pl.akimboFirePrev = BITS_AKIMBOCHOICE_RIGHT; + } + } +#endif +} + +void +weapon_ironsight_akimbo_semi_secondaryAttack( + void(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed) arg_funAttack, + int arg_weaponTypeID +){ + player pl = (player)self; + weapondynamic_t arg_thisWeapon = pl.ary_myWeapons[pl.inventoryEquippedIndex]; + + // reset + pl.akimboTest = 0; + +#ifndef AKIMBO_SEMI_DUAL_TOLERANCE + if(arg_thisWeapon.iFireModeAkimbo == BITS_FIREMODE_AKIMBO_SEMI_AUTO){ + // since secondary fire does nothing in semi-auto, we let it do ironsight stuff here + weapon_ironsight_ToggleIronsight(pl, (weapondata_ironsight_t*)ary_weaponData[arg_weaponTypeID], arg_thisWeapon); + }else{ + // fires the right weapon always + arg_funAttack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_RIGHT); + } +#else + // NOTE - holding primary is impossible, would've called _primary above if so. + // Only secondary could possibly be held (and, is). + if(arg_thisWeapon.iFireModeAkimbo == BITS_FIREMODE_AKIMBO_SEMI_AUTO){ + // since secondary fire does nothing in semi-auto, we let it do ironsight stuff here + weapon_ironsight_ToggleIronsight(pl, (weapondata_ironsight_t*)ary_weaponData[arg_weaponTypeID], arg_thisWeapon); + + }else{ + // fires the right weapon always + if(!weapon_akimbo_semiAttackDualHack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_LEFT, arg_funAttack)){ + arg_funAttack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_RIGHT); + pl.akimboFirePrev = BITS_AKIMBOCHOICE_RIGHT; + } + } +#endif +} + + + + + +// And now for full semi weapons (holding down the mouse fires continuously) +// They don't use the DUAL_TOLERANCE system regardless of the constant. +// Also, no ironsight version, that combo never happens. +void +weapon_gun_akimbo_full_primaryAttack( + void(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed) arg_funAttack +){ + player pl = (player)self; + weapondynamic_t arg_thisWeapon = pl.ary_myWeapons[pl.inventoryEquippedIndex]; + + pl.akimboTest = 0; + + if(input_buttons & INPUT_BUTTON3){ + arg_funAttack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_BOTH); + }else{ + // Only intent given inputs, firing both will still happen in + // the "Full-auto" firemode + arg_funAttack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_LEFT); + } +} + +void +weapon_gun_akimbo_full_secondaryAttack( + void(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed) arg_funAttack +){ + player pl = (player)self; + weapondynamic_t arg_thisWeapon = pl.ary_myWeapons[pl.inventoryEquippedIndex]; + + pl.akimboTest = 0; + + if(arg_thisWeapon.iFireModeAkimbo == BITS_FIREMODE_AKIMBO_FREE_FULL){ + arg_funAttack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_RIGHT); + //pl.akimboFirePrev = BITS_AKIMBOCHOICE_RIGHT; + } +} + + + + + + BOOL weapon_akimbo_AttackDualHack( player pl, weapondynamic_t arg_thisWeapon, int arg_flagger, - int* arg_akimboFireCallback + void(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed) arg_funAttack ){ //printfline("WELL WHAT. %.2f, %i, %i", pl.akimboDualFireToleranceTime, pl.akimboFirePrev, arg_flagger); if(arg_flagger == 0){ @@ -669,8 +832,10 @@ weapon_akimbo_AttackDualHack( // Could make a table to know what to use per akimbo weapon ID, having a table // with one space for every single weapon in the game seems pretty wasteful. // Calls like weapon_socommk23_akimbo_attack, etc. - BOOL(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed)* tempRef = arg_akimboFireCallback; - (*tempRef)(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_BOTH); + //BOOL(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed)* tempRef = arg_akimboFireCallback; + //(*tempRef)(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_BOTH); + + arg_funAttack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_BOTH); //printfline("I WENT, akprev:%i aktest:%i - flagg:%i", pl.akimboFirePrev, pl.akimboTest, arg_flagger); @@ -694,12 +859,12 @@ weapon_akimbo_AttackDualHack( BOOL weapon_akimbo_semiAttackDualHack( player pl, weapondynamic_t arg_thisWeapon, int arg_flagger, - int* arg_akimboFireCallback + void(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed) arg_funAttack ){ if(arg_thisWeapon.iFireModeAkimbo == BITS_FIREMODE_AKIMBO_SEMI_AUTO){ return FALSE; } - return weapon_akimbo_AttackDualHack(pl, arg_thisWeapon, arg_flagger, arg_akimboFireCallback); + return weapon_akimbo_AttackDualHack(pl, arg_thisWeapon, arg_flagger, arg_funAttack); } // WARNING! Don't do this, full-firing akimbos really don't need this, @@ -708,12 +873,12 @@ weapon_akimbo_semiAttackDualHack( BOOL weapon_akimbo_fullAttackDualHack( player pl, weapondynamic_t arg_thisWeapon, int arg_flagger, - int* arg_akimboFireCallback + void(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed) arg_funAttack ){ if(arg_thisWeapon.iFireModeAkimbo == BITS_FIREMODE_AKIMBO_FULL_AUTO){ return FALSE; } - return weapon_akimbo_AttackDualHack(pl, arg_thisWeapon, arg_flagger, arg_akimboFireCallback); + return weapon_akimbo_AttackDualHack(pl, arg_thisWeapon, arg_flagger, arg_funAttack); } @@ -1117,7 +1282,7 @@ weapon_akimbo_fullAttackChoice( }//weapon_akimbo_fullAttackChoice -BOOL +void weapon_ironsight_ToggleIronsight( player pl, weapondata_ironsight_t* basePRef, weapondynamic_t arg_thisWeapon @@ -1125,7 +1290,6 @@ weapon_ironsight_ToggleIronsight( //weapondata_ironsight_t* basePRef = (weapondata_ironsight_t*)ary_weaponData[WEAPON_ID::SOCOMMK23]; weapondata_ironsight_t baseRef = *basePRef; - // SEARCH ME!!! //arg_thisWeapon.iIronSight = 0; if(pl.isReloading == FALSE && pl.isChangingIronsight == FALSE){ @@ -1154,13 +1318,12 @@ weapon_ironsight_ToggleIronsight( //arg_thisWeapon.iIronSight = pl.recentAttackHadAmmo; //arg_thisWeapon.iIronSight = !arg_thisWeapon.iIronSight; - return TRUE; + return; }else{ printfline("time: %.2f weapon_ironsight_ToggleIronsight FAILED (%d, %d). current:%i", time, pl.isReloading, pl.isChangingIronsight, arg_thisWeapon.iIronSight); } - - return FALSE; + }// weapon_ironsight_ToggleIronsight @@ -1658,27 +1821,24 @@ weapon_melee_onDrawHUD(player pl, weapondata_melee_t* basePRef, weapondynamic_t -// SHELL SOUNDS: -// ts/sound/weapons/shell.wav -// ts/sound/weapons/sshell.wav -// ts/sound/weapons/sshell1.wav -// ts/sound/weapons/sshell2.wav -// ts/sound/weapons/sshell3.wav -// valve/sound/player/pl_shell1.wav -// valve/sound/player/pl_shell2.wav -// valve/sound/player/pl_shell3.wav -// ---- -// * sshell1, 2, and 3 are also found in the valve folder, these appear to be clones. -// * pl_shell ones are not cloned but can still be used -// * unknown if weapons/shell and sshell are used in original TS, may only be the -// 1,2,3 ones (shell#, sshell#) for most weapons and shotguns accordingly. - -// - - - - - +// Not to be confused with the clientside-only event "weapon_ejectShell_event". +// This is called by weapons to add the event, handles setting the shell-type global +// for it to see. If shell-ejects are done serverside, that would not be an amazing +// idea. Per-player would be better. +void weapon_ejectShell(int arg_shellEjectType){ + //ary_shellEjectData[arg_shellEjectType]... + +#ifdef CLIENT + player pl = (player)self; + pl.iShellEjectType = arg_shellEjectType; + View_AddEvent(w_ejectshell_pistol, 0.0f); +#else + // anything for the playermodel? Also only do that for all players except the + // localplayer if using a viewmodel. + // ...and already this is sounding more like a job for predraw, which does handle + // players rendering players other than themselves. And yes, still clientside. +#endif +} // Precache models and the HUD icon given in FreeTS weapondata. // Weapon sounds and anything else not in the struct shuold be precached @@ -1871,22 +2031,6 @@ setupWeaponData(void){ ///////////////////////////////////////////////////////// - ASSIGN_AMMODATA(NONE) - ASSIGN_AMMODATA(_9X19MM) - ASSIGN_AMMODATA(_45ACP) - ASSIGN_AMMODATA(_P50AE) - - ASSIGN_AMMODATA(_5P7X28) - - ASSIGN_AMMODATA(_10MMAUTO) - ASSIGN_AMMODATA(_P22LR) - ASSIGN_AMMODATA(_P454CASULL) - ASSIGN_AMMODATA(_5P56NATO) - ASSIGN_AMMODATA(_7P62X39MM) - ASSIGN_AMMODATA(_50BMG) - ASSIGN_AMMODATA(_SHELLS) - ASSIGN_AMMODATA(_32ACP) - ASSIGN_AMMODATA(_7P62X51MM) ASSIGN_WEAPONDATA(NONE, none) @@ -1955,10 +2099,39 @@ setupWeaponData(void){ ary_shotgunExtra[SHOTGUN_EXTRA_ID::BENELLIM3] = &weapon_benellim3_shotgunExtra; ary_shotgunExtra[SHOTGUN_EXTRA_ID::MOSSBERG500] = &weapon_mossberg500_shotgunExtra; ary_shotgunExtra[SHOTGUN_EXTRA_ID::MOSSBERG500_IRONSIGHT] = &weapon_mossberg500_shotgunExtra_ironsight; - ary_shotgunExtra[SHOTGUN_EXTRA_ID::SPAS12] = &weapon_spas12_shotgunExtra; + ASSIGN_AMMODATA(NONE) + ASSIGN_AMMODATA(_9X19MM) + ASSIGN_AMMODATA(_45ACP) + ASSIGN_AMMODATA(_P50AE) + + ASSIGN_AMMODATA(_5P7X28) + + ASSIGN_AMMODATA(_10MMAUTO) + ASSIGN_AMMODATA(_P22LR) + ASSIGN_AMMODATA(_P454CASULL) + ASSIGN_AMMODATA(_5P56NATO) + ASSIGN_AMMODATA(_7P62X39MM) + ASSIGN_AMMODATA(_50BMG) + ASSIGN_AMMODATA(_SHELLS) + ASSIGN_AMMODATA(_32ACP) + ASSIGN_AMMODATA(_7P62X51MM) + + + + ASSIGN_SHELLEJECTDATA(NONE) + ASSIGN_SHELLEJECTDATA(_56) + ASSIGN_SHELLEJECTDATA(_556) + ASSIGN_SHELLEJECTDATA(_22) + ASSIGN_SHELLEJECTDATA(_9MM) + ASSIGN_SHELLEJECTDATA(_GENERIC) + ASSIGN_SHELLEJECTDATA(_SHOTGUN) + ASSIGN_SHELLEJECTDATA(_SHOTGUN_BLUE) + ASSIGN_SHELLEJECTDATA(_SHOTGUN_GOLD) + + }//setupWeaponData @@ -2042,10 +2215,8 @@ getAmmoTypeOfWeapon(int arg_weaponID) -// check for being redundant with the events_custom.qc (whatever) ejectshell - like -// method! -// Could likely combine this better with that alternate way, but both should -// effectively do the exact same thing. + + // This is based off what the HL glock does, adjust with custom shell-choices per // different weapons that use them. // Is HL's "w_shotgun_ejectshell" even any different from this besides shell-model @@ -2056,20 +2227,33 @@ getAmmoTypeOfWeapon(int arg_weaponID) // Try testing FreeHL or FreeCS, do you see your own shells in thirdperson on firing // and (multiplayer) do other players see your shells on firing? -// (based off w_glock_ejectshell) +// TODO: rename to weapon_ejectShell_event #ifdef CLIENT void w_ejectshell_pistol(void) { - static void w_glock_ejectshell_death(void) { + + player pl = (player)pSeat->m_ePlayer; + + static void weapon_ejectshell_remove(void) { remove(self); } - static void w_glock_ejectshell_touch(void) { - if (other == world) + static void weapon_ejectshell_touch(void) { + if(other == world){ + // TODO, use custom Sound_Play(self, CHAN_BODY, "modelevent_shell.land"); + //shellejectdata_t* mySED = aryShellEjectData[pl.iShellEjectType]; + //Sound_Play(self, CHAN_BODY, (*mySED).sTouchSound); + } } + vector vOrigin; entity eShell = spawn(); + + // TODO, use custom setmodel(eShell, "models/shell.mdl"); + //shellejectdata_t* mySED2 = aryShellEjectData[pl.iShellEjectType]; + //setmodel(eShell, (*mySED2).sModelPath); + eShell.solid = SOLID_BBOX; eShell.movetype = MOVETYPE_BOUNCE; eShell.drawmask = MASK_ENGINE; @@ -2080,14 +2264,50 @@ w_ejectshell_pistol(void) eShell.velocity += (v_forward * 0); eShell.velocity += (v_right * 80); eShell.velocity += (v_up * 100); - eShell.touch = w_glock_ejectshell_touch; + + eShell.touch = weapon_ejectshell_touch; eShell.avelocity = [0,45,900]; - eShell.think = w_glock_ejectshell_death; + eShell.think = weapon_ejectshell_remove; eShell.nextthink = time + 2.5f; setsize(eShell, [0,0,0], [0,0,0]); - setorigin(eShell, pSeat->m_eViewModel.origin + (v_forward * 26) + (v_right * 8) + (v_up * -4)); -} + + + + // TODO: I think attachments supply a direction too, fuzzy on the details, + // player predraw (client/player.qc) definitely has something like that to put the + // viewmodel laser-start or flashlight sprite glow effect in the right place. + + // FreeHL way (forget all the rest if so) + vOrigin = pSeat->m_eViewModel.origin + (v_forward * 26) + (v_right * 8) + (v_up * -4); + + /* + // way #1 + //vOrigin = pSeat->m_eViewModel.origin; + // way #2: old codebase way? + //vOrigin = pSeat->m_vecPredictedOrigin + [0, 0, getstatf(STAT_VIEWHEIGHT)]; + + // way #3 + // "pSeat->m_iVMBones + 1" gets the first attachment, add more to get other + // attachments, or places on the model that can be helpful to tie into + // Although this is still making shell ejections happen at the end of the muzzle + // and the other attachments just go further out? + vector vOffset = gettaginfo(pSeat->m_eViewModel, pSeat->m_iVMBones + 1); + printfline("WHAT?! %.2f %.2f %.2f", vOffset[0], vOffset[1], vOffset[2]); + + // way #3a + // assumes a vOrigin provided by earlier + //vOrigin += (v_forward * vOffset[0]); + //vOrigin += (v_right * -vOffset[1]); + //vOrigin += (v_up * vOffset[2]) ; + + // way #3b + // or only be vOffset + vOrigin = vOffset; + */ + setorigin(eShell, vOrigin); + +}//weapon_ejectShell_event // also clientside only, dealing with configs diff --git a/src/shared/weapons/weapon_akimbocolts.qc b/src/shared/weapons/weapon_akimbocolts.qc index b4997dc..96c8f2c 100644 --- a/src/shared/weapons/weapon_akimbocolts.qc +++ b/src/shared/weapons/weapon_akimbocolts.qc @@ -131,7 +131,7 @@ w_akimbocolts_holster(void) // Akimbo weapons consistently. // Putting it here avoids duplicating a bunch of code. // Also, "attackTypeUsed" is whether primary (FALSE) or secondary (TRUE) lead to this point. -BOOLEAN weapon_akimbocolts_akimbo_attack(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed){ +void weapon_akimbocolts_akimbo_attack(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed){ float randomChoice; //weapondynamic_t arg_thisWeapon = pl.ary_myWeapons[pl.inventoryEquippedIndex]; @@ -148,16 +148,11 @@ BOOLEAN weapon_akimbocolts_akimbo_attack(player pl, weapondynamic_t arg_thisWeap // because I am not copy/pasting this monstrosity 5 times. finalAkimboChoice = weapon_akimbo_semiAttackChoice(pl, ary_weaponData[WEAPON_ID::AKIMBOCOLTS], arg_thisWeapon, attackTypeUsed); -#ifdef CLIENT - SAVE_STATE(pl.nextAkimboAttackPreference); -#endif - if(finalAkimboChoice == -1){ //pl.akimboFirePrev = 0; - return FALSE; + return; } - if(pl.recentAttackHadAmmo == FALSE){ if((finalAkimboChoice & BITS_AKIMBOCHOICE_LEFT)){ PLAY_CLICK_SOUND_LEFT @@ -165,14 +160,14 @@ BOOLEAN weapon_akimbocolts_akimbo_attack(player pl, weapondynamic_t arg_thisWeap if((finalAkimboChoice & BITS_AKIMBOCHOICE_RIGHT)){ PLAY_CLICK_SOUND_RIGHT } - return FALSE; + return; } // ?? Is this even possible? if(finalAkimboChoice == 0){ //pl.akimboFirePrev = 0; - return FALSE; + return; } // Use me for things the recent firing round already did to avoid redundancy. @@ -185,16 +180,12 @@ BOOLEAN weapon_akimbocolts_akimbo_attack(player pl, weapondynamic_t arg_thisWeap weapon_base_onAttack(pl, ary_weaponData[WEAPON_ID::AKIMBOCOLTS], arg_thisWeapon, effectiveAkimboChoice); -#if 0 if(effectiveAkimboChoice & BITS_AKIMBOCHOICE_LEFT){ - TS_Weapons_PlaySoundDirect(pl, "weapons/gold/gold-fire.wav"); + SoundPitched_Send(pl, SNDP_AKIMBOCOLTS_FIRE); } if(effectiveAkimboChoice & BITS_AKIMBOCHOICE_RIGHT){ - TS_Weapons_PlaySoundDirect(pl, "weapons/gold/gold-fire.wav"); + SoundPitched_Send(pl, SNDP_AKIMBOCOLTS_FIRE); } -#else - SoundPitched_Send(pl, SNDP_AKIMBOCOLTS_FIRE); -#endif if(pl.akimboTest == 0 && !(finalAkimboChoice == BITS_AKIMBOCHOICE_BOTH)){ @@ -262,62 +253,20 @@ BOOLEAN weapon_akimbocolts_akimbo_attack(player pl, weapondynamic_t arg_thisWeap weapon_base_setWholeAttackDelay(pl, (*ary_weaponData[pl.activeweapon]).fAttackDelay * 1); } - return TRUE; -}//END OF weapon_akimbocolts_akimbo_attack +}// weapon_akimbocolts_akimbo_attack void w_akimbocolts_primary(void) { - player pl = (player)self; - weapondynamic_t arg_thisWeapon = pl.ary_myWeapons[pl.inventoryEquippedIndex]; - - // reset - pl.akimboTest = 0; - - // in addition to the primary input, which lead to '_primary' being called at all. - if(input_buttons & INPUT_BUTTON3){ - if(!weapon_akimbo_semiAttackDualHack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_BOTH, &weapon_akimbocolts_akimbo_attack)){ - // nothing unusual here. - pl.akimboTest = 0; - weapon_akimbocolts_akimbo_attack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_BOTH); - }else{ - } - }else{ - if(!weapon_akimbo_semiAttackDualHack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_RIGHT, &weapon_akimbocolts_akimbo_attack)){ - weapon_akimbocolts_akimbo_attack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_LEFT); - pl.akimboFirePrev = BITS_AKIMBOCHOICE_LEFT; - } - - } - + weapon_gun_akimbo_semi_primaryAttack(weapon_akimbocolts_akimbo_attack); } void w_akimbocolts_secondary(void) { - player pl = (player)self; - weapondynamic_t arg_thisWeapon = pl.ary_myWeapons[pl.inventoryEquippedIndex]; - - // reset - pl.akimboTest = 0; - - // NOTE - holding primary is impossible, would've called _primary above if so. - // Only secondary could possibly be held (and, is). - if(arg_thisWeapon.iFireModeAkimbo == BITS_FIREMODE_AKIMBO_SEMI_AUTO){ - // no ironsights, nothing to do here. - }else{ - // fires the right weapon always - - //weapon_akimbocolts_akimbo_attack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_RIGHT); - //return; - - if(!weapon_akimbo_semiAttackDualHack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_LEFT, &weapon_akimbocolts_akimbo_attack)){ - weapon_akimbocolts_akimbo_attack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_RIGHT); - pl.akimboFirePrev = BITS_AKIMBOCHOICE_RIGHT; - } - } + weapon_gun_akimbo_semi_secondaryAttack(weapon_akimbocolts_akimbo_attack); } diff --git a/src/shared/weapons/weapon_barrettm82.qc b/src/shared/weapons/weapon_barrettm82.qc index 2ebcc82..8cf639f 100644 --- a/src/shared/weapons/weapon_barrettm82.qc +++ b/src/shared/weapons/weapon_barrettm82.qc @@ -141,7 +141,8 @@ w_barrettm82_primary(void) } SoundPitched_Send(pl, SNDP_BARRETTM82_FIRE); - + + randomChoice = random(); if(randomChoice < 0.5){ TS_Weapons_ViewAnimation(weaponseq_barrettm82::shoot, 31.0f/30.0f); }else{ diff --git a/src/shared/weapons/weapon_beretta_akimbo.qc b/src/shared/weapons/weapon_beretta_akimbo.qc index cc29da6..60a28c6 100644 --- a/src/shared/weapons/weapon_beretta_akimbo.qc +++ b/src/shared/weapons/weapon_beretta_akimbo.qc @@ -153,7 +153,7 @@ w_beretta_akimbo_holster(void) // Akimbo weapons consistently. // Putting it here avoids duplicating a bunch of code. // Also, "attackTypeUsed" is whether primary (FALSE) or secondary (TRUE) lead to this point. -BOOLEAN weapon_beretta_akimbo_attack(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed){ +void weapon_beretta_akimbo_attack(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed){ float randomChoice; //weapondynamic_t arg_thisWeapon = pl.ary_myWeapons[pl.inventoryEquippedIndex]; @@ -170,16 +170,11 @@ BOOLEAN weapon_beretta_akimbo_attack(player pl, weapondynamic_t arg_thisWeapon, // because I am not copy/pasting this monstrosity 5 times. finalAkimboChoice = weapon_akimbo_semiAttackChoice(pl, ary_weaponData[WEAPON_ID::BERETTA_AKIMBO], arg_thisWeapon, attackTypeUsed); -#ifdef CLIENT - SAVE_STATE(pl.nextAkimboAttackPreference); -#endif - if(finalAkimboChoice == -1){ //pl.akimboFirePrev = 0; - return FALSE; + return; } - if(pl.recentAttackHadAmmo == FALSE){ if((finalAkimboChoice & BITS_AKIMBOCHOICE_LEFT)){ PLAY_CLICK_SOUND_LEFT @@ -187,14 +182,14 @@ BOOLEAN weapon_beretta_akimbo_attack(player pl, weapondynamic_t arg_thisWeapon, if((finalAkimboChoice & BITS_AKIMBOCHOICE_RIGHT)){ PLAY_CLICK_SOUND_RIGHT } - return FALSE; + return; } // ?? Is this even possible? if(finalAkimboChoice == 0){ //pl.akimboFirePrev = 0; - return FALSE; + return; } // Use me for things the recent firing round already did to avoid redundancy. @@ -313,63 +308,20 @@ BOOLEAN weapon_beretta_akimbo_attack(player pl, weapondynamic_t arg_thisWeapon, weapon_base_setWholeAttackDelay(pl, (*ary_weaponData[pl.activeweapon]).fAttackDelay * 1); } - return TRUE; -}//END OF weapon_beretta_akimbo_attack +}// weapon_beretta_akimbo_attack void w_beretta_akimbo_primary(void) { - player pl = (player)self; - weapondynamic_t arg_thisWeapon = pl.ary_myWeapons[pl.inventoryEquippedIndex]; - - // reset - pl.akimboTest = 0; - - // in addition to the primary input, which lead to '_primary' being called at all. - if(input_buttons & INPUT_BUTTON3){ - if(!weapon_akimbo_semiAttackDualHack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_BOTH, &weapon_beretta_akimbo_attack)){ - // nothing unusual here. - pl.akimboTest = 0; - weapon_beretta_akimbo_attack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_BOTH); - }else{ - } - }else{ - if(!weapon_akimbo_semiAttackDualHack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_RIGHT, &weapon_beretta_akimbo_attack)){ - weapon_beretta_akimbo_attack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_LEFT); - pl.akimboFirePrev = BITS_AKIMBOCHOICE_LEFT; - } - - } - + weapon_gun_akimbo_semi_primaryAttack(weapon_beretta_akimbo_attack); } void w_beretta_akimbo_secondary(void) { - player pl = (player)self; - weapondynamic_t arg_thisWeapon = pl.ary_myWeapons[pl.inventoryEquippedIndex]; - - // reset - pl.akimboTest = 0; - - // NOTE - holding primary is impossible, would've called _primary above if so. - // Only secondary could possibly be held (and, is). - if(arg_thisWeapon.iFireModeAkimbo == BITS_FIREMODE_AKIMBO_SEMI_AUTO){ - // no ironsights, nothing to do here. - }else{ - // fires the right weapon always - - //weapon_beretta_akimbo_attack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_RIGHT); - //return; - - if(!weapon_akimbo_semiAttackDualHack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_LEFT, &weapon_beretta_akimbo_attack)){ - weapon_beretta_akimbo_attack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_RIGHT); - pl.akimboFirePrev = BITS_AKIMBOCHOICE_RIGHT; - } - } - + weapon_gun_akimbo_semi_secondaryAttack(weapon_beretta_akimbo_attack); } void diff --git a/src/shared/weapons/weapon_fiveseven_akimbo.qc b/src/shared/weapons/weapon_fiveseven_akimbo.qc index 22b8871..c248df2 100644 --- a/src/shared/weapons/weapon_fiveseven_akimbo.qc +++ b/src/shared/weapons/weapon_fiveseven_akimbo.qc @@ -119,8 +119,6 @@ w_fiveseven_akimbo_holster(void) -var int leftCount = 0; -var int rightCount = 0; // General attack method to be called by primary or secondary fire as needed. // The firemode used determines whether only pressing primary fire works (alternate b/w @@ -128,7 +126,7 @@ var int rightCount = 0; // Akimbo weapons consistently. // Putting it here avoids duplicating a bunch of code. // Also, "attackTypeUsed" is whether primary (FALSE) or secondary (TRUE) lead to this point. -BOOLEAN weapon_fiveseven_akimbo_attack(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed){ +void weapon_fiveseven_akimbo_attack(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed){ //weapondynamic_t arg_thisWeapon = pl.ary_myWeapons[pl.inventoryEquippedIndex]; //special case @@ -144,16 +142,11 @@ BOOLEAN weapon_fiveseven_akimbo_attack(player pl, weapondynamic_t arg_thisWeapon // because I am not copy/pasting this monstrosity 5 times. finalAkimboChoice = weapon_akimbo_semiAttackChoice(pl, ary_weaponData[WEAPON_ID::FIVESEVEN_AKIMBO], arg_thisWeapon, attackTypeUsed); -#ifdef CLIENT - SAVE_STATE(pl.nextAkimboAttackPreference); -#endif - if(finalAkimboChoice == -1){ //pl.akimboFirePrev = 0; - return FALSE; + return; } - /* // DEBUG if(finalAkimboChoice > 0){ @@ -167,26 +160,17 @@ BOOLEAN weapon_fiveseven_akimbo_attack(player pl, weapondynamic_t arg_thisWeapon if((finalAkimboChoice & BITS_AKIMBOCHOICE_RIGHT)){ PLAY_CLICK_SOUND_RIGHT } - return FALSE; + return; } // ?? Is this even possible? if(finalAkimboChoice == 0){ //pl.akimboFirePrev = 0; - return FALSE; + return; } - // DEBUG!!! - if((finalAkimboChoice & BITS_AKIMBOCHOICE_LEFT)){ - leftCount++; - } - if((finalAkimboChoice & BITS_AKIMBOCHOICE_RIGHT)){ - rightCount++; - } - printfline("COUNTS! %i %i", leftCount, rightCount); - // Use me for things the recent firing round already did to avoid redundancy. // That is, if left-click was pressed a fraction of a second ago and then right-click // to force leading here to play the dual-fire anim, no need to do the muzzle flash, @@ -268,63 +252,20 @@ BOOLEAN weapon_fiveseven_akimbo_attack(player pl, weapondynamic_t arg_thisWeapon weapon_base_setWholeAttackDelay(pl, (*ary_weaponData[pl.activeweapon]).fAttackDelay * 1); } - return TRUE; -}//END OF weapon_fiveseven_akimbo_attack +}// weapon_fiveseven_akimbo_attack void w_fiveseven_akimbo_primary(void) { - player pl = (player)self; - weapondynamic_t arg_thisWeapon = pl.ary_myWeapons[pl.inventoryEquippedIndex]; - - // reset - pl.akimboTest = 0; - - // in addition to the primary input, which lead to '_primary' being called at all. - if(input_buttons & INPUT_BUTTON3){ - if(!weapon_akimbo_semiAttackDualHack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_BOTH, &weapon_fiveseven_akimbo_attack)){ - // nothing unusual here. - pl.akimboTest = 0; - weapon_fiveseven_akimbo_attack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_BOTH); - }else{ - } - }else{ - if(!weapon_akimbo_semiAttackDualHack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_RIGHT, &weapon_fiveseven_akimbo_attack)){ - weapon_fiveseven_akimbo_attack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_LEFT); - pl.akimboFirePrev = BITS_AKIMBOCHOICE_LEFT; - } - - } - + weapon_gun_akimbo_semi_primaryAttack(weapon_fiveseven_akimbo_attack); } void w_fiveseven_akimbo_secondary(void) { - player pl = (player)self; - weapondynamic_t arg_thisWeapon = pl.ary_myWeapons[pl.inventoryEquippedIndex]; - - // reset - pl.akimboTest = 0; - - // NOTE - holding primary is impossible, would've called _primary above if so. - // Only secondary could possibly be held (and, is). - if(arg_thisWeapon.iFireModeAkimbo == BITS_FIREMODE_AKIMBO_SEMI_AUTO){ - // no ironsight. - }else{ - // fires the right weapon always - - //weapon_fiveseven_akimbo_attack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_RIGHT); - //return; - - if(!weapon_akimbo_semiAttackDualHack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_LEFT, &weapon_fiveseven_akimbo_attack)){ - weapon_fiveseven_akimbo_attack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_RIGHT); - pl.akimboFirePrev = BITS_AKIMBOCHOICE_RIGHT; - } - } - + weapon_gun_akimbo_semi_secondaryAttack(weapon_fiveseven_akimbo_attack); } void diff --git a/src/shared/weapons/weapon_glock18.qc b/src/shared/weapons/weapon_glock18.qc index cd4bc9d..f3a6798 100644 --- a/src/shared/weapons/weapon_glock18.qc +++ b/src/shared/weapons/weapon_glock18.qc @@ -176,12 +176,14 @@ w_glock18_primary(void) #ifdef CLIENT View_ShowMuzzleflash(MUZZLE_SMALL); - // Why even be an event? Sometimes it happens, sometimes it doesn't? - // shell ejection can happen instantly in the weapon_base_onAttack call - // further down anyway + View_AddEvent(w_ejectshell_pistol, 0.0f); #endif + // TODO: replace View_AddEvent + weapon_ejectShell(SHELLEJECT_ID::_9MM); + + weapon_base_onAttack(pl, ary_weaponData[WEAPON_ID::GLOCK18], arg_thisWeapon, BITS_AKIMBOCHOICE_LEFT); // nothing too special for that. diff --git a/src/shared/weapons/weapon_karate.qc b/src/shared/weapons/weapon_karate.qc index 342e4ec..3154da3 100644 --- a/src/shared/weapons/weapon_karate.qc +++ b/src/shared/weapons/weapon_karate.qc @@ -182,7 +182,7 @@ w_karate_primary(void) // moved to a method so that early termination does not stop too much. -void w_karate_determineSecondaryAttack(MELEE_HIT_RESPONSE* hitRep, int* meleeAnimToPlay){ +void w_karate_determineSecondaryAttack(MELEE_HIT_RESPONSE& hitRep, int& meleeAnimToPlay){ player pl = (player)self; weapondynamic_t arg_thisWeapon = pl.ary_myWeapons[pl.inventoryEquippedIndex]; float curSpeed; @@ -192,8 +192,8 @@ void w_karate_determineSecondaryAttack(MELEE_HIT_RESPONSE* hitRep, int* meleeAni if(input_buttons & INPUT_BUTTON8){ //crouching? //spin kick - (*meleeAnimToPlay) = 1; - (*hitRep) = weapon_base_onPrimaryAttack_melee(pl, ary_weaponData[WEAPON_ID::KARATE], arg_thisWeapon, 40 * pl.fKarateStamina, 72); + meleeAnimToPlay = 1; + hitRep = weapon_base_onPrimaryAttack_melee(pl, ary_weaponData[WEAPON_ID::KARATE], arg_thisWeapon, 40 * pl.fKarateStamina, 72); weapon_base_setWholeAttackDelay(pl, 1); pl.fMoveBlockDelay = time + 1; pl.fKarateStamina = bound(0, pl.fKarateStamina - 0.25, 1); @@ -213,8 +213,8 @@ void w_karate_determineSecondaryAttack(MELEE_HIT_RESPONSE* hitRep, int* meleeAni if(dotproduct(_2d_dir, velocity_dir) <= -0.7 && GET_VIEW_ANGLES.x >= -55 && GET_VIEW_ANGLES.x <= 55){ // moving back-kick - (*meleeAnimToPlay) = 2; - (*hitRep) = weapon_base_onPrimaryAttack_melee_fromCustomDirection(pl, ary_weaponData[WEAPON_ID::KARATE], arg_thisWeapon, 30 * pl.fKarateStamina, 76, -v_forward); + meleeAnimToPlay = 2; + hitRep = weapon_base_onPrimaryAttack_melee_fromCustomDirection(pl, ary_weaponData[WEAPON_ID::KARATE], arg_thisWeapon, 30 * pl.fKarateStamina, 76, -v_forward); weapon_base_setWholeAttackDelay(pl, 1); pl.fMoveBlockDelay = time + 1; //TAGGG - NOTE. Why is this stamina-loss in original TS so high? @@ -224,8 +224,8 @@ void w_karate_determineSecondaryAttack(MELEE_HIT_RESPONSE* hitRep, int* meleeAni pl.fKarateStamina = bound(0, pl.fKarateStamina - 0.40, 1); }else{ //moving-kick - (*meleeAnimToPlay) = 0; - (*hitRep) = weapon_base_onPrimaryAttack_melee_fromCustomDirection(pl, ary_weaponData[WEAPON_ID::KARATE], arg_thisWeapon, 30 * pl.fKarateStamina, 74, v_forward); + meleeAnimToPlay = 0; + hitRep = weapon_base_onPrimaryAttack_melee_fromCustomDirection(pl, ary_weaponData[WEAPON_ID::KARATE], arg_thisWeapon, 30 * pl.fKarateStamina, 74, v_forward); weapon_base_setWholeAttackDelay(pl, 0.53); pl.fMoveBlockDelay = time + 0.46; pl.fKarateStamina = bound(0, pl.fKarateStamina - 0.16, 1); @@ -237,8 +237,8 @@ void w_karate_determineSecondaryAttack(MELEE_HIT_RESPONSE* hitRep, int* meleeAni if(input_movevalues.x < -40 && GET_VIEW_ANGLES.x >= -55 && GET_VIEW_ANGLES.x <= 55){ //standing back-kick. makevectors(GET_VIEW_ANGLES); - (*meleeAnimToPlay) = 2; - (*hitRep) = weapon_base_onPrimaryAttack_melee_fromCustomDirection(pl, ary_weaponData[WEAPON_ID::KARATE], arg_thisWeapon, 30 * pl.fKarateStamina, 74, -v_forward); + meleeAnimToPlay = 2; + hitRep = weapon_base_onPrimaryAttack_melee_fromCustomDirection(pl, ary_weaponData[WEAPON_ID::KARATE], arg_thisWeapon, 30 * pl.fKarateStamina, 74, -v_forward); weapon_base_setWholeAttackDelay(pl, 1); pl.fMoveBlockDelay = time + 1; pl.fKarateStamina = bound(0, pl.fKarateStamina - 0.3, 1); @@ -247,8 +247,8 @@ void w_karate_determineSecondaryAttack(MELEE_HIT_RESPONSE* hitRep, int* meleeAni // DEFAULT: nothing special then. - (*meleeAnimToPlay) = 0; - (*hitRep) = weapon_base_onPrimaryAttack_melee(pl, ary_weaponData[WEAPON_ID::KARATE], arg_thisWeapon, 30 * pl.fKarateStamina, 66); + meleeAnimToPlay = 0; + hitRep = weapon_base_onPrimaryAttack_melee(pl, ary_weaponData[WEAPON_ID::KARATE], arg_thisWeapon, 30 * pl.fKarateStamina, 66); weapon_base_setWholeAttackDelay(pl, 0.53); pl.fMoveBlockDelay = time + 0.46; @@ -266,7 +266,10 @@ w_karate_secondary(void) player pl = (player)self; weapondynamic_t arg_thisWeapon = pl.ary_myWeapons[pl.inventoryEquippedIndex]; float randomChoice; - MELEE_HIT_RESPONSE hitRep; + // a warning if this isn't defaulted, really? + // The whole point of being sent as a reference in determineSecondaryAttack is + // to give it a value though, I think this FTE warning is wrong, but satisfying anyway + MELEE_HIT_RESPONSE hitRep = MELEE_HIT_RESPONSE::NONE; int meleeAnimToPlay = 0; if(pl.w_attack_next > 0){ @@ -279,7 +282,7 @@ w_karate_secondary(void) // TODO - base karate melee damage? I forget. - w_karate_determineSecondaryAttack(&hitRep, &meleeAnimToPlay); + w_karate_determineSecondaryAttack(hitRep, meleeAnimToPlay); //pl.fUncrouchBlockDelay = time + 1.0f; //Animation_ShootWeapon( self ); diff --git a/src/shared/weapons/weapon_m16a4.qc b/src/shared/weapons/weapon_m16a4.qc index bc11bee..e73fe4e 100644 --- a/src/shared/weapons/weapon_m16a4.qc +++ b/src/shared/weapons/weapon_m16a4.qc @@ -150,12 +150,21 @@ w_m16a4_primary(void) INPUT_PRIMARY_TAP_GATE } + if( + pl.aryNextBurstShotTime_listenIndex != -1 && + arg_thisWeapon.iFireMode != BITS_FIREMODE_NONE + ){ + // the player is trying to manually fire while burst-fire is in the middle + // of sending shots? STOP + return; + } + if (!arg_thisWeapon.iClipLeft || WEAPON_UNDERWATER_CHECK) { PLAY_CLICK_SOUND return; } - SoundPitched_Send(pl, SNDP_M16A4_FIRE); + SoundPitched_Send(pl, SNDP_M16A4_FIRE); if(!arg_thisWeapon.iIronSight){ randomChoice = random(); @@ -190,17 +199,7 @@ w_m16a4_primary(void) if(arg_thisWeapon.iFireMode == BITS_FIREMODE_BURST) { - /* -#ifdef SERVER - weapon_base_burstFire(pl, ary_weaponData[WEAPON_ID::M16A4], arg_thisWeapon, BITS_AKIMBOCHOICE_LEFT, 3, 0.11); - // signal for server logic... for now. - return FALSE; -#else - weapon_base_onAttack(pl, ary_weaponData[WEAPON_ID::M16A4], arg_thisWeapon, BITS_AKIMBOCHOICE_LEFT); -#endif - */ - - weapon_base_burstFire(pl, ary_weaponData[WEAPON_ID::M16A4], arg_thisWeapon, BITS_AKIMBOCHOICE_LEFT, 3, 0.02); + weapon_gun_burstFire(pl, (weapondata_gun_t*)ary_weaponData[WEAPON_ID::M16A4], arg_thisWeapon, BITS_AKIMBOCHOICE_LEFT, 3, 0.02, 0.18); } else if(arg_thisWeapon.iFireMode == BITS_FIREMODE_SEMI) { diff --git a/src/shared/weapons/weapon_m61grenade.qc b/src/shared/weapons/weapon_m61grenade.qc index da5147e..29f9b1a 100644 --- a/src/shared/weapons/weapon_m61grenade.qc +++ b/src/shared/weapons/weapon_m61grenade.qc @@ -7,8 +7,8 @@ enum weaponseq_m61grenade{ throw_slide }; -BOOL weapon_grenade_onInputPress(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed); -//BOOL weapon_grenade_onInputRelease(player pl, weapondynamic_t arg_thisWeapon); +void weapon_grenade_onInputPress(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed); +//void weapon_grenade_onInputRelease(player pl, weapondynamic_t arg_thisWeapon); void weapon_m61grenade_onPrimaryAttackRelease(player pl, weapondynamic_t arg_thisWeapon){ @@ -269,7 +269,7 @@ weapondata_throwable_t weapon_m61grenade = -BOOL weapon_grenade_onInputPress(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed){ +void weapon_grenade_onInputPress(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed){ if(arg_thisWeapon.iCount == 0){ // what. how. @@ -302,7 +302,7 @@ BOOL weapon_grenade_onInputPress(player pl, weapondynamic_t arg_thisWeapon, int } } - return TRUE; + return; } @@ -315,7 +315,7 @@ BOOL weapon_grenade_onInputPress(player pl, weapondynamic_t arg_thisWeapon, int // It makes far more sense to just check for either input still being held-down in the think // method during the pullpin grenade phase. /* -BOOLEAN weapon_grenade_onInputRelease(player pl, weapondynamic_t arg_thisWeapon){ +void weapon_grenade_onInputRelease(player pl, weapondynamic_t arg_thisWeapon){ if(pl.w_attack_next > 0){ // wait for w_attack_next to expire before doing logic against grenadeFireIndex choice // (except above, checks a bit differently for spawning the grenade) diff --git a/src/shared/weapons/weapon_miniuzi_akimbo.qc b/src/shared/weapons/weapon_miniuzi_akimbo.qc index ea63be4..f7fd2ab 100644 --- a/src/shared/weapons/weapon_miniuzi_akimbo.qc +++ b/src/shared/weapons/weapon_miniuzi_akimbo.qc @@ -41,7 +41,6 @@ void weapon_miniuzi_akimbo_onColdCock(player pl, weapondynamic_t arg_thisWeapon) } -//weapondata_ironsight_t weapon_miniuzi_akimbo = weapondata_gun_t weapon_miniuzi_akimbo = { WEAPONDATA_TYPEID_GUN, @@ -79,18 +78,7 @@ weapondata_gun_t weapon_miniuzi_akimbo = 1, -1, -1, - -1/*, - { - weaponseq_miniuzi_akimbo::change, - 21.0f/60.0f, - weaponseq_miniuzi_akimbo::rechange, - 21.0f/60.0f, - weaponseq_miniuzi_akimbo::idleb, - weaponseq_miniuzi_akimbo::reloadb, - 76.0f/30.0f, - {0.030000, 2.000000, 0.005000} - } - */ + -1 }; @@ -150,15 +138,13 @@ w_miniuzi_akimbo_holster(void) } - - // General attack method to be called by primary or secondary fire as needed. // The firemode used determines whether only pressing primary fire works (alternate b/w // the Akimbo weapons with each shot), or primary & secondary control the left/right // Akimbo weapons consistently. // Putting it here avoids duplicating a bunch of code. // Also, "attackTypeUsed" is whether primary (FALSE) or secondary (TRUE) lead to this point. -BOOLEAN weapon_miniuzi_akimbo_attack(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed){ +void weapon_miniuzi_akimbo_attack(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed){ float randomChoice; int finalAkimboChoice = BITS_AKIMBOCHOICE_NONE; //default @@ -172,11 +158,9 @@ BOOLEAN weapon_miniuzi_akimbo_attack(player pl, weapondynamic_t arg_thisWeapon, //because I am not copy/pasting this monstrosity 5 times. finalAkimboChoice = weapon_akimbo_fullAttackChoice(pl, ary_weaponData[WEAPON_ID::MINIUZI_AKIMBO], arg_thisWeapon, attackTypeUsed); - SAVE_STATE(pl.nextAkimboAttackPreference); - if(finalAkimboChoice == -1){ //pl.akimboFirePrev = 0; - return FALSE; + return; } /* @@ -193,13 +177,13 @@ BOOLEAN weapon_miniuzi_akimbo_attack(player pl, weapondynamic_t arg_thisWeapon, if((finalAkimboChoice & BITS_AKIMBOCHOICE_RIGHT)){ PLAY_CLICK_SOUND_RIGHT } - return FALSE; + return; } // ?? Is this even possible? if(finalAkimboChoice == 0){ //pl.akimboFirePrev = 0; - return FALSE; + return; } @@ -279,23 +263,13 @@ BOOLEAN weapon_miniuzi_akimbo_attack(player pl, weapondynamic_t arg_thisWeapon, weapon_base_setWholeAttackDelay(pl, (*ary_weaponData[pl.activeweapon]).fAttackDelay * 1); } - return TRUE; -}//END OF weapon_miniuzi_akimbo_attack +}// weapon_miniuzi_akimbo_attack void w_miniuzi_akimbo_primary(void) { - player pl = (player)self; - weapondynamic_t arg_thisWeapon = pl.ary_myWeapons[pl.inventoryEquippedIndex]; - - pl.akimboTest = 0; - - if(input_buttons & INPUT_BUTTON3){ - weapon_miniuzi_akimbo_attack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_BOTH); - }else{ - weapon_miniuzi_akimbo_attack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_LEFT); - } + weapon_gun_akimbo_full_primaryAttack(weapon_miniuzi_akimbo_attack); } @@ -303,16 +277,7 @@ w_miniuzi_akimbo_primary(void) void w_miniuzi_akimbo_secondary(void) { - player pl = (player)self; - weapondynamic_t arg_thisWeapon = pl.ary_myWeapons[pl.inventoryEquippedIndex]; - - // reset - pl.akimboTest = 0; - - if(arg_thisWeapon.iFireModeAkimbo == BITS_FIREMODE_AKIMBO_FREE_FULL){ - weapon_miniuzi_akimbo_attack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_RIGHT); - //pl.akimboFirePrev = BITS_AKIMBOCHOICE_RIGHT; - } + weapon_gun_akimbo_full_secondaryAttack(weapon_miniuzi_akimbo_attack); } diff --git a/src/shared/weapons/weapon_mossberg500.qc b/src/shared/weapons/weapon_mossberg500.qc index e0d80a6..9f0ca55 100644 --- a/src/shared/weapons/weapon_mossberg500.qc +++ b/src/shared/weapons/weapon_mossberg500.qc @@ -276,7 +276,7 @@ w_mossberg500_secondary(void) } */ - return weapon_ironsight_ToggleIronsight(pl, (weapondata_ironsight_t*)ary_weaponData[WEAPON_ID::MOSSBERG500], arg_thisWeapon); + weapon_ironsight_ToggleIronsight(pl, (weapondata_ironsight_t*)ary_weaponData[WEAPON_ID::MOSSBERG500], arg_thisWeapon); } diff --git a/src/shared/weapons/weapon_mp5k.qc b/src/shared/weapons/weapon_mp5k.qc index 178d732..19dd05e 100644 --- a/src/shared/weapons/weapon_mp5k.qc +++ b/src/shared/weapons/weapon_mp5k.qc @@ -151,6 +151,15 @@ w_mp5k_primary(void) INPUT_PRIMARY_TAP_GATE } + if( + pl.aryNextBurstShotTime_listenIndex != -1 && + arg_thisWeapon.iFireMode != BITS_FIREMODE_NONE + ){ + // the player is trying to manually fire while burst-fire is in the middle + // of sending shots? STOP + return; + } + if (!arg_thisWeapon.iClipLeft || WEAPON_UNDERWATER_CHECK) { PLAY_CLICK_SOUND return; @@ -185,7 +194,7 @@ w_mp5k_primary(void) if(arg_thisWeapon.iFireMode == BITS_FIREMODE_BURST) { - weapon_base_burstFire(pl, ary_weaponData[WEAPON_ID::MP5SD], arg_thisWeapon, BITS_AKIMBOCHOICE_LEFT, 3, 0.02); + weapon_gun_burstFire(pl, (weapondata_gun_t*)ary_weaponData[WEAPON_ID::MP5SD], arg_thisWeapon, BITS_AKIMBOCHOICE_LEFT, 3, 0.02, 0.18); } else if(arg_thisWeapon.iFireMode == BITS_FIREMODE_SEMI || arg_thisWeapon.iFireMode == BITS_FIREMODE_FULL) { diff --git a/src/shared/weapons/weapon_mp5sd.qc b/src/shared/weapons/weapon_mp5sd.qc index eb1fafd..5e2b087 100644 --- a/src/shared/weapons/weapon_mp5sd.qc +++ b/src/shared/weapons/weapon_mp5sd.qc @@ -135,6 +135,15 @@ w_mp5sd_primary(void) INPUT_PRIMARY_TAP_GATE } + if( + pl.aryNextBurstShotTime_listenIndex != -1 && + arg_thisWeapon.iFireMode != BITS_FIREMODE_NONE + ){ + // the player is trying to manually fire while burst-fire is in the middle + // of sending shots? STOP + return; + } + if (!arg_thisWeapon.iClipLeft || WEAPON_UNDERWATER_CHECK) { PLAY_CLICK_SOUND return; @@ -160,7 +169,7 @@ w_mp5sd_primary(void) if(arg_thisWeapon.iFireMode == BITS_FIREMODE_BURST) { - weapon_base_burstFire(pl, ary_weaponData[WEAPON_ID::MP5SD], arg_thisWeapon, BITS_AKIMBOCHOICE_LEFT, 3, 0.02); + weapon_gun_burstFire(pl, (weapondata_gun_t*)ary_weaponData[WEAPON_ID::MP5SD], arg_thisWeapon, BITS_AKIMBOCHOICE_LEFT, 3, 0.02, 0.18); } else if(arg_thisWeapon.iFireMode == BITS_FIREMODE_SEMI || arg_thisWeapon.iFireMode == BITS_FIREMODE_FULL) { diff --git a/src/shared/weapons/weapon_rugermk1.qc b/src/shared/weapons/weapon_rugermk1.qc index 05631ab..333299e 100644 --- a/src/shared/weapons/weapon_rugermk1.qc +++ b/src/shared/weapons/weapon_rugermk1.qc @@ -152,7 +152,7 @@ w_rugermk1_primary(void) #ifdef CLIENT View_ShowMuzzleflash(MUZZLE_SMALL); - View_AddEvent(w_ejectshell_pistol, 0.0f); + //View_AddEvent(w_ejectshell_pistol, 0.0f); #endif weapon_base_onAttack(pl, ary_weaponData[WEAPON_ID::RUGERMK1], arg_thisWeapon, BITS_AKIMBOCHOICE_LEFT); diff --git a/src/shared/weapons/weapon_sawedoff.qc b/src/shared/weapons/weapon_sawedoff.qc index 03c5973..8fb6c27 100644 --- a/src/shared/weapons/weapon_sawedoff.qc +++ b/src/shared/weapons/weapon_sawedoff.qc @@ -193,6 +193,7 @@ w_sawedoff_primary(void) TS_Weapons_ViewAnimation(weaponseq_sawedoff::shoot2, 31.0f/33.0f); } }else{ + randomChoice = random(); if(randomChoice < 0.5){ TS_Weapons_ViewAnimation(weaponseq_sawedoff::shoot1b, 31.0f/33.0f); }else{ @@ -202,7 +203,7 @@ w_sawedoff_primary(void) #ifdef CLIENT View_ShowMuzzleflash(MUZZLE_SMALL); - View_AddEvent(w_ejectshell_pistol, 0.0f); + //View_AddEvent(w_ejectshell_pistol, 0.0f); #endif weapon_base_onAttack(pl, ary_weaponData[WEAPON_ID::SAWEDOFF], arg_thisWeapon, BITS_AKIMBOCHOICE_LEFT); @@ -223,7 +224,7 @@ w_sawedoff_secondary(void) { player pl = (player)self; weapondynamic_t arg_thisWeapon = pl.ary_myWeapons[pl.inventoryEquippedIndex]; - return weapon_ironsight_ToggleIronsight(pl, (weapondata_ironsight_t*)ary_weaponData[WEAPON_ID::SAWEDOFF], arg_thisWeapon); + weapon_ironsight_ToggleIronsight(pl, (weapondata_ironsight_t*)ary_weaponData[WEAPON_ID::SAWEDOFF], arg_thisWeapon); } // need custom reload logic, works more like a typical weapon @@ -240,14 +241,14 @@ w_sawedoff_reload(void) // CHECK - we have two reload anims for ordinary and ironsight mode each. // One for if we have 1 clip left, another for if we have 0 clip left. if(arg_thisWeapon.iClipLeft == 0){ - //do the both-empty reload anim. + // do the both-empty reload anim. if(!arg_thisWeapon.iIronSight){ reloadSeq = weaponseq_sawedoff::reload; }else{ reloadSeq = weaponseq_sawedoff::reloadb; } }else{ - //wasn't 0? must be 1. Otherwise we wouldn't have reached this point. + // wasn't 0? must be 1. Otherwise we wouldn't have reached this point. if(!arg_thisWeapon.iIronSight){ reloadSeq = weaponseq_sawedoff::reload_sigle; }else{ diff --git a/src/shared/weapons/weapon_skorpion_akimbo.qc b/src/shared/weapons/weapon_skorpion_akimbo.qc index 3f3393c..1319cfb 100644 --- a/src/shared/weapons/weapon_skorpion_akimbo.qc +++ b/src/shared/weapons/weapon_skorpion_akimbo.qc @@ -119,7 +119,7 @@ w_skorpion_akimbo_holster(void) // Akimbo weapons consistently. // Putting it here avoids duplicating a bunch of code. // Also, "attackTypeUsed" is whether primary (FALSE) or secondary (TRUE) lead to this point. -BOOLEAN weapon_skorpion_akimbo_attack(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed){ +void weapon_skorpion_akimbo_attack(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed){ float randomChoice; int finalAkimboChoice = BITS_AKIMBOCHOICE_NONE; //default @@ -133,11 +133,9 @@ BOOLEAN weapon_skorpion_akimbo_attack(player pl, weapondynamic_t arg_thisWeapon, //because I am not copy/pasting this monstrosity 5 times. finalAkimboChoice = weapon_akimbo_fullAttackChoice(pl, ary_weaponData[WEAPON_ID::SKORPION_AKIMBO], arg_thisWeapon, attackTypeUsed); - SAVE_STATE(pl.nextAkimboAttackPreference); - if(finalAkimboChoice == -1){ //pl.akimboFirePrev = 0; - return FALSE; + return; } /* @@ -154,13 +152,13 @@ BOOLEAN weapon_skorpion_akimbo_attack(player pl, weapondynamic_t arg_thisWeapon, if((finalAkimboChoice & BITS_AKIMBOCHOICE_RIGHT)){ PLAY_CLICK_SOUND_RIGHT } - return FALSE; + return; } // ?? Is this even possible? if(finalAkimboChoice == 0){ //pl.akimboFirePrev = 0; - return FALSE; + return; } @@ -224,23 +222,13 @@ BOOLEAN weapon_skorpion_akimbo_attack(player pl, weapondynamic_t arg_thisWeapon, weapon_base_setWholeAttackDelay(pl, (*ary_weaponData[pl.activeweapon]).fAttackDelay * 1); } - return TRUE; -}//END OF weapon_skorpion_akimbo_attack +}// weapon_skorpion_akimbo_attack void w_skorpion_akimbo_primary(void) { - player pl = (player)self; - weapondynamic_t arg_thisWeapon = pl.ary_myWeapons[pl.inventoryEquippedIndex]; - - pl.akimboTest = 0; - - if(input_buttons & INPUT_BUTTON3){ - weapon_skorpion_akimbo_attack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_BOTH); - }else{ - weapon_skorpion_akimbo_attack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_LEFT); - } + weapon_gun_akimbo_full_primaryAttack(weapon_skorpion_akimbo_attack); } @@ -248,16 +236,7 @@ w_skorpion_akimbo_primary(void) void w_skorpion_akimbo_secondary(void) { - player pl = (player)self; - weapondynamic_t arg_thisWeapon = pl.ary_myWeapons[pl.inventoryEquippedIndex]; - - // reset - pl.akimboTest = 0; - - if(arg_thisWeapon.iFireModeAkimbo == BITS_FIREMODE_AKIMBO_FREE_FULL){ - weapon_skorpion_akimbo_attack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_RIGHT); - //pl.akimboFirePrev = BITS_AKIMBOCHOICE_RIGHT; - } + weapon_gun_akimbo_full_secondaryAttack(weapon_skorpion_akimbo_attack); } diff --git a/src/shared/weapons/weapon_socommk23_akimbo.qc b/src/shared/weapons/weapon_socommk23_akimbo.qc index 103fcfc..ed1a030 100644 --- a/src/shared/weapons/weapon_socommk23_akimbo.qc +++ b/src/shared/weapons/weapon_socommk23_akimbo.qc @@ -152,7 +152,7 @@ var int rightCount = 0; // Akimbo weapons consistently. // Putting it here avoids duplicating a bunch of code. // Also, "attackTypeUsed" is whether primary (FALSE) or secondary (TRUE) lead to this point. -BOOLEAN weapon_socommk23_akimbo_attack(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed){ +void weapon_socommk23_akimbo_attack(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed){ //weapondynamic_t arg_thisWeapon = pl.ary_myWeapons[pl.inventoryEquippedIndex]; //special case @@ -168,13 +168,10 @@ BOOLEAN weapon_socommk23_akimbo_attack(player pl, weapondynamic_t arg_thisWeapon // because I am not copy/pasting this monstrosity 5 times. finalAkimboChoice = weapon_akimbo_semiAttackChoice(pl, ary_weaponData[WEAPON_ID::SOCOMMK23_AKIMBO], arg_thisWeapon, attackTypeUsed); -#ifdef CLIENT - SAVE_STATE(pl.nextAkimboAttackPreference); -#endif if(finalAkimboChoice == -1){ //pl.akimboFirePrev = 0; - return FALSE; + return; } @@ -191,17 +188,15 @@ BOOLEAN weapon_socommk23_akimbo_attack(player pl, weapondynamic_t arg_thisWeapon if((finalAkimboChoice & BITS_AKIMBOCHOICE_RIGHT)){ PLAY_CLICK_SOUND_RIGHT } - return FALSE; + return; } - // ?? Is this even possible? if(finalAkimboChoice == 0){ //pl.akimboFirePrev = 0; - return FALSE; + return; } - // DEBUG!!! if((finalAkimboChoice & BITS_AKIMBOCHOICE_LEFT)){ leftCount++; @@ -315,65 +310,20 @@ BOOLEAN weapon_socommk23_akimbo_attack(player pl, weapondynamic_t arg_thisWeapon weapon_base_setWholeAttackDelay(pl, (*ary_weaponData[pl.activeweapon]).fAttackDelay * 1); } - return TRUE; -}//END OF weapon_socommk23_akimbo_attack +}// weapon_socommk23_akimbo_attack void w_socommk23_akimbo_primary(void) { - player pl = (player)self; - weapondynamic_t arg_thisWeapon = pl.ary_myWeapons[pl.inventoryEquippedIndex]; - - // reset - pl.akimboTest = 0; - - // in addition to the primary input, which lead to '_primary' being called at all. - if(input_buttons & INPUT_BUTTON3){ - if(!weapon_akimbo_semiAttackDualHack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_BOTH, &weapon_socommk23_akimbo_attack)){ - // nothing unusual here. - pl.akimboTest = 0; - weapon_socommk23_akimbo_attack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_BOTH); - }else{ - } - }else{ - if(!weapon_akimbo_semiAttackDualHack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_RIGHT, &weapon_socommk23_akimbo_attack)){ - weapon_socommk23_akimbo_attack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_LEFT); - pl.akimboFirePrev = BITS_AKIMBOCHOICE_LEFT; - } - - } - + weapon_gun_akimbo_semi_primaryAttack(weapon_socommk23_akimbo_attack); } void w_socommk23_akimbo_secondary(void) { - player pl = (player)self; - weapondynamic_t arg_thisWeapon = pl.ary_myWeapons[pl.inventoryEquippedIndex]; - - // reset - pl.akimboTest = 0; - - // NOTE - holding primary is impossible, would've called _primary above if so. - // Only secondary could possibly be held (and, is). - if(arg_thisWeapon.iFireModeAkimbo == BITS_FIREMODE_AKIMBO_SEMI_AUTO){ - // since secondary fire does nothing in semi-auto, we let it do ironsight stuff here - weapon_ironsight_ToggleIronsight(pl, (weapondata_ironsight_t*)ary_weaponData[WEAPON_ID::SOCOMMK23_AKIMBO], arg_thisWeapon); - - }else{ - // fires the right weapon always - - //weapon_socommk23_akimbo_attack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_RIGHT); - //return; - - if(!weapon_akimbo_semiAttackDualHack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_LEFT, &weapon_socommk23_akimbo_attack)){ - weapon_socommk23_akimbo_attack(pl, arg_thisWeapon, BITS_AKIMBOCHOICE_RIGHT); - pl.akimboFirePrev = BITS_AKIMBOCHOICE_RIGHT; - } - } - + weapon_ironsight_akimbo_semi_secondaryAttack(weapon_socommk23_akimbo_attack, WEAPON_ID::SOCOMMK23_AKIMBO); }