diff --git a/src/client/progs.src b/src/client/progs.src index 6d62fcc..58b2052 100644 --- a/src/client/progs.src +++ b/src/client/progs.src @@ -3,6 +3,11 @@ //---WARNINGS DISABLED--- #pragma warning disable Q302 /*uninitialised locals*/ + +// See ui_buymenu.qc for why this is disabled. +// No idea how to make warnings disabled only per file, in there +// would affect all files included in the compile after anyway +#pragma warning disable F314 /*implicit cast*/ ///////////////////////////////////////////////////////////////// diff --git a/src/client/ui_buymenu.qc b/src/client/ui_buymenu.qc index 86c876a..1018280 100644 --- a/src/client/ui_buymenu.qc +++ b/src/client/ui_buymenu.qc @@ -14,27 +14,187 @@ - -#define INITIALIZE_BASICBUTTON(arg_varName, arg_sName, arg_sHotkeyDisplay, arg_clr, arg_funOnClick_Custom) buymenu_btn_##arg_varName = spawn(CBuyMenu_BasicButton);\ +#define INITIALIZE_BASICBUTTON(arg_varName, arg_sName, arg_sHotkeyDisplay, arg_clr, arg_funOnClick_Custom) CBuyMenu_BasicButton_instantiate(&buymenu_btn_##arg_varName);\ 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_funOnClick_Custom);\ + CBuyMenu_BasicButton_create(&buymenu_btn_##arg_varName, 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_parentName) buymenu_btn_Buy_##arg_varName = spawn(CBuyMenu_WeaponButton);\ +#define INITIALIZE_WEAPONBUTTON(arg_varName, arg_sHotkeyDisplay, arg_clr, arg_parentName) CBuyMenu_WeaponButton_instantiate(&buymenu_btn_Buy_##arg_varName);\ 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, NULL, tempWeapRef.sIconFilePath, tempWeapRef.iPrice, tempWeapRef.iSlots, tempWeapRef.iBitsUpgrade & ~tempWeapRef.iBitsUpgradeAuto);\ - buymenu_addbuttonToTotal(&buymenu_btn_Buy_##arg_varName);\ + CBuyMenu_WeaponButton_create(&buymenu_btn_Buy_##arg_varName, sprintf("%s %s", arg_sHotkeyDisplay, tempWeapRef.sDisplayName), flDeterminedHotkey, arg_clr, NULL, tempWeapRef.sIconFilePath, tempWeapRef.iPrice, tempWeapRef.iSlots, tempWeapRef.iBitsUpgrade & ~tempWeapRef.iBitsUpgradeAuto);\ + buymenu_addbuttonToTotal((CBuyMenu_BasicButton*)&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); + buymenu_addbutton((CBuyMenu_BasicButton*)&buymenu_btn_Buy_##arg_parentName, (CBuyMenu_BasicButton*)&buymenu_btn_Buy_##arg_varName); + + + +typedef struct CBuyMenu_BasicButton_s CBuyMenu_BasicButton; +typedef struct CBuyMenu_WeaponButton_s CBuyMenu_WeaponButton; +typedef struct CBuyMenu_RemoveWeaponButton_s CBuyMenu_RemoveWeaponButton; + + + + +// Without using a typedef for method-types, FTE can't make things +// pointers to that mehtod type for whatever reason. +// That is, this kind of cast: +// methPtr = (void(CBuyMenu_BasicButton*)*) thingToCast +// ...makes the compiler complain, but this from the typedef below): +// methPtr = (MethodType_void_BasicButton*) thingToCast +// ...doesn't. No idea, let's just move on. +// Although these casts aren't needed since the types given/received just +// come as these in parameters and vars in button classes anyway. +typedef void(CBuyMenu_BasicButton*) MethodType_void_BasicButton; + + + +// Notice that the buttons do not have location/size information. They are +// drawn wherever as needed, checks for clicks need that supplied to know where +// to check. +// NOTE: any method names involving "click" also happen when the button's hotkey +// is pressed. +//class CBuyMenu_BasicButton +typedef struct CBuyMenu_BasicButton_s{ + void* my_vtable; + + int iType; // is this a BasicButton or a WeaponButton? + BOOL bActive; // Effectively hides this from all logic. As in, don't skip the space this would occupy. Pretend like this button didn't exit. + // Refreshed at a new layer / going back one. + + int iGlobalIndex; + string sName; + + // -1 is the signal for "no hotkey". Numbers actually start at 48 for 0 (49 for 1... or 48+1 for clarity). + float flHotkey; + + vector clr; // stored; natural color. + vector clr_render; // for actual use. + + // Array of buttons that are shown when I'm clicked on. Many buttons use this. + // The "0 Cancel" back button will be drawn if applicaple (for the active (deepest layer open) if it's not the first layer). + // struct CBuyMenu_BasicButton* ary_btn[16i]; + int ary_btn_index[16]; + int ary_btn_softLength; + + + // 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. + + // BACK TO THE DEPTHS OF HELL WITH YE + // (the existence of any method-pointer done in this way corrupts a random + // piece of memory in ways that can be strange to stumble upon) + //virtual void(CBuyMenu_BasicButton* arg_this) funOnClick_Custom = NULL; + //virtual void(CBuyMenu_BasicButton* arg_this) funOnShow_Custom = NULL; + // But this way is safe, so are non-pointer method types in structs. + MethodType_void_BasicButton* funOnClick_Custom; + MethodType_void_BasicButton* funOnShow_Custom; -// prototype'd class -class CBuyMenu_BasicButton; + // 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 + // to see if the player can afford an upgrade as it is displayed. + +} CBuyMenu_BasicButton; + +void CBuyMenu_BasicButton_instantiate(CBuyMenu_BasicButton* arg_this); +void CBuyMenu_BasicButton_init(CBuyMenu_BasicButton* arg_this); + +void CBuyMenu_BasicButton_create(CBuyMenu_BasicButton* arg_this, string arg_sName, float arg_flHotkey, vector arg_clr, MethodType_void_BasicButton* arg_funOnClick_Custom); + +void CBuyMenu_BasicButton_funOnClick_Base(CBuyMenu_BasicButton* arg_this); +void CBuyMenu_BasicButton_funOnShow_Base(CBuyMenu_BasicButton* arg_this); +void CBuyMenu_BasicButton_funOnRender_Base(CBuyMenu_BasicButton* arg_this, vector arg_suggestedDrawPos, int arg_iLayer, int arg_iButtonRow, BOOL arg_fIsSelected); + + + +//class CBuyMenu_WeaponButton : CBuyMenu_BasicButton{ +typedef struct CBuyMenu_WeaponButton_s{ + void* my_vtable; + + int iType; + BOOL bActive; + int iGlobalIndex; + string sName; + float flHotkey; + vector clr; + vector clr_render; + int ary_btn_index[16]; + int ary_btn_softLength; + MethodType_void_BasicButton* funOnClick_Custom; + MethodType_void_BasicButton* funOnShow_Custom; + + ///////////////////////////////////////////////////////////////////////////// + + + // What weapon (by ID) will I purchase (or try to) when bought? + // Parameter limit used up - have to set this separtely. Ugh. + // We're remaking buttons to use structs instead of classes later so this isn't too + // bad of a patch for now. + int iWeaponPurchaseID; + + string sWeaponImagePath; + int iWeaponPrice; + int iWeaponSlots; + int iBitsWeaponOpt; //Can the player buy... a scope? lazer sight? flash light? akimbo? etc. + + + // after arg_clr: int arg_ary_btn_index[16] + +} CBuyMenu_WeaponButton; + + +void CBuyMenu_WeaponButton_instantiate(CBuyMenu_WeaponButton* arg_this); +void CBuyMenu_WeaponButton_init(CBuyMenu_WeaponButton* arg_this); + +void CBuyMenu_WeaponButton_create(CBuyMenu_WeaponButton* arg_this, string arg_sName, float arg_flHotkey, vector arg_clr, MethodType_void_BasicButton* arg_funOnClick_Custom, string arg_sWeaponImagePath, int arg_iWeaponPrice, int arg_iWeaponSlots, int arg_iBitsWeaponOpt ); + +void CBuyMenu_WeaponButton_funOnClick_Base(CBuyMenu_WeaponButton* arg_this); +void CBuyMenu_WeaponButton_funOnShow_Base(CBuyMenu_WeaponButton* arg_this); +void CBuyMenu_WeaponButton_funOnRender_Base(CBuyMenu_WeaponButton* arg_this, vector arg_suggestedDrawPos, int arg_iLayer, int arg_iButtonRow, BOOL arg_fIsSelected); + + + +// Very slightly modified form of CBuyMenu_BasicButton that just includes +// an extra var for storing what part of the config to remove if clicked on. +// As in, the 3rd button will remove the 2nd index (...ary_myWeapons[2]) from the player's +// temp config. +//class CBuyMenu_RemoveWeaponButton : CBuyMenu_BasicButton{ +typedef struct CBuyMenu_RemoveWeaponButton_s{ + void* my_vtable; + + int iType; + BOOL bActive; + int iGlobalIndex; + string sName; + float flHotkey; + vector clr; + vector clr_render; + int ary_btn_index[16]; + int ary_btn_softLength; + MethodType_void_BasicButton* funOnClick_Custom; + MethodType_void_BasicButton* funOnShow_Custom; + + ///////////////////////////////////////////////////////////////////////////// + + + // What element of the config do I remove if I am picked? + int linkedConfigIndex; + +} CBuyMenu_RemoveWeaponButton; + +void CBuyMenu_RemoveWeaponButton_instantiate(CBuyMenu_RemoveWeaponButton* arg_this); +void CBuyMenu_RemoveWeaponButton_init(CBuyMenu_RemoveWeaponButton* arg_this); + +void CBuyMenu_BasicButton_funOnClick_Base_vcall(CBuyMenu_BasicButton* arg_this); +void CBuyMenu_BasicButton_funOnShow_Base_vcall(CBuyMenu_BasicButton* arg_this); +void CBuyMenu_BasicButton_funOnRender_Base_vcall(CBuyMenu_BasicButton* arg_this, vector arg_suggestedDrawPos, int arg_iLayer, int arg_iButtonRow, BOOL arg_fIsSelected); + + + + var int iWeaponTempID = -1; @@ -50,11 +210,11 @@ var int iHoveredButtonIndex = -1; var int iActiveLayer = 0; -class CBuyMenu_BasicButton; -class CBuyMenu_WeaponButton; -class CBuyMenu_WeaponButton; -class CBuyMenu_RemoveWeaponButton; +void UI_BuyMenu_ResetTempVariables(void); +void buymenu_addbutton(CBuyMenu_BasicButton* arg_this, CBuyMenu_BasicButton* arg_other); +void buymenu_addbuttonToTotal(CBuyMenu_BasicButton* arg_this); +void drawBuyButton(int arg_iGlobalIndex, string arg_text, vector arg_suggestedDrawPos, int arg_iLayer, int arg_iButtonRow, BOOL arg_fIsSelected, vector arg_clr); void buymenu_cancelConfigAndClose(void); void refreshButtons(void); void setupRemoveButtonList(void); @@ -168,109 +328,364 @@ var CBuyMenu_WeaponButton buymenu_btn_Buy_SEALKNIFE; -// Notice that the buttons do not have location/size information. They are -// drawn wherever as needed, checks for clicks need that supplied to know where -// to check. -// NOTE: any method names involving "click" also happen when the button's hotkey -// is pressed. -class CBuyMenu_BasicButton{ - - // yes. really. - CBuyMenu_BasicButton* _this; - - int iType; // is this a BasicButton or a WeaponButton? - BOOL bActive; // Effectively hides this from all logic. As in, don't skip the space this would occupy. Pretend like this button didn't exit. - // Refreshed at a new layer / going back one. - int iGlobalIndex; - string sName; + + +// struct method implementations +///////////////////////////////////////////////////// + +void +CBuyMenu_BasicButton_init(CBuyMenu_BasicButton* arg_this) +{ + arg_this->iType = BUTTON_TYPEID_BASIC; + arg_this->bActive = TRUE; + arg_this->funOnClick_Custom = NULL; + arg_this->funOnShow_Custom = NULL; +} +void +CBuyMenu_BasicButton_create( + CBuyMenu_BasicButton* arg_this, + string arg_sName, float arg_flHotkey, vector arg_clr, + MethodType_void_BasicButton* arg_funOnClick_Custom +){ + arg_this->sName = arg_sName; - // -1 is the signal for "no hotkey". Numbers actually start at 48 for 0 (49 for 1... or 48+1 for clarity). - float flHotkey; + arg_this->flHotkey = arg_flHotkey; + arg_this->clr = arg_clr; + arg_this->clr_render = arg_clr; //good default. - vector clr; // stored; natural color. - vector clr_render; // for actual use. + arg_this->funOnClick_Custom = arg_funOnClick_Custom; - // Array of buttons that are shown when I'm clicked on. Many buttons use this. - // The "0 Cancel" back button will be drawn if applicaple (for the active (deepest layer open) if it's not the first layer). - // struct CBuyMenu_BasicButton* ary_btn[16i]; - int ary_btn_index[16]; - int ary_btn_softLength; + arg_this->funOnShow_Custom = NULL; +} + + + +// When this button is clicked, what does it do? +void +CBuyMenu_BasicButton_funOnClick_Base(CBuyMenu_BasicButton* arg_this) +{ + + // basic button behavior. Only if our array has a non-zero length. + // Buttons of zero length don't unwrap into new buttons and can do something special, + // like go up a layer instead ("cancel"), something about configs, or buy a + // weapon/accessory. + if(arg_this->ary_btn_softLength != 0i){ + int i; + + // "this"... is not already a pointer??! WHAT HERESY BEFALLS MY EYES?!!! + // nah just kidding, makes sense for QuakeC. + // setActiveLayerButton(&this); + ary_layerButtonChoice[iActiveLayer] = arg_this; + + // "warning F307: type mismatch: CBuyMenu_BasicButton * arg_this to + // CBuyMenu_BasicButton *[ary_layerButtonChoice]" + // ...????? happens if using CBuyMenu_BasicButton pointers (*) in arg_this above + // and the array "ary_layerButtonChoice". + iActiveLayer = iActiveLayer + 1; + + // 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 "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). + for(i = 0; i < arg_this->ary_btn_softLength; i++){ + int nextButtonIndex = arg_this->ary_btn_index[i]; + CBuyMenu_BasicButton* someButton = ary_btnTotal[nextButtonIndex]; + someButton->bActive = TRUE; + //someButton->funOnShow_Base(); + CBuyMenu_BasicButton_funOnShow_Base_vcall(someButton); + } + + }// button length check + + if(arg_this->funOnClick_Custom != NULL){ + // If we have a custom click method, do it. Also, go easy on FTE + MethodType_void_BasicButton tempMetho = (*arg_this->funOnClick_Custom); + tempMetho(arg_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(); + +}//funOnClick_Base + + +void +CBuyMenu_BasicButton_funOnShow_Base(CBuyMenu_BasicButton* arg_this) +{ + if(arg_this->funOnShow_Custom != NULL){ + MethodType_void_BasicButton tempMetho = (*arg_this->funOnShow_Custom); + tempMetho(arg_this); + } + +} + +void +CBuyMenu_BasicButton_funOnRender_Base +( + CBuyMenu_BasicButton* arg_this, + vector arg_suggestedDrawPos, int arg_iLayer, int arg_iButtonRow, BOOL arg_fIsSelected +) +{ + drawBuyButton(arg_this->iGlobalIndex, arg_this->sName, arg_suggestedDrawPos, arg_iLayer, arg_iButtonRow, arg_fIsSelected, arg_this->clr_render); +} + + + + +void +CBuyMenu_WeaponButton_init(CBuyMenu_WeaponButton* arg_this) +{ + CBuyMenu_BasicButton_init((CBuyMenu_BasicButton*)arg_this); + arg_this->bActive = TRUE; + arg_this->iWeaponPurchaseID = -1; //default +} +void +CBuyMenu_WeaponButton_create +( + CBuyMenu_WeaponButton* arg_this, + string arg_sName, float arg_flHotkey, vector arg_clr, + MethodType_void_BasicButton* arg_funOnClick_Custom, + string arg_sWeaponImagePath, int arg_iWeaponPrice, int arg_iWeaponSlots, + int arg_iBitsWeaponOpt +){ + + //defaults. + //arg_this->iLayer = 0i; + arg_this->ary_btn_softLength = 0i; - // 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. + arg_this->sName = arg_sName; - virtual void(CBuyMenu_BasicButton* arg_this) funOnClick_Custom = NULL; - //int* funOnClick_Custom; - virtual void(CBuyMenu_BasicButton* arg_this) funOnShow_Custom = NULL; - //int* funOnShow_Custom; + arg_this->flHotkey = arg_flHotkey; + arg_this->clr = arg_clr; + arg_this->clr_render = arg_clr; //good default. - void(void) CBuyMenu_BasicButton; + arg_this->funOnClick_Custom = arg_funOnClick_Custom; - virtual void(CBuyMenu_BasicButton* arg_this) setThisPointer; + arg_this->funOnShow_Custom = NULL; - virtual void(string arg_sName, float arg_flHotkey, vector arg_clr, void(CBuyMenu_BasicButton* arg_this) arg_funOnClick_Custom ) create; + // Why do we add "_0.tga" to a .spr reference for the draw to work? + // The world may never know. + arg_this->sWeaponImagePath = sprintf("%s_0.tga", arg_sWeaponImagePath); - virtual void(vector arg_suggestedDrawPos, int arg_iLayer, int arg_iButtonRow, BOOL arg_fIsSelected) funOnRender_Base; - virtual void(void) funOnClick_Base; + arg_this->iWeaponPrice = arg_iWeaponPrice; + arg_this->iWeaponSlots = arg_iWeaponSlots; + arg_this->iBitsWeaponOpt = arg_iBitsWeaponOpt; - virtual void(void) funOnShow_Base; + //Use that flag to determine what butttons to give me. - // 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 - // to see if the player can afford an upgrade as it is displayed. + arg_this->iType = BUTTON_TYPEID_WEAPON; + //Only add subbuttons (buy, upgrades, etc.) if this lacks the INSTANT option. + if( !(arg_this->iBitsWeaponOpt & BITS_WEAPONOPT_INSTANT)){ + + //Every weapon has at least a "Buy" button. + buymenu_addbutton((CBuyMenu_BasicButton*)arg_this, &buymenu_btn_WeaponOpt_Buy); + + if(arg_this->iBitsWeaponOpt & BITS_WEAPONOPT_SILENCER){ + buymenu_addbutton((CBuyMenu_BasicButton*)arg_this, &buymenu_btn_WeaponOpt_Silencer); + } + if(arg_this->iBitsWeaponOpt & BITS_WEAPONOPT_LASERSIGHT){ + buymenu_addbutton((CBuyMenu_BasicButton*)arg_this, &buymenu_btn_WeaponOpt_Lasersight); + } + if(arg_this->iBitsWeaponOpt & BITS_WEAPONOPT_FLASHLIGHT){ + buymenu_addbutton((CBuyMenu_BasicButton*)arg_this, &buymenu_btn_WeaponOpt_Flashlight); + } + if(arg_this->iBitsWeaponOpt & BITS_WEAPONOPT_SCOPE){ + buymenu_addbutton((CBuyMenu_BasicButton*)arg_this, &buymenu_btn_WeaponOpt_Scope); + } + if(arg_this->iBitsWeaponOpt & BITS_WEAPONOPT_AKIMBO){ + buymenu_addbutton((CBuyMenu_BasicButton*)arg_this, &buymenu_btn_WeaponOpt_Akimbo); + } + if(arg_this->iBitsWeaponOpt & BITS_WEAPONOPT_FULLLOAD){ + buymenu_addbutton((CBuyMenu_BasicButton*)arg_this, &buymenu_btn_WeaponOpt_FullLoad); + } + }//BITS_WEAPONOPT_INSTANT check +}//create + + + + +void +CBuyMenu_WeaponButton_funOnClick_Base(CBuyMenu_WeaponButton* arg_this) +{ + weapondata_basic_t weaponRef; + // Just one thing. Let's reset this to be safe (new weapon opened for seeing + // upgrade choices) + UI_BuyMenu_ResetTempVariables(); + // and, thie tempCost starts at the value of this weapon as stated. + if(arg_this->iWeaponPurchaseID == -1){ + return; + } + weaponRef = (*ary_weaponData[arg_this->iWeaponPurchaseID]); + if(!(arg_this->iBitsWeaponOpt & BITS_WEAPONOPT_INSTANT)){ + // normal behavior. + iWeaponTempID = arg_this->iWeaponPurchaseID; + //CBuyMenu_BasicButton::funOnClick_Base(); + CBuyMenu_BasicButton_funOnClick_Base((CBuyMenu_BasicButton*)arg_this); + }else{ + // has the instant flag? that's it, apply it if we can. + if(canBuyWeapon(arg_this->iWeaponPurchaseID, 0, 0, 1) ){ + BOOL addSuccess = attemptAddWeaponToConfig(arg_this->iWeaponPurchaseID, BITS_WEAPONOPT_NONE, 1); + if(addSuccess){ + //and then go back. + buymenu_backOneLayer(); + buymenu_btn_Back_updateText(); + } + } + } +}//funOnClick_Base + + +void +CBuyMenu_WeaponButton_funOnShow_Base(CBuyMenu_WeaponButton* arg_this) +{ + CBuyMenu_BasicButton_funOnShow_Base((CBuyMenu_BasicButton*)arg_this); + // See if this weapon can be afforded. + if(canBuyWeapon(arg_this->iWeaponPurchaseID, 0, 0, 1)){ + arg_this->clr_render = arg_this->clr; + }else{ + // same, but draw it red to show we can't afford it at a glance. + arg_this->clr_render = clrRed; + } +} + +void +CBuyMenu_WeaponButton_funOnRender_Base +( + CBuyMenu_WeaponButton* arg_this, + vector arg_suggestedDrawPos, int arg_iLayer, int arg_iButtonRow, + BOOL arg_fIsSelected +) +{ + CBuyMenu_BasicButton_funOnRender_Base( + (CBuyMenu_BasicButton*)arg_this, arg_suggestedDrawPos, arg_iLayer, + arg_iButtonRow, arg_fIsSelected + ); + + // I want to draw my sWeaponImagePath above myself. + if(arg_fIsSelected && !(arg_this->iBitsWeaponOpt & BITS_WEAPONOPT_INSTANT) ){ + + vector arg_buttonPos = [ + video_mins[0] + 5 + + arg_iLayer * (vButtonSizStandard.x + 1), video_mins[1] + video_res[1]/2 + arg_iButtonRow * (vButtonSizStandard.y + 1) + ]; + + float arg_opac; + if(arg_fIsSelected || arg_iLayer == iActiveLayer){ + arg_opac = 0.96; + }else{ + arg_opac = 0.71; + } + + vector textDrawOrigin = [arg_suggestedDrawPos.x + LABEL_OFFSET_X + 128, (video_res[1]/2) + LABEL_OFFSET_Y - (48 + 1)]; + + // NOTICE - draw on top of all buttons on this row unconditionally. Don't use arg_suggestedDrawPos.y + drawsubpic([arg_buttonPos.x, (video_res[1]/2) - (48 + 1)], [128,48], arg_this->sWeaponImagePath, [0,0], [128/128,48/48], clrPaleBlue, 0.96, DRAWFLAG_ADDITIVE); + + string drawString1 = sprintf("%i Credits", arg_this->iWeaponPrice); + string drawString2 = sprintf("%i Slots", arg_this->iWeaponSlots); + + drawfill( [arg_buttonPos.x, (video_res[1]/2) - (48 + 1)], [256-1, 48], arg_this->clr * 0.93f, arg_opac - 0.60f, DRAWFLAG_NORMAL ); + + Gfx_Text( textDrawOrigin, drawString1, vButtonFontSize, arg_this->clr * 0.98f, (1.0f-(1.0f - arg_opac)*0.88) - 0.02f, DRAWFLAG_NORMAL, FONT_ARIAL_STD ); + Gfx_Text( [textDrawOrigin.x, textDrawOrigin.y + (vButtonSizStandard.y+1) ], drawString2, vButtonFontSize, arg_this->clr * 0.98f, (1.0f-(1.0f - arg_opac)*0.88) - 0.02f, DRAWFLAG_NORMAL, FONT_ARIAL_STD ); + + } +}//funOnRender_Base + + + +void +CBuyMenu_RemoveWeaponButton_init(CBuyMenu_RemoveWeaponButton* arg_this) +{ + CBuyMenu_BasicButton_init((CBuyMenu_BasicButton*)arg_this); +} + + + + + + + +void CBuyMenu_BasicButton_vtable[] = { + (void)CBuyMenu_BasicButton_funOnClick_Base, + (void)CBuyMenu_BasicButton_funOnShow_Base, + (void)CBuyMenu_BasicButton_funOnRender_Base }; - - -class CBuyMenu_WeaponButton : CBuyMenu_BasicButton{ - - // What weapon (by ID) will I purchase (or try to) when bought? - // Parameter limit used up - have to set this separtely. Ugh. - // We're remaking buttons to use structs instead of classes later so this isn't too - // bad of a patch for now. - int iWeaponPurchaseID; - - string sWeaponImagePath; - int iWeaponPrice; - int iWeaponSlots; - int iBitsWeaponOpt; //Can the player buy... a scope? lazer sight? flash light? akimbo? etc. - - - 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_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) funOnRender_Base; - virtual void(void) funOnClick_Base; - - - virtual void(void) funOnShow_Base; - +void CBuyMenu_WeaponButton_vtable[] = { + (void)CBuyMenu_WeaponButton_funOnClick_Base, + (void)CBuyMenu_WeaponButton_funOnShow_Base, + (void)CBuyMenu_WeaponButton_funOnRender_Base }; - - -// Very slightly modified form of CBuyMenu_BasicButton that just includes -// an extra var for storing what part of the config to remove if clicked on. -// As in, the 3rd button will remove the 2nd index (...ary_myWeapons[2]) from the player's -// temp config. -class CBuyMenu_RemoveWeaponButton : CBuyMenu_BasicButton{ - // What element of the config do I remove if I am picked? - int linkedConfigIndex; - - void(void) CBuyMenu_RemoveWeaponButton; +void CBuyMenu_RemoveWeaponButton_vtable[] = { + (void)CBuyMenu_BasicButton_funOnClick_Base, + (void)CBuyMenu_BasicButton_funOnShow_Base, + (void)CBuyMenu_BasicButton_funOnRender_Base }; void -CBuyMenu_RemoveWeaponButton::CBuyMenu_RemoveWeaponButton(void) +CBuyMenu_BasicButton_instantiate(CBuyMenu_BasicButton* arg_this) { - + arg_this->my_vtable = &CBuyMenu_BasicButton_vtable; + CBuyMenu_BasicButton_init(arg_this); } +void +CBuyMenu_WeaponButton_instantiate(CBuyMenu_WeaponButton* arg_this) +{ + arg_this->my_vtable = &CBuyMenu_WeaponButton_vtable; + CBuyMenu_WeaponButton_init(arg_this); +} +void +CBuyMenu_RemoveWeaponButton_instantiate(CBuyMenu_RemoveWeaponButton* arg_this) +{ + arg_this->my_vtable = &CBuyMenu_RemoveWeaponButton_vtable; + CBuyMenu_RemoveWeaponButton_init(arg_this); +} + + +typedef void(CBuyMenu_BasicButton*) CBuyMenu_BasicButton_funOnClick_Base_type; +typedef void(CBuyMenu_BasicButton*) CBuyMenu_BasicButton_funOnShow_Base_type; +typedef void(CBuyMenu_BasicButton*, vector, int, int, BOOL) CBuyMenu_BasicButton_funOnRender_Base_type; + +void CBuyMenu_BasicButton_funOnClick_Base_vcall(CBuyMenu_BasicButton* arg_this){ + void* method_raw = &arg_this->my_vtable[0]; + CBuyMenu_BasicButton_funOnClick_Base_type myMethod = *(((CBuyMenu_BasicButton_funOnClick_Base_type*) method_raw)); + myMethod(arg_this); +} +void CBuyMenu_BasicButton_funOnShow_Base_vcall(CBuyMenu_BasicButton* arg_this){ + void* method_raw = &arg_this->my_vtable[1]; + CBuyMenu_BasicButton_funOnShow_Base_type myMethod = *(((CBuyMenu_BasicButton_funOnShow_Base_type*) method_raw)); + myMethod(arg_this); +} +void CBuyMenu_BasicButton_funOnRender_Base_vcall(CBuyMenu_BasicButton* arg_this, vector arg_suggestedDrawPos, int arg_iLayer, int arg_iButtonRow, BOOL arg_fIsSelected){ + void* method_raw = &arg_this->my_vtable[2]; + CBuyMenu_BasicButton_funOnRender_Base_type myMethod = *(((CBuyMenu_BasicButton_funOnRender_Base_type*) method_raw)); + myMethod(arg_this, arg_suggestedDrawPos, arg_iLayer, arg_iButtonRow, arg_fIsSelected); +} + + + +// convenient way to reset these globals for keeping track of a purchase in progress. +// Leaving the buy screen or getting out of a weapon should reset them. +void +UI_BuyMenu_ResetTempVariables(void) +{ + iWeaponTempID = -1; + iBitsUpgradeTemp = BITS_WEAPONOPT_NONE; + iExtraPriceTemp = 0; + iExtraSlotsTemp = 0; + iPurchaseCountTemp = 1; +}// UI_BuyMenu_ResetTempVariables + + // Being called implies the mouse was clicked. Calls OnClick_Base if the mouse is // within the button bounds. @@ -279,13 +694,11 @@ checkBuyMenuButtonClicked( CBuyMenu_BasicButton* arg_someBtn, vector vPosition, vector vSize ) { - CBuyMenu_BasicButton deref = *arg_someBtn; - if(UI_CheckMouse(vPosition, vSize)){ // What button is being hovered over? - iHoveredButtonIndex = deref.iGlobalIndex; + iHoveredButtonIndex = arg_someBtn->iGlobalIndex; - (*arg_someBtn).funOnClick_Base(); + CBuyMenu_BasicButton_funOnClick_Base_vcall(arg_someBtn); pSeatLocal->m_inputMouseClicked = FALSE; return TRUE; @@ -300,11 +713,11 @@ checkBuyMenuButtonHotKeyPressed( CBuyMenu_BasicButton* arg_someBtn ) { - CBuyMenu_BasicButton deref = *arg_someBtn; - // Check for the button's hotkey. - if(deref.flHotkey != -1 && pSeatLocal->m_inputKeyDown == deref.flHotkey){ - (*arg_someBtn).funOnClick_Base(); + if(arg_someBtn->flHotkey != -1 && pSeatLocal->m_inputKeyDown == arg_someBtn->flHotkey){ + + CBuyMenu_BasicButton_funOnClick_Base_vcall(arg_someBtn); + pSeatLocal->m_inputKeyDown = 0; return TRUE; } @@ -322,7 +735,7 @@ UI_BuyMenu_OnMouseClick(void) vector vButtonPos = [video_mins[0] + 5, video_mins[1] + video_res[1]/2, 0]; vector vBtnPos = [0,0,0]; int btnToRender_index_global; - CBuyMenu_BasicButton previousLayerButton; + CBuyMenu_BasicButton* previousLayerButton; if(iActiveLayer == 0){ vBtnPos.x = (int)vButtonPos.x; //default pos. @@ -338,9 +751,9 @@ UI_BuyMenu_OnMouseClick(void) vBtnPos.y = (int)vButtonPos.y; // All other layers only render buttons that the previous layer (selected button there) tells them to. - previousLayerButton = *ary_layerButtonChoice[iActiveLayer - 1i]; + previousLayerButton = ary_layerButtonChoice[iActiveLayer - 1]; - for(i2 = 0i; i2 < previousLayerButton.ary_btn_softLength; i2 = i2+1i){ + for(i2 = 0i; i2 < previousLayerButton->ary_btn_softLength; i2 = i2+1){ // CONCLUSION // So much as this local var, "btnCheck", being set to a dereferenced @@ -357,10 +770,10 @@ UI_BuyMenu_OnMouseClick(void) // When this method ends, or really this scope (?), that thing the // ary_btnTotal element is pointing at blanks out. - btnToRender_index_global = previousLayerButton.ary_btn_index[i2]; + btnToRender_index_global = previousLayerButton->ary_btn_index[i2]; - CBuyMenu_BasicButton tempButton2 = *ary_btnTotal[btnToRender_index_global]; - if(tempButton2.bActive == FALSE){ + CBuyMenu_BasicButton* tempButton2 = ary_btnTotal[btnToRender_index_global]; + if(tempButton2->bActive == FALSE){ // let the next button be tried instead. continue; } @@ -389,7 +802,7 @@ UI_BuyMenu_OnKeyDown(void) { int i2; int btnToRender_index_global; - CBuyMenu_BasicButton previousLayerButton; + CBuyMenu_BasicButton* previousLayerButton; if(iActiveLayer == 0){ for(i2 = 0i; i2 < ary_layerFirstButton_softLength; i2++){ @@ -397,13 +810,13 @@ UI_BuyMenu_OnKeyDown(void) } }else{ // All other layers only render buttons that the previous layer (selected button there) tells them to. - previousLayerButton = *ary_layerButtonChoice[iActiveLayer - 1i]; + previousLayerButton = ary_layerButtonChoice[iActiveLayer - 1]; - for(i2 = 0i; i2 < previousLayerButton.ary_btn_softLength; i2 = i2+1i){ + for(i2 = 0i; i2 < previousLayerButton->ary_btn_softLength; i2 = i2+1){ btnToRender_index_global = previousLayerButton.ary_btn_index[i2]; - CBuyMenu_BasicButton tempButton2 = *ary_btnTotal[btnToRender_index_global]; - if(tempButton2.bActive == FALSE){ + CBuyMenu_BasicButton* tempButton2 = ary_btnTotal[btnToRender_index_global]; + if(tempButton2->bActive == FALSE){ // let the next button be tried instead. continue; } @@ -418,7 +831,7 @@ UI_BuyMenu_OnKeyDown(void) -// For "_this" button, add "arg_other" to its list of buttons (ary_btn) to be shown when this button +// For "arg_this" button, add "arg_other" to its list of buttons (ary_btn) to be shown when this button // is clicked. // Also, so much as adding a button to another's list will bump the other button's "iLayer" by 1 // past the button it's being linked to. @@ -426,24 +839,21 @@ UI_BuyMenu_OnKeyDown(void) // (and match between the two parents, which should be parentButton+1). // "iLayer" will be handled naturally just fine otherwise. void -buymenu_addbutton(CBuyMenu_BasicButton* _this, CBuyMenu_BasicButton* arg_other) +buymenu_addbutton(CBuyMenu_BasicButton* arg_this, CBuyMenu_BasicButton* arg_other) { - CBuyMenu_BasicButton _this_deref = *_this; - CBuyMenu_BasicButton arg_other_deref = *arg_other; - - if(_this_deref.ary_btn_softLength < 16i){ - //proceed. - int nextButtonSlot = _this_deref.ary_btn_softLength; + if(arg_this->ary_btn_softLength < 16i){ + // proceed. + int nextButtonSlot = arg_this->ary_btn_softLength; - //I am the number "i" child of the parent. Useful for telling what button from the previous layer - //was selected. + // I am the number "i" child of the parent. Useful for telling what button from the previous layer + // was selected. - //_this.ary_btn[nextButtonSlot] = arg_other; - _this_deref.ary_btn_index[nextButtonSlot] = arg_other_deref.iGlobalIndex; + //arg_this.ary_btn[nextButtonSlot] = arg_other; + arg_this->ary_btn_index[nextButtonSlot] = arg_other->iGlobalIndex; - _this_deref.ary_btn_softLength += 1i; //increase the number of buttons I link to by 1. - // arg_other_deref.iLayer = _this_deref.iLayer + 1i; //This "other" button is one layer deeper + arg_this->ary_btn_softLength += 1; //increase the number of buttons I link to by 1. + // arg_other_deref.iLayer = _this_deref.iLayer + 1; //This "other" button is one layer deeper // than the parent. } @@ -451,9 +861,8 @@ buymenu_addbutton(CBuyMenu_BasicButton* _this, CBuyMenu_BasicButton* arg_other) }//buymenu_addbutton - void -buymenu_addbuttonToTotal(CBuyMenu_BasicButton* _this) +buymenu_addbuttonToTotal(CBuyMenu_BasicButton* arg_this) { if(ary_btnTotal_softLength >= ary_btnTotal.length){ @@ -462,18 +871,16 @@ buymenu_addbuttonToTotal(CBuyMenu_BasicButton* _this) return; } - CBuyMenu_BasicButton _this_deref = *_this; + //localcmd(sprintf("echo addButtonToTotal: IM %s AND MY ID IS %i\n", arg_this.sName, ary_btnTotal_softLength)); - //localcmd(sprintf("echo addButtonToTotal: IM %s AND MY ID IS %i\n", _this.sName, ary_btnTotal_softLength)); - - _this_deref.iGlobalIndex = ary_btnTotal_softLength; - ary_btnTotal[ary_btnTotal_softLength] = _this; - ary_btnTotal_softLength = ary_btnTotal_softLength + 1i; + arg_this->iGlobalIndex = ary_btnTotal_softLength; + ary_btnTotal[ary_btnTotal_softLength] = arg_this; + ary_btnTotal_softLength = ary_btnTotal_softLength + 1; }//buymenu_addbutton void -buymenu_addbuttonToFirstLayer(CBuyMenu_BasicButton* _this) +buymenu_addbuttonToFirstLayer(CBuyMenu_BasicButton* arg_this) { if(ary_layerFirstButton_softLength >= ary_layerFirstButton.length){ @@ -482,8 +889,8 @@ buymenu_addbuttonToFirstLayer(CBuyMenu_BasicButton* _this) return; } - ary_layerFirstButton[ary_layerFirstButton_softLength] = _this; - ary_layerFirstButton_softLength = ary_layerFirstButton_softLength + 1i; + ary_layerFirstButton[ary_layerFirstButton_softLength] = arg_this; + ary_layerFirstButton_softLength = ary_layerFirstButton_softLength + 1; }//buymenu_addbuttonToFirstLayer @@ -544,286 +951,8 @@ setActiveLayerButton(CBuyMenu_BasicButton* arg_someButton) ary_layerButtonChoice[iActiveLayer] = arg_someButton; } -void -CBuyMenu_BasicButton::CBuyMenu_BasicButton(void) -{ - iType = BUTTON_TYPEID_BASIC; - bActive = TRUE; - funOnClick_Custom = NULL; - funOnShow_Custom = NULL; -} -void -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_funOnClick_Custom -){ - sName = arg_sName; - - flHotkey = arg_flHotkey; - clr = arg_clr; - clr_render = arg_clr; //good default. - - funOnClick_Custom = arg_funOnClick_Custom; //(int*)&arg_funOnClick_Custom; - funOnShow_Custom = NULL; -}//create -void -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); -}//funOnRender_Base - - - -void -CBuyMenu_BasicButton::funOnShow_Base(void) -{ - - if(funOnShow_Custom != NULL){ - //void(CBuyMenu_BasicButton* arg_this)* tempRef = funOnShow_Custom; - //(*tempRef)(_this); - funOnShow_Custom(_this); - } - -}// funOnShow_Base - - -// When this button is clicked, what does it do? -void -CBuyMenu_BasicButton::funOnClick_Base(void) -{ - - // basic button behavior. Only if our array has a non-zero length. - // Buttons of zero length don't unwrap into new buttons and can do something special, - // like go up a layer instead ("cancel"), something about configs, or buy a - // weapon/accessory. - if( ary_btn_softLength != 0i){ - - // "this"... is not already a pointer??! WHAT HERESY BEFALLS MY EYES?!!! - // nah just kidding, makes sense for QuakeC. - // setActiveLayerButton(&this); - ary_layerButtonChoice[iActiveLayer] = _this; - - // "warning F307: type mismatch: CBuyMenu_BasicButton * _this to - // CBuyMenu_BasicButton *[ary_layerButtonChoice]" - // ...????? happens if using CBuyMenu_BasicButton pointers (*) in _this above - // and the array "ary_layerButtonChoice". - iActiveLayer = iActiveLayer + 1i; - - // 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 "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). - for(int i = 0; i < ary_btn_softLength; i++){ - int nextButtonIndex = ary_btn_index[i]; - CBuyMenu_BasicButton someButton = *ary_btnTotal[nextButtonIndex]; - if(someButton.iType == BUTTON_TYPEID_WEAPON){ - CBuyMenu_WeaponButton someButto = *((CBuyMenu_WeaponButton*)ary_btnTotal[nextButtonIndex]); - someButto.bActive = TRUE; - someButto.funOnShow_Base(); - }else{ - someButton.bActive = TRUE; - someButton.funOnShow_Base(); - } - } - - }// button length check - - if(funOnClick_Custom != NULL){ - // If we have a custom click method, do it. - //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(); - -}//funOnClick_Base - - -void -CBuyMenu_WeaponButton::CBuyMenu_WeaponButton(void) -{ - // is chaining constructors ok here? No need! Done implicitly. - bActive = TRUE; - iWeaponPurchaseID = -1; //default -} -void -CBuyMenu_WeaponButton::create_WeaponButton -( - 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 -){ - - //defaults. - //_this_deref.iLayer = 0i; - ary_btn_softLength = 0i; - - - sName = arg_sName; - - flHotkey = arg_flHotkey; - clr = arg_clr; - clr_render = arg_clr; //good default. - - 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. - sWeaponImagePath = sprintf("%s_0.tga", arg_sWeaponImagePath); - - iWeaponPrice = arg_iWeaponPrice; - iWeaponSlots = arg_iWeaponSlots; - - iBitsWeaponOpt = arg_iBitsWeaponOpt; - - //Use that flag to determine what butttons to give me. - - iType = BUTTON_TYPEID_WEAPON; - - //Only add subbuttons (buy, upgrades, etc.) if this lacks the INSTANT option. - if( !(iBitsWeaponOpt & BITS_WEAPONOPT_INSTANT)){ - - //Every weapon has at least a "Buy" button. - buymenu_addbutton(_this, &buymenu_btn_WeaponOpt_Buy); - - if(iBitsWeaponOpt & BITS_WEAPONOPT_SILENCER){ - buymenu_addbutton(_this, &buymenu_btn_WeaponOpt_Silencer); - } - if(iBitsWeaponOpt & BITS_WEAPONOPT_LASERSIGHT){ - buymenu_addbutton(_this, &buymenu_btn_WeaponOpt_Lasersight); - } - if(iBitsWeaponOpt & BITS_WEAPONOPT_FLASHLIGHT){ - buymenu_addbutton(_this, &buymenu_btn_WeaponOpt_Flashlight); - } - if(iBitsWeaponOpt & BITS_WEAPONOPT_SCOPE){ - buymenu_addbutton(_this, &buymenu_btn_WeaponOpt_Scope); - } - if(iBitsWeaponOpt & BITS_WEAPONOPT_AKIMBO){ - buymenu_addbutton(_this, &buymenu_btn_WeaponOpt_Akimbo); - } - if(iBitsWeaponOpt & BITS_WEAPONOPT_FULLLOAD){ - buymenu_addbutton(_this, &buymenu_btn_WeaponOpt_FullLoad); - } - }//BITS_WEAPONOPT_INSTANT check - -}//create_WeaponButton - - -void -CBuyMenu_WeaponButton::funOnRender_Base -( - vector arg_suggestedDrawPos, int arg_iLayer, int arg_iButtonRow, - BOOL arg_fIsSelected -) -{ - CBuyMenu_BasicButton::funOnRender_Base( - arg_suggestedDrawPos, arg_iLayer, arg_iButtonRow, arg_fIsSelected - ); //call the parent's. - - // I want to draw my sWeaponImagePath above myself. - if(arg_fIsSelected && !(iBitsWeaponOpt & BITS_WEAPONOPT_INSTANT) ){ - - vector arg_buttonPos = [ - video_mins[0] + 5 + - arg_iLayer * (vButtonSizStandard.x + 1), video_mins[1] + video_res[1]/2 + arg_iButtonRow * (vButtonSizStandard.y + 1) - ]; - - float arg_opac; - if(arg_fIsSelected || arg_iLayer == iActiveLayer){ - arg_opac = 0.96; - }else{ - arg_opac = 0.71; - } - - vector textDrawOrigin = [arg_suggestedDrawPos.x + LABEL_OFFSET_X + 128, (video_res[1]/2) + LABEL_OFFSET_Y - (48 + 1)]; - - // NOTICE - draw on top of all buttons on this row unconditionally. Don't use arg_suggestedDrawPos.y - drawsubpic([arg_buttonPos.x, (video_res[1]/2) - (48 + 1)], [128,48], sWeaponImagePath, [0,0], [128/128,48/48], clrPaleBlue, 0.96, DRAWFLAG_ADDITIVE); - - string drawString1 = sprintf("%i Credits", iWeaponPrice); - string drawString2 = sprintf("%i Slots", iWeaponSlots); - - drawfill( [arg_buttonPos.x, (video_res[1]/2) - (48 + 1)], [256-1, 48], this.clr * 0.93f, arg_opac - 0.60f, DRAWFLAG_NORMAL ); - - Gfx_Text( textDrawOrigin, drawString1, vButtonFontSize, this.clr * 0.98f, (1.0f-(1.0f - arg_opac)*0.88) - 0.02f, DRAWFLAG_NORMAL, FONT_ARIAL_STD ); - 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 ); - - } -}//funOnRender_Base - - -// convenient way to reset these globals for keeping track of a purchase in progress. -// Leaving the buy screen or getting out of a weapon should reset them. -void -UI_BuyMenu_ResetTempVariables(void) -{ - iWeaponTempID = -1; - iBitsUpgradeTemp = BITS_WEAPONOPT_NONE; - iExtraPriceTemp = 0; - iExtraSlotsTemp = 0; - iPurchaseCountTemp = 1; -}// UI_BuyMenu_ResetTempVariables - - -void -CBuyMenu_WeaponButton::funOnShow_Base(void) -{ - CBuyMenu_BasicButton::funOnShow_Base(); - // See if this weapon can be afforded. - if(canBuyWeapon(iWeaponPurchaseID, 0, 0, 1)){ - clr_render = clr; - }else{ - // same, but draw it red to show we can't afford it at a glance. - clr_render = clrRed; - } -}//funOnShow_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 - // upgrade choices) - UI_BuyMenu_ResetTempVariables(); - // and, thie tempCost starts at the value of this weapon as stated. - if(iWeaponPurchaseID == -1){ - return; - } - weaponRef = (*ary_weaponData[iWeaponPurchaseID]); - if(!(iBitsWeaponOpt & BITS_WEAPONOPT_INSTANT)){ - // normal behavior. - iWeaponTempID = iWeaponPurchaseID; - CBuyMenu_BasicButton::funOnClick_Base(); - }else{ - // has the instant flag? that's it, apply it if we can. - if(canBuyWeapon(iWeaponPurchaseID, 0, 0, 1) ){ - BOOL addSuccess = attemptAddWeaponToConfig(iWeaponPurchaseID, BITS_WEAPONOPT_NONE, 1); - if(addSuccess){ - //and then go back. - buymenu_backOneLayer(); - buymenu_btn_Back_updateText(); - } - } - } -}//funOnClick_Base - void buymenu_btn_Back_clicked(CBuyMenu_BasicButton* arg_this) @@ -850,7 +979,7 @@ buymenu_backOneLayer(void) // layer and then advances the active layer. ary_layerButtonChoice[iActiveLayer - 1] = NULL; - iActiveLayer = iActiveLayer - 1i; //drop a layer. + iActiveLayer = iActiveLayer - 1; //drop a layer. }//buymenu_backOneLayer @@ -891,13 +1020,13 @@ void setupRemoveButtonList(void) { for(int i = 0; i < ary_myWeapons_length; i++){ - ary_btn_removeButton[i] = spawn(CBuyMenu_RemoveWeaponButton); + //ary_btn_removeButton[i] = spawn(CBuyMenu_RemoveWeaponButton); + CBuyMenu_RemoveWeaponButton_instantiate(&ary_btn_removeButton[i]); // basic init without the ".create" call. That gives the button its actual properties, // which will change as things are deleted or the "Remove Items" button is returned to. - ary_btn_removeButton[i].setThisPointer(&ary_btn_removeButton[i]); - buymenu_addbuttonToTotal(&ary_btn_removeButton[i]); - buymenu_addbutton(&buymenu_btn_RemoveItem, &ary_btn_removeButton[i]); + buymenu_addbuttonToTotal((CBuyMenu_BasicButton*)&ary_btn_removeButton[i]); + buymenu_addbutton(&buymenu_btn_RemoveItem, (CBuyMenu_BasicButton*)&ary_btn_removeButton[i]); } }// setupRemoveButtonList @@ -905,9 +1034,9 @@ setupRemoveButtonList(void) void buymenu_btn_removeButton_clicked(CBuyMenu_BasicButton* arg_this) { - CBuyMenu_RemoveWeaponButton removeWeaponButtonRef = *( (CBuyMenu_RemoveWeaponButton*)arg_this ); - removeWeaponFromConfig(removeWeaponButtonRef.linkedConfigIndex); - //and refresh this area. + CBuyMenu_RemoveWeaponButton* removeWeaponButtonRef = (CBuyMenu_RemoveWeaponButton*)arg_this; + removeWeaponFromConfig(removeWeaponButtonRef->linkedConfigIndex); + // and refresh this area. buymenu_btn_RemoveItem_clicked(&buymenu_btn_RemoveItem); } @@ -936,7 +1065,7 @@ buymenu_btn_RemoveItem_clicked(CBuyMenu_BasicButton* arg_this) int hotKeyCode; if(i < 9) { - //for i choices 0 through 8, use "i+1" to give 1-9. + // for i choices 0 through 8, use "i+1" to give 1-9. buttonDisplayText = sprintf("%i: %s", (i+1i), basicRef.sDisplayName); hotKeyCode = 48+(i+1); // '0' + (i+1) } @@ -954,7 +1083,8 @@ 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); + CBuyMenu_BasicButton_create((CBuyMenu_BasicButton*)&ary_btn_removeButton[i], buttonDisplayText, hotKeyCode, clrPaleBlue, &buymenu_btn_removeButton_clicked); ary_btn_removeButton[i].bActive = TRUE; //CBuyMenu_RemoveWeaponButton removeWeaponButtonRef2 = (CBuyMenu_RemoveWeaponButton)ary_btn_removeButton[i]; @@ -975,25 +1105,26 @@ refreshButtons(void) { int i; int i2; - CBuyMenu_BasicButton previousLayerButton; - CBuyMenu_BasicButton tempButton; + CBuyMenu_BasicButton* previousLayerButton; + CBuyMenu_BasicButton* tempButton; for(i = 0; i <= iActiveLayer; i++){ if(i == 0){ - //CBuyMenu_BasicButton tempButton = *ary_layerFirstButton[i2]; for(i2 = 0; i2 < ary_layerFirstButton_softLength; i2++){ - tempButton = *ary_layerFirstButton[i2]; - tempButton.funOnShow_Base(); + tempButton = ary_layerFirstButton[i2]; + //tempButton.funOnShow_Base(); + CBuyMenu_BasicButton_funOnShow_Base_vcall(tempButton); }// for i2 in ary_layerFirstButton }else{ - previousLayerButton = *ary_layerButtonChoice[i - 1i]; + previousLayerButton = ary_layerButtonChoice[i - 1]; - for(i2 = 0i; i2 < previousLayerButton.ary_btn_softLength; i2 = i2+1i){ - //btnToRender = &previousLayerButton.ary_btn[i2]; - int btnToRender_index_global = previousLayerButton.ary_btn_index[i2]; - tempButton = *ary_btnTotal[btnToRender_index_global]; - tempButton.funOnShow_Base(); + for(i2 = 0i; i2 < previousLayerButton->ary_btn_softLength; i2 = i2+1){ + //btnToRender = &previousLayerButton->ary_btn[i2]; + int btnToRender_index_global = previousLayerButton->ary_btn_index[i2]; + tempButton = ary_btnTotal[btnToRender_index_global]; + //tempButton.funOnShow_Base(); + CBuyMenu_BasicButton_funOnShow_Base_vcall(tempButton); } } } @@ -1046,9 +1177,7 @@ buymenu_btn_UseNewConfig_clicked(CBuyMenu_BasicButton* arg_this) void buymenu_btn_Buy_onShow(CBuyMenu_BasicButton* arg_this) -{ - CBuyMenu_BasicButton thisTemp = *arg_this; - +{ // uhhh. Why did I do this again? Clarity? int arg_extraPrice = 0; int arg_extraSlots = 0; @@ -1059,9 +1188,9 @@ buymenu_btn_Buy_onShow(CBuyMenu_BasicButton* arg_this) weapondata_basic_t weaponRef = *( (weapondata_basic_t*) ary_weaponData[iWeaponTempID]); if(canBuyWeapon(iWeaponTempID, finalExtraPrice, finalExtraSlots, 1)){ - thisTemp.clr_render = thisTemp.clr; + arg_this->clr_render = arg_this->clr; }else{ - thisTemp.clr_render = clrRed; + arg_this->clr_render = clrRed; } } @@ -1069,67 +1198,60 @@ buymenu_btn_Buy_onShow(CBuyMenu_BasicButton* arg_this) void buymenu_btn_Silencer_onShow(CBuyMenu_BasicButton* arg_this) { - CBuyMenu_BasicButton thisTemp = *arg_this; // See if this buyopt's additional cost can be afforded. if(canBuyWeapon(iWeaponTempID, iExtraPriceTemp + WEAPONOPT_SILENCER_COST, 0, 1)){ - thisTemp.clr_render = thisTemp.clr; + arg_this->clr_render = arg_this->clr; }else{ - thisTemp.clr_render = clrRed; + arg_this->clr_render = clrRed; } } void buymenu_btn_Lasersight_onShow(CBuyMenu_BasicButton* arg_this) { - CBuyMenu_BasicButton thisTemp = *arg_this; if(canBuyWeapon(iWeaponTempID, iExtraPriceTemp + WEAPONOPT_LASERSIGHT_COST, 0, 1)){ - thisTemp.clr_render = thisTemp.clr; + arg_this->clr_render = arg_this->clr; }else{ - thisTemp.clr_render = clrRed; + arg_this->clr_render = clrRed; } } void buymenu_btn_Flashlight_onShow(CBuyMenu_BasicButton* arg_this) { - CBuyMenu_BasicButton thisTemp = *arg_this; if(canBuyWeapon(iWeaponTempID, iExtraPriceTemp + WEAPONOPT_FLASHLIGHT_COST, 0, 1)){ - thisTemp.clr_render = thisTemp.clr; + arg_this->clr_render = arg_this->clr; }else{ - thisTemp.clr_render = clrRed; + arg_this->clr_render = clrRed; } } void buymenu_btn_Scope_onShow(CBuyMenu_BasicButton* arg_this) { - CBuyMenu_BasicButton thisTemp = *arg_this; if(canBuyWeapon(iWeaponTempID, iExtraPriceTemp + WEAPONOPT_SCOPE_COST, 0, 1)){ - thisTemp.clr_render = thisTemp.clr; + arg_this->clr_render = arg_this->clr; }else{ - thisTemp.clr_render = clrRed; + arg_this->clr_render = clrRed; } } void buymenu_btn_Akimbo_onShow(CBuyMenu_BasicButton* arg_this) { - CBuyMenu_BasicButton thisTemp = *arg_this; - //Can we afford one more copy of this weapon? weapondata_basic_t weaponRef = (*ary_weaponData[iWeaponTempID]); if(canBuyWeapon(iWeaponTempID, iExtraPriceTemp + weaponRef.iPrice, iExtraSlotsTemp + weaponRef.iSlots, iPurchaseCountTemp)){ - thisTemp.clr_render = thisTemp.clr; + arg_this->clr_render = arg_this->clr; }else{ - thisTemp.clr_render = clrRed; + arg_this->clr_render = clrRed; } } void buymenu_btn_FullLoad_onShow(CBuyMenu_BasicButton* arg_this) { - CBuyMenu_BasicButton thisTemp = *arg_this; //I'm not copying and pasting this stuff all over the place. int buyCount = fullLoadCountToBuy(iWeaponTempID); if(buyCount >= 0){ @@ -1138,14 +1260,14 @@ buymenu_btn_FullLoad_onShow(CBuyMenu_BasicButton* arg_this) int testPrice = (buyCount) * weaponRef.iPrice; int testSlots = (buyCount) * weaponRef.iSlots; if(canBuyWeapon(iWeaponTempID, iExtraPriceTemp + testPrice, iExtraSlotsTemp + testSlots, iPurchaseCountTemp)){ - thisTemp.clr_render = thisTemp.clr; + arg_this->clr_render = arg_this->clr; }else{ - thisTemp.clr_render = clrRed; + arg_this->clr_render = clrRed; } }else{ //assume there is nothing else to buy? - thisTemp.clr_render = thisTemp.clr; + arg_this->clr_render = arg_this->clr; } }//buymenu_btn_FullLoad_clicked @@ -1154,11 +1276,10 @@ void buymenu_btn_Silencer_clicked(CBuyMenu_BasicButton* arg_this) { if(canBuyWeapon(iWeaponTempID, iExtraPriceTemp + WEAPONOPT_SILENCER_COST, iExtraSlotsTemp, iPurchaseCountTemp)){ - CBuyMenu_BasicButton thisTemp = *arg_this; //allow it and hide this button. iBitsUpgradeTemp |= BITS_WEAPONOPT_SILENCER; iExtraPriceTemp += WEAPONOPT_SILENCER_COST; - thisTemp.bActive = FALSE; + arg_this->bActive = FALSE; refreshButtons(); } } @@ -1168,11 +1289,10 @@ buymenu_btn_Lasersight_clicked(CBuyMenu_BasicButton* arg_this) { if(canBuyWeapon(iWeaponTempID, iExtraPriceTemp + WEAPONOPT_LASERSIGHT_COST, iExtraSlotsTemp, iPurchaseCountTemp)){ - CBuyMenu_BasicButton thisTemp = *arg_this; //allow it and hide this button. iBitsUpgradeTemp |= BITS_WEAPONOPT_LASERSIGHT; iExtraPriceTemp += WEAPONOPT_LASERSIGHT_COST; - thisTemp.bActive = FALSE; + arg_this->bActive = FALSE; refreshButtons(); } } @@ -1182,11 +1302,10 @@ buymenu_btn_Flashlight_clicked(CBuyMenu_BasicButton* arg_this) { if(canBuyWeapon(iWeaponTempID, iExtraPriceTemp + WEAPONOPT_FLASHLIGHT_COST, iExtraSlotsTemp, iPurchaseCountTemp)){ - CBuyMenu_BasicButton thisTemp = *arg_this; // allow it and hide this button. iBitsUpgradeTemp |= BITS_WEAPONOPT_FLASHLIGHT; iExtraPriceTemp += WEAPONOPT_FLASHLIGHT_COST; - thisTemp.bActive = FALSE; + arg_this->bActive = FALSE; refreshButtons(); } } @@ -1195,11 +1314,10 @@ void buymenu_btn_Scope_clicked(CBuyMenu_BasicButton* arg_this) { if(canBuyWeapon(iWeaponTempID, iExtraPriceTemp + WEAPONOPT_SCOPE_COST, iExtraSlotsTemp, iPurchaseCountTemp)){ - CBuyMenu_BasicButton thisTemp = *arg_this; // allow it and hide this button. iBitsUpgradeTemp |= BITS_WEAPONOPT_SCOPE; iExtraPriceTemp += WEAPONOPT_SCOPE_COST; - thisTemp.bActive = FALSE; + arg_this->bActive = FALSE; refreshButtons(); } } @@ -1210,12 +1328,11 @@ buymenu_btn_Akimbo_clicked(CBuyMenu_BasicButton* arg_this) weapondata_basic_t weaponRef = (*ary_weaponData[iWeaponTempID]); if(canBuyWeapon(iWeaponTempID, iExtraPriceTemp + weaponRef.iPrice, iExtraSlotsTemp + weaponRef.iSlots, iPurchaseCountTemp)){ - CBuyMenu_BasicButton thisTemp = *arg_this; // allow it and hide this button. iBitsUpgradeTemp |= BITS_WEAPONOPT_AKIMBO; iExtraPriceTemp += weaponRef.iPrice; iExtraSlotsTemp += weaponRef.iSlots; - thisTemp.bActive = FALSE; + arg_this->bActive = FALSE; refreshButtons(); } } @@ -1234,7 +1351,6 @@ buymenu_btn_FullLoad_clicked(CBuyMenu_BasicButton* arg_this) int buyCount = fullLoadCountToBuy(iWeaponTempID); if(buyCount >= 0){ - CBuyMenu_BasicButton thisTemp; weapondata_basic_t weaponRef = (*ary_weaponData[iWeaponTempID]); int testPrice = (buyCount) * weaponRef.iPrice; @@ -1244,12 +1360,11 @@ buymenu_btn_FullLoad_clicked(CBuyMenu_BasicButton* arg_this) int finalExtraSlots = iExtraSlotsTemp + testSlots; if(canBuyWeapon(iWeaponTempID, finalExtraPrice, finalExtraSlots, iPurchaseCountTemp)){ - thisTemp = *arg_this; // allow it and hide this button. iBitsUpgradeTemp |= BITS_WEAPONOPT_FULLLOAD; iExtraPriceTemp += testPrice; iExtraSlotsTemp += testSlots; - thisTemp.bActive = FALSE; + arg_this->bActive = FALSE; // Go ahead and buy this now. buymenu_btn_Buy_Weapon_clicked((CBuyMenu_BasicButton*)&buymenu_btn_WeaponOpt_Buy); @@ -1271,14 +1386,13 @@ buymenu_btn_FullLoad_clicked(CBuyMenu_BasicButton* arg_this) if(numberAfforded > 0){ //do something! - thisTemp = *arg_this; //iBitsUpgradeTemp |= BITS_WEAPONOPT_FULLLOAD; iPurchaseCountTemp = numberAfforded; // no need for extra price/slot stuff! We'll make that from that // altered 'iPurchaseCountTemp'. // That is ever rarely anything besides '1'. Except for this case of // course. - thisTemp.bActive = FALSE; + arg_this->bActive = FALSE; buymenu_btn_Buy_Weapon_clicked( (CBuyMenu_BasicButton*) &buymenu_btn_WeaponOpt_Buy); refreshButtons(); @@ -1302,7 +1416,7 @@ UI_BuyMenu_Show(void) buymenu_btn_Back_updateText(); // just in case? - for(int i = 0i; i < ary_layerButtonChoice.length; i+=1i){ + for(int i = 0i; i < ary_layerButtonChoice.length; i+=1){ ary_layerButtonChoice[i] = NULL; } } @@ -1326,12 +1440,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 +1458,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.funOnShow_Custom = buymenu_btn_Buy_onShow; + buymenu_btn_WeaponOpt_Buy.funOnShow_Custom = &buymenu_btn_Buy_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; + 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 @@ -1472,8 +1586,8 @@ UI_BuyMenu_Draw(void) int currentLayerSelectedIndex; int btnToRender_index_global; - CBuyMenu_BasicButton someThing; - CBuyMenu_BasicButton previousLayerButton; + CBuyMenu_BasicButton* someThing; + CBuyMenu_BasicButton* previousLayerButton; BOOL fIsSelected = FALSE; @@ -1493,7 +1607,7 @@ UI_BuyMenu_Draw(void) drawPlayerInventory(TRUE); - for(int i = 0i; i <= iActiveLayer; i = i + 1i){ + for(int i = 0i; i <= iActiveLayer; i = i + 1){ //Adjust these as needed. These also show where to draw the "0 Cancel" button //for the active layer (after the most recent button; below). //vector vBtnPos; @@ -1503,18 +1617,18 @@ UI_BuyMenu_Draw(void) if(ary_layerButtonChoice[i] == NULL){ currentLayerSelectedIndex = -1; }else{ - someThing = *ary_layerButtonChoice[i]; - currentLayerSelectedIndex = someThing.iGlobalIndex; + someThing = ary_layerButtonChoice[i]; + currentLayerSelectedIndex = someThing->iGlobalIndex; } vBtnPos.x = (int)vButtonPos.x; //default pos. vBtnPos.y = (int)vButtonPos.y; for(int i2 = 0i; i2 < ary_layerFirstButton_softLength; i2++){ - CBuyMenu_BasicButton tempButton = *ary_layerFirstButton[i2]; + CBuyMenu_BasicButton* tempButton = ary_layerFirstButton[i2]; fIsSelected = (tempButton.iGlobalIndex == currentLayerSelectedIndex); - (*ary_layerFirstButton[i2]).funOnRender_Base(vBtnPos, i, i2, fIsSelected); + CBuyMenu_BasicButton_funOnRender_Base_vcall(ary_layerFirstButton[i2], vBtnPos, i, i2, fIsSelected); vBtnPos.y += (vButtonSizStandard.y + 1); @@ -1525,30 +1639,31 @@ UI_BuyMenu_Draw(void) vBtnPos.y = (int)vButtonPos.y; // All other layers only render buttons that the previous layer (selected button there) tells them to. - previousLayerButton = *ary_layerButtonChoice[i - 1i]; + previousLayerButton = ary_layerButtonChoice[i - 1]; if(ary_layerButtonChoice[i] == NULL){ currentLayerSelectedIndex = -1; }else{ - someThing = *ary_layerButtonChoice[i]; - currentLayerSelectedIndex = someThing.iGlobalIndex; + someThing = ary_layerButtonChoice[i]; + currentLayerSelectedIndex = someThing->iGlobalIndex; } - for(int i2 = 0i; i2 < previousLayerButton.ary_btn_softLength; i2 = i2+1i){ - btnToRender_index_global = previousLayerButton.ary_btn_index[i2]; + for(int i2 = 0i; i2 < previousLayerButton->ary_btn_softLength; i2 = i2+1){ + btnToRender_index_global = previousLayerButton->ary_btn_index[i2]; - CBuyMenu_BasicButton tempButton2_aaa = *ary_btnTotal[btnToRender_index_global]; + CBuyMenu_BasicButton* tempButton2_aaa = ary_btnTotal[btnToRender_index_global]; //NOTICE - we can only check for bActive in the active layer. Any others must show // all buttons yet. - if(i == iActiveLayer && tempButton2_aaa.bActive == FALSE){ + if(i == iActiveLayer && tempButton2_aaa->bActive == FALSE){ //skip showing this one. continue; } fIsSelected = (btnToRender_index_global == currentLayerSelectedIndex); - (*ary_btnTotal[btnToRender_index_global]).funOnRender_Base(vBtnPos, i, i2, fIsSelected); + CBuyMenu_BasicButton_funOnRender_Base_vcall(ary_btnTotal[btnToRender_index_global], vBtnPos, i, i2, fIsSelected); + vBtnPos.y += (vButtonSizStandard.y + 1); }// for i2 in this layer's buttons. @@ -1562,13 +1677,14 @@ UI_BuyMenu_Draw(void) // Whatever the size of the latest layer is. Since that index itself wasn't used (minus 1 is the most recently used index; // we're putting a button AFTER that one). if(iActiveLayer > 0){ - previousLayerButton = *ary_layerButtonChoice[iActiveLayer - 1i]; - backButtonRow = previousLayerButton.ary_btn_softLength; + previousLayerButton = ary_layerButtonChoice[iActiveLayer - 1]; + backButtonRow = previousLayerButton->ary_btn_softLength; }else{ backButtonRow = ary_layerFirstButton_softLength; } - buymenu_btn_Back.funOnRender_Base(vBtnPos, i, backButtonRow, fIsSelected); + //buymenu_btn_Back.funOnRender_Base(vBtnPos, i, backButtonRow, fIsSelected); + CBuyMenu_BasicButton_funOnRender_Base_vcall(&buymenu_btn_Back, vBtnPos, i, backButtonRow, fIsSelected); vBtnPos.y += (vButtonSizStandard.y + 1); } diff --git a/src/shared/ammo.h b/src/shared/ammo.h index b82f61b..fcf10d4 100644 --- a/src/shared/ammo.h +++ b/src/shared/ammo.h @@ -1,13 +1,4 @@ -#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}; - -#define ASSIGN_MUZZLEFLASHDATA(arg_constName) ary_muzzleFlashData[MUZZLEFLASH_ID::##arg_constName] = (muzzleflashdata_t*) &muzzleflash_##arg_constName; -#define DECLARE_MUZZLEFLASHDATA(arg_varName, arg_sSpritePath) var muzzleflashdata_t muzzleflash_##arg_varName = {0, arg_sSpritePath}; - enum AMMO_ID{ NONE = 0, diff --git a/src/shared/ammo.qc b/src/shared/ammo.qc index 23a1ef2..0123a68 100644 --- a/src/shared/ammo.qc +++ b/src/shared/ammo.qc @@ -1,4 +1,14 @@ +#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}; + +#define ASSIGN_MUZZLEFLASHDATA(arg_constName) ary_muzzleFlashData[MUZZLEFLASH_ID::##arg_constName] = (muzzleflashdata_t*) &muzzleflash_##arg_constName; +#define DECLARE_MUZZLEFLASHDATA(arg_varName, arg_sSpritePath) var muzzleflashdata_t muzzleflash_##arg_varName = {0, arg_sSpritePath}; + + DECLARE_AMMODATA(NONE, "_NONE_", 0, 0) DECLARE_AMMODATA(_9X19MM, "9 x 19mm", 1.6666666666, 210) DECLARE_AMMODATA(_45ACP, ".45Acp", 5.1, 200) diff --git a/src/shared/player.h b/src/shared/player.h index 56f0697..1fcbf88 100644 --- a/src/shared/player.h +++ b/src/shared/player.h @@ -155,7 +155,9 @@ class player:base_player int recentLaserDistanceDisplay; + // does anything use this? BOOL forceViewModelUpdate; + // NOTICE - individual dynamic weapons have "iForceBodygroup1Submodel". // "prev_iForceBodygroup1Submodel" is player-wide (here) instead because we only need to // keep track of changes in a weapon's iForceBodygroup1Submodel while that weapon is @@ -224,8 +226,13 @@ class player:base_player PREDICTED_INT(iMeleeCycler); - //SHARED!!! + // SHARED vector vViewAngleOffsetTarget; + vector vViewAngleOffsetTarget1; + vector vViewAngleOffsetTarget2; + vector vViewAngleOffsetTarget3; + vector vViewAngleOffsetTarget4; + PREDICTED_FLOAT(fAccuracyKickback); PREDICTED_FLOAT(fAccuracyKickbackStartCooldown); diff --git a/src/shared/util.h b/src/shared/util.h index d377349..e04ff2a 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -236,6 +236,11 @@ if (pl.inputSecondaryTapFrameCount == 0)\ #define GET_VIEW_ANGLES pl.v_angle #endif +#ifdef CLIENT +#define GET_MY_VIEW_ANGLES view_angles +#else +#define GET_MY_VIEW_ANGLES this.v_angle +#endif // OLD UNDERWATER CHECK. Using a new var for more accuracy. diff --git a/src/shared/weapons.h b/src/shared/weapons.h index a25f4cb..36a1e5d 100644 --- a/src/shared/weapons.h +++ b/src/shared/weapons.h @@ -1,8 +1,5 @@ -class player; - - // Doing at least this because nuclide's src/server/weapons.qc // still expects it to exist. @@ -11,6 +8,90 @@ class player; // inventory element. #define WEAPON_NONE 0 +// Any preference for macro constants or 'enumflags', whatever does the auto-power-of-2? +// No idea, doing macros for now + + +#define BITS_AKIMBOCHOICE_NONE 0 +#define BITS_AKIMBOCHOICE_LEFT 1 +#define BITS_AKIMBOCHOICE_RIGHT 2 +#define BITS_AKIMBOCHOICE_BOTH (BITS_AKIMBOCHOICE_LEFT | BITS_AKIMBOCHOICE_RIGHT) + + + +// Firemodes, normal +// melee weapons don't really do firemode. +// Can be used for burst-fire bullets too for bypassing some requirements. +#define BITS_FIREMODE_NONE 0 +#define BITS_FIREMODE_BURST 1 +#define BITS_FIREMODE_FULL 2 +#define BITS_FIREMODE_SEMI 4 +#define BITS_FIREMODE_PUMP 8 + + +// Akimbo firemodes +#define BITS_FIREMODE_AKIMBO_NONE 0 +#define BITS_FIREMODE_AKIMBO_SEMI_AUTO 1 +#define BITS_FIREMODE_AKIMBO_FREE_SEMI 2 +#define BITS_FIREMODE_AKIMBO_FULL_AUTO 4 +#define BITS_FIREMODE_AKIMBO_FREE_FULL 8 + + + +#define BITS_WEAPONOPT_NONE 0x00 +#define BITS_WEAPONOPT_SILENCER 0x01 +#define BITS_WEAPONOPT_LASERSIGHT 0x02 +#define BITS_WEAPONOPT_FLASHLIGHT 0x04 +#define BITS_WEAPONOPT_SCOPE 0x08 +#define BITS_WEAPONOPT_AKIMBO 0x10 +#define BITS_WEAPONOPT_FULLLOAD 0x20 + +// This is a special flag to say, skip showing buyoptions altogether. The buy button goes straight to +// buying the weapon. +//good for items (stealh shoes, kevlar) +#define BITS_WEAPONOPT_INSTANT 0x80000000 + +// Types of weapons that, if present, can be toggled on/off by the player. Only some can. +// A lot of other behavior about this isn't automatic though, a change here does little elsewhere. +#define BITMASK_WEAPONOPT_TOGGLEABLE BITS_WEAPONOPT_LASERSIGHT | BITS_WEAPONOPT_FLASHLIGHT +// only min/max order of bits. +#define BITMASK_WEAPONOPT_TOGGLEABLE_MIN BITS_WEAPONOPT_LASERSIGHT +#define BITMASK_WEAPONOPT_TOGGLEABLE_MAX BITS_WEAPONOPT_FLASHLIGHT + + +#define BUYCATEGORY_NONE 0 +#define BUYCATEGORY_HANDGUNS 1 +#define BUYCATEGORY_SMGS 2 +#define BUYCATEGORY_RIFLES 3 +#define BUYCATEGORY_SHOTGUNS 4 +#define BUYCATEGORY_SPECIALPURPOSE 5 + + + +#define WEAPONDATA_TYPEID_BASIC 0 +#define WEAPONDATA_TYPEID_GUN 1 +#define WEAPONDATA_TYPEID_IRONSIGHT 2 +//#define WEAPONDATA_TYPEID_AKIMBO 3 +#define WEAPONDATA_TYPEID_MELEE 3 +//Note that THROWABLE is knives, not grenades. +#define WEAPONDATA_TYPEID_THROWABLE 4 + + + +#define ary_myWeapons_length 16 + + + + + +class player; +class weapondynamic_t; + +// commonly used in akimbo-fire methods for weapon-specific firint script. +// Parameter list commonly looks like: +// player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed +typedef void(player, weapondynamic_t, int) MethodType_WeaponAttack; + //returned by weapon_base_onPrimaryAttack_melee to tell what type of thing was hit, since some // aspects of a hit depend on knowing this (knives & katana have different sounds for each of @@ -148,44 +229,6 @@ int ary_AKIMBO_UPGRADE_TO_WEAPON[] = { -// What akimbo weapons are involved, if asked? -// no, let's bitmask it. -/* -enum AkimboChoice{ - NONE = 0, //??? - LEFT = 1, - RIGHT = 2, - BOTH = 3 -}; -*/ -#define BITS_AKIMBOCHOICE_NONE 0 -#define BITS_AKIMBOCHOICE_LEFT 1 -#define BITS_AKIMBOCHOICE_RIGHT 2 -#define BITS_AKIMBOCHOICE_BOTH (BITS_AKIMBOCHOICE_LEFT | BITS_AKIMBOCHOICE_RIGHT) - - - - -// melee weapons don't really do firemode. -// Can be used for burst-fire bullets too for bypassing some requirements. -#define BITS_FIREMODE_NONE 0 - -#define BITS_FIREMODE_BURST 1 -#define BITS_FIREMODE_FULL 2 -#define BITS_FIREMODE_SEMI 4 -#define BITS_FIREMODE_PUMP 8 - - -//AKIMBO - -//??? -#define BITS_FIREMODE_AKIMBO_NONE 0 - -#define BITS_FIREMODE_AKIMBO_SEMI_AUTO 1 -#define BITS_FIREMODE_AKIMBO_FREE_SEMI 2 -#define BITS_FIREMODE_AKIMBO_FULL_AUTO 4 -#define BITS_FIREMODE_AKIMBO_FREE_FULL 8 - //string getFiremodeName(int firemodeBit); //string getAkimboFiremodeName(int firemodeBit); @@ -220,59 +263,6 @@ string getAkimboFiremodeName(int firemodeBit){ -#define BITS_WEAPONOPT_NONE 0x00 -#define BITS_WEAPONOPT_SILENCER 0x01 -#define BITS_WEAPONOPT_LASERSIGHT 0x02 -#define BITS_WEAPONOPT_FLASHLIGHT 0x04 -#define BITS_WEAPONOPT_SCOPE 0x08 -#define BITS_WEAPONOPT_AKIMBO 0x10 -#define BITS_WEAPONOPT_FULLLOAD 0x20 - -// This is a special flag to say, skip showing buyoptions altogether. The buy button goes straight to -// buying the weapon. -//good for items (stealh shoes, kevlar) -#define BITS_WEAPONOPT_INSTANT 0x80000000 - -// Types of weapons that, if present, can be toggled on/off by the player. Only some can. -// A lot of other behavior about this isn't automatic though, a change here does little elsewhere. -#define BITMASK_WEAPONOPT_TOGGLEABLE BITS_WEAPONOPT_LASERSIGHT | BITS_WEAPONOPT_FLASHLIGHT -// only min/max order of bits. -#define BITMASK_WEAPONOPT_TOGGLEABLE_MIN BITS_WEAPONOPT_LASERSIGHT -#define BITMASK_WEAPONOPT_TOGGLEABLE_MAX BITS_WEAPONOPT_FLASHLIGHT - - -#define BUYCATEGORY_NONE 0 -#define BUYCATEGORY_HANDGUNS 1 -#define BUYCATEGORY_SMGS 2 -#define BUYCATEGORY_RIFLES 3 -#define BUYCATEGORY_SHOTGUNS 4 -#define BUYCATEGORY_SPECIALPURPOSE 5 - - - -#define WEAPONDATA_TYPEID_BASIC 0 -#define WEAPONDATA_TYPEID_GUN 1 -#define WEAPONDATA_TYPEID_IRONSIGHT 2 -//#define WEAPONDATA_TYPEID_AKIMBO 3 -#define WEAPONDATA_TYPEID_MELEE 3 -//Note that THROWABLE is knives, not grenades. -#define WEAPONDATA_TYPEID_THROWABLE 4 - - - -#define ASSIGN_WEAPONDATA(arg_constName, arg_weaponName) ary_weaponData[WEAPON_ID::##arg_constName] = (weapondata_basic_t*) &weapon_##arg_weaponName; - -// NOTICE - the ID lacks the "_akimbo" suffix. The actual variable name has the "_akimbo" suffix. -// Just provide the name of the weapon without the "_akimbo" suffix and it will be added as needed -// automatically. -#define ASSIGN_AKIMBOUPGRADEDATA(arg_constName, arg_weaponName) ary_akimboUpgradeData[WEAPON_AKIMBO_UPGRADE_ID::##arg_constName] = (weapondata_basic_t*) &weapon_##arg_weaponName##_akimbo; - - - -#define ary_myWeapons_length 16 - - - ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////// @@ -824,16 +814,16 @@ BOOL weapon_shotgun_onInterrupt(player pl, weapondata_basic_t* basePRef, weapond 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); +void weapon_gun_akimbo_semi_primaryAttack(MethodType_WeaponAttack arg_funAttack); +void weapon_gun_akimbo_semi_secondaryAttack(MethodType_WeaponAttack arg_funAttack); +void weapon_ironsight_akimbo_semi_secondaryAttack(MethodType_WeaponAttack arg_funAttack, int arg_weaponTypeID); -void weapon_gun_akimbo_full_primaryAttack(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); +void weapon_gun_akimbo_full_primaryAttack(MethodType_WeaponAttack arg_funAttack); +void weapon_gun_akimbo_full_secondaryAttack(MethodType_WeaponAttack arg_funAttack); -BOOL weapon_akimbo_semiAttackDualHack(player pl, weapondynamic_t arg_thisWeapon, int arg_flagger, 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); +BOOL weapon_akimbo_semiAttackDualHack(player pl, weapondynamic_t arg_thisWeapon, int arg_flagger, MethodType_WeaponAttack arg_funAttack); +BOOL weapon_akimbo_fullAttackDualHack(player pl, weapondynamic_t arg_thisWeapon, int arg_flagger, MethodType_WeaponAttack arg_funAttack); +BOOL weapon_akimbo_AttackDualHack(player pl, weapondynamic_t arg_thisWeapon, int arg_flagger, MethodType_WeaponAttack arg_funAttack); int weapon_akimbo_semiAttackChoice(player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon, int attackTypeUsed); int weapon_akimbo_fullAttackChoice(player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon, int attackTypeUsed); diff --git a/src/shared/weapons.qc b/src/shared/weapons.qc index 64cd573..e0e0a2d 100644 --- a/src/shared/weapons.qc +++ b/src/shared/weapons.qc @@ -1,4 +1,17 @@ + + +#define ASSIGN_WEAPONDATA(arg_constName, arg_weaponName) ary_weaponData[WEAPON_ID::##arg_constName] = (weapondata_basic_t*) &weapon_##arg_weaponName; + +// NOTICE - the ID lacks the "_akimbo" suffix. The actual variable name has the "_akimbo" suffix. +// Just provide the name of the weapon without the "_akimbo" suffix and it will be added as needed +// automatically. +#define ASSIGN_AKIMBOUPGRADEDATA(arg_constName, arg_weaponName) ary_akimboUpgradeData[WEAPON_AKIMBO_UPGRADE_ID::##arg_constName] = (weapondata_basic_t*) &weapon_##arg_weaponName##_akimbo; + + + + + weapon_t w_null = {}; // Populate each slot with a member of the enum early on in runtime instead. @@ -640,7 +653,7 @@ weapon_shotgun_onThink_reloadLogic(player pl, weapondata_gun_t* basePRef, weapon // happens there. void weapon_gun_akimbo_semi_primaryAttack( - void(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed) arg_funAttack + MethodType_WeaponAttack arg_funAttack ){ player pl = (player)self; weapondynamic_t arg_thisWeapon = pl.ary_myWeapons[pl.inventoryEquippedIndex]; @@ -678,7 +691,7 @@ weapon_gun_akimbo_semi_primaryAttack( // 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 + MethodType_WeaponAttack arg_funAttack ){ player pl = (player)self; weapondynamic_t arg_thisWeapon = pl.ary_myWeapons[pl.inventoryEquippedIndex]; @@ -715,7 +728,7 @@ weapon_gun_akimbo_semi_secondaryAttack( void weapon_ironsight_akimbo_semi_secondaryAttack( - void(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed) arg_funAttack, + MethodType_WeaponAttack arg_funAttack, int arg_weaponTypeID ){ player pl = (player)self; @@ -751,14 +764,12 @@ weapon_ironsight_akimbo_semi_secondaryAttack( - - // 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 + MethodType_WeaponAttack arg_funAttack ){ player pl = (player)self; weapondynamic_t arg_thisWeapon = pl.ary_myWeapons[pl.inventoryEquippedIndex]; @@ -776,7 +787,7 @@ weapon_gun_akimbo_full_primaryAttack( void weapon_gun_akimbo_full_secondaryAttack( - void(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed) arg_funAttack + MethodType_WeaponAttack arg_funAttack ){ player pl = (player)self; weapondynamic_t arg_thisWeapon = pl.ary_myWeapons[pl.inventoryEquippedIndex]; @@ -797,7 +808,7 @@ weapon_gun_akimbo_full_secondaryAttack( BOOL weapon_akimbo_AttackDualHack( player pl, weapondynamic_t arg_thisWeapon, int arg_flagger, - void(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed) arg_funAttack + MethodType_WeaponAttack arg_funAttack ){ //printfline("WELL WHAT. %.2f, %i, %i", pl.akimboDualFireToleranceTime, pl.akimboFirePrev, arg_flagger); if(arg_flagger == 0){ @@ -870,7 +881,7 @@ weapon_akimbo_AttackDualHack( BOOL weapon_akimbo_semiAttackDualHack( player pl, weapondynamic_t arg_thisWeapon, int arg_flagger, - void(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed) arg_funAttack + MethodType_WeaponAttack arg_funAttack ){ if(arg_thisWeapon.iFireModeAkimbo == BITS_FIREMODE_AKIMBO_SEMI_AUTO){ return FALSE; @@ -884,7 +895,7 @@ weapon_akimbo_semiAttackDualHack( BOOL weapon_akimbo_fullAttackDualHack( player pl, weapondynamic_t arg_thisWeapon, int arg_flagger, - void(player pl, weapondynamic_t arg_thisWeapon, int attackTypeUsed) arg_funAttack + MethodType_WeaponAttack arg_funAttack ){ if(arg_thisWeapon.iFireModeAkimbo == BITS_FIREMODE_AKIMBO_FULL_AUTO){ return FALSE;