From: drjaska Date: Thu, 5 Sep 2024 14:27:05 +0000 (+0300) Subject: Mostly whitespace weapons cleanup chores X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=938e833e053d75e4aa271783e38c91e0ecc4e453;p=xonotic%2Fxonotic-data.pk3dir.git Mostly whitespace weapons cleanup chores --- diff --git a/qcsrc/common/weapons/all.qh b/qcsrc/common/weapons/all.qh index 02f3ab0a2..8ac7a20c8 100644 --- a/qcsrc/common/weapons/all.qh +++ b/qcsrc/common/weapons/all.qh @@ -42,55 +42,55 @@ WepSet _WepSet_FromWeapon(int i); // NOTE: dumpeffectinfo, dumpnotifs, dumpturrets and dumpweapons use similar code GENERIC_COMMAND(dumpweapons, "Dump all turrets into " DEFAULT_FILENAME, false) // WEAPONTODO: make this work with other progs than just server { - switch(request) - { - case CMD_REQUEST_COMMAND: - { - #ifdef SVQC - wep_config_file = -1; - wep_config_alsoprint = -1; - string filename = argv(1); - - if(filename == "") - { - filename = DEFAULT_FILENAME; - wep_config_alsoprint = false; - } - else if(filename == "-") - { - filename = DEFAULT_FILENAME; - wep_config_alsoprint = true; - } - wep_config_file = fopen(filename, FILE_WRITE); - - if(wep_config_file >= 0) - { - Dump_Weapon_Settings(); - LOG_INFOF("Dumping weapons... File located in ^2data/data/%s^7.", filename); - fclose(wep_config_file); - wep_config_file = -1; - wep_config_alsoprint = -1; - } - else - { - LOG_INFOF("^1Error: ^7Could not open file '%s'!", filename); - } - #else - LOG_INFO("Weapons dump command only works with sv_cmd."); - #endif - return; - } - - default: - case CMD_REQUEST_USAGE: - { - LOG_HELP("Usage:^3 ", GetProgramCommandPrefix(), " dumpweapons []"); - LOG_HELPF(" Where is the file to write (default is %s),", DEFAULT_FILENAME); - LOG_HELP(" if supplied with '-' output to console as well as default,"); - LOG_HELP(" if left blank, it will only write to default."); - return; - } - } + switch(request) + { + case CMD_REQUEST_COMMAND: + { + #ifdef SVQC + wep_config_file = -1; + wep_config_alsoprint = -1; + string filename = argv(1); + + if(filename == "") + { + filename = DEFAULT_FILENAME; + wep_config_alsoprint = false; + } + else if(filename == "-") + { + filename = DEFAULT_FILENAME; + wep_config_alsoprint = true; + } + wep_config_file = fopen(filename, FILE_WRITE); + + if(wep_config_file >= 0) + { + Dump_Weapon_Settings(); + LOG_INFOF("Dumping weapons... File located in ^2data/data/%s^7.", filename); + fclose(wep_config_file); + wep_config_file = -1; + wep_config_alsoprint = -1; + } + else + { + LOG_INFOF("^1Error: ^7Could not open file '%s'!", filename); + } + #else + LOG_INFO("Weapons dump command only works with sv_cmd."); + #endif + return; + } + + default: + case CMD_REQUEST_USAGE: + { + LOG_HELP("Usage:^3 ", GetProgramCommandPrefix(), " dumpweapons []"); + LOG_HELPF(" Where is the file to write (default is %s),", DEFAULT_FILENAME); + LOG_HELP(" if supplied with '-' output to console as well as default,"); + LOG_HELP(" if left blank, it will only write to default."); + return; + } + } } #undef DEFAULT_FILENAME @@ -98,25 +98,28 @@ GENERIC_COMMAND(dumpweapons, "Dump all turrets into " DEFAULT_FILENAME, false) / entity W_PROP_reloader; float autocvar_w_prop_interval = 5; .void(Weapon this, int) wr_net; + void W_PROP_reload(int chan, entity to) { - W_PROP_reloader.nextthink = time + autocvar_w_prop_interval; - msg_entity = to; - FOREACH(Weapons, true, { - it.wr_update(it); - void(Weapon, int) f = it.wr_net; - if (f) f(it, chan); - }); + W_PROP_reloader.nextthink = time + autocvar_w_prop_interval; + msg_entity = to; + FOREACH(Weapons, true, { + it.wr_update(it); + void(Weapon, int) f = it.wr_net; + if (f) f(it, chan); + }); } + void W_PROP_think(entity this) { - W_PROP_reload(MSG_ALL, NULL); + W_PROP_reload(MSG_ALL, NULL); } + STATIC_INIT_LATE(W_PROP_reloader) { - entity e = W_PROP_reloader = new_pure(W_PROP_reloader); - setthink(e, W_PROP_think); - W_PROP_think(e); + entity e = W_PROP_reloader = new_pure(W_PROP_reloader); + setthink(e, W_PROP_think); + W_PROP_think(e); } #endif @@ -127,8 +130,8 @@ REGISTRY_DEFINE_GET(Weapons, WEP_Null) Weapon Weapon_from_name(string s) { - FOREACH(Weapons, it != WEP_Null && it.netname == s, return it); - return WEP_Null; + FOREACH(Weapons, it != WEP_Null && it.netname == s, return it); + return WEP_Null; } @@ -155,20 +158,20 @@ const .float reloading_time = reload_time; #define W_PROPS(L, class, prefix) \ - L(W_PROP_BEGIN, W_PROP, W_PROP_END, class, prefix) \ - L(W_CONFIG_BEGIN, W_CONFIG, W_CONFIG_END, class, prefix) \ - L(W_UPDATE_BEGIN, W_UPDATE, W_UPDATE_END, class, prefix) \ - L(W_NET_BEGIN, W_NET, W_NET_END, class, prefix) \ - /**/ \ - - - #define W_PROP(class, wepname, fld, T, m) W_PROP_##m(class, fld, T, wepname) - #define W_PROP_NONE(class, fld, T, wepname) _W_PROP(class, fld, T, wepname) - #define W_PROP_PRI(class, fld, T, wepname) _W_PROP(class, primary_##fld, T, wepname) - #define W_PROP_SEC(class, fld, T, wepname) _W_PROP(class, secondary_##fld, T, wepname) - #define W_PROP_BOTH(class, fld, T, wepname) \ - W_PROP_PRI(class, fld, T, wepname) \ - W_PROP_SEC(class, fld, T, wepname) + L(W_PROP_BEGIN, W_PROP, W_PROP_END, class, prefix) \ + L(W_CONFIG_BEGIN, W_CONFIG, W_CONFIG_END, class, prefix) \ + L(W_UPDATE_BEGIN, W_UPDATE, W_UPDATE_END, class, prefix) \ + L(W_NET_BEGIN, W_NET, W_NET_END, class, prefix) \ + /**/ \ + + + #define W_PROP(class, wepname, fld, T, m) W_PROP_##m(class, fld, T, wepname) + #define W_PROP_NONE(class, fld, T, wepname) _W_PROP(class, fld, T, wepname) + #define W_PROP_PRI(class, fld, T, wepname) _W_PROP(class, primary_##fld, T, wepname) + #define W_PROP_SEC(class, fld, T, wepname) _W_PROP(class, secondary_##fld, T, wepname) + #define W_PROP_BOTH(class, fld, T, wepname) \ + W_PROP_PRI(class, fld, T, wepname) \ + W_PROP_SEC(class, fld, T, wepname) #define W_PROP_BEGIN(class) #ifdef GAMEQC #define _W_PROP(class, fld, T, wepname) \ @@ -183,13 +186,13 @@ const .float reloading_time = reload_time; - #define W_CONFIG(class, wepname, fld, T, m) W_CONFIG_##m(class, fld, T, wepname) - #define W_CONFIG_NONE(class, fld, T, wepname) _W_CONFIG(class, fld, T, wepname) - #define W_CONFIG_PRI(class, fld, T, wepname) _W_CONFIG(class, primary_##fld, T, wepname) - #define W_CONFIG_SEC(class, fld, T, wepname) _W_CONFIG(class, secondary_##fld, T, wepname) - #define W_CONFIG_BOTH(class, fld, T, wepname) \ - W_CONFIG_PRI(class, fld, T, wepname) \ - W_CONFIG_SEC(class, fld, T, wepname) + #define W_CONFIG(class, wepname, fld, T, m) W_CONFIG_##m(class, fld, T, wepname) + #define W_CONFIG_NONE(class, fld, T, wepname) _W_CONFIG(class, fld, T, wepname) + #define W_CONFIG_PRI(class, fld, T, wepname) _W_CONFIG(class, primary_##fld, T, wepname) + #define W_CONFIG_SEC(class, fld, T, wepname) _W_CONFIG(class, secondary_##fld, T, wepname) + #define W_CONFIG_BOTH(class, fld, T, wepname) \ + W_CONFIG_PRI(class, fld, T, wepname) \ + W_CONFIG_SEC(class, fld, T, wepname) #ifdef SVQC #define W_CONFIG_BEGIN(class) METHOD(class, wr_config, void(class this)) { #define _W_CONFIG(class, fld, T, wepname) if (#wepname == this.netname) WEP_CONFIG_WRITE_CVARS(wepname, fld, T); @@ -201,13 +204,13 @@ const .float reloading_time = reload_time; #endif - #define W_UPDATE(class, wepname, fld, T, m) W_UPDATE_##m(class, fld, T, wepname) - #define W_UPDATE_NONE(class, fld, T, wepname) _W_UPDATE(class, fld, T, wepname) - #define W_UPDATE_PRI(class, fld, T, wepname) _W_UPDATE(class, primary_##fld, T, wepname) - #define W_UPDATE_SEC(class, fld, T, wepname) _W_UPDATE(class, secondary_##fld, T, wepname) - #define W_UPDATE_BOTH(class, fld, T, wepname) \ - W_UPDATE_PRI(class, fld, T, wepname) \ - W_UPDATE_SEC(class, fld, T, wepname) + #define W_UPDATE(class, wepname, fld, T, m) W_UPDATE_##m(class, fld, T, wepname) + #define W_UPDATE_NONE(class, fld, T, wepname) _W_UPDATE(class, fld, T, wepname) + #define W_UPDATE_PRI(class, fld, T, wepname) _W_UPDATE(class, primary_##fld, T, wepname) + #define W_UPDATE_SEC(class, fld, T, wepname) _W_UPDATE(class, secondary_##fld, T, wepname) + #define W_UPDATE_BOTH(class, fld, T, wepname) \ + W_UPDATE_PRI(class, fld, T, wepname) \ + W_UPDATE_SEC(class, fld, T, wepname) #ifdef GAMEQC .entity baseline, baseline_target; #define W_UPDATE_BEGIN(class) \ @@ -237,54 +240,59 @@ const .float reloading_time = reload_time; #endif - #define W_NET(class, wepname, fld, T, m) W_NET_##m(class, fld, T, wepname) - #define W_NET_NONE(class, fld, T, wepname) _W_NET(class, fld, T, wepname) - #define W_NET_PRI(class, fld, T, wepname) _W_NET(class, primary_##fld, T, wepname) - #define W_NET_SEC(class, fld, T, wepname) _W_NET(class, secondary_##fld, T, wepname) - #define W_NET_BOTH(class, fld, T, wepname) \ - W_NET_PRI(class, fld, T, wepname) \ - W_NET_SEC(class, fld, T, wepname) - #if defined(CSQC) - REGISTER_NET_TEMP(WeaponUpdate) - #define W_NET_BEGIN(class) METHOD(class, wr_net, void(class this, int i)) { int n = 0; - #define _W_NET(class, fld, T, wepname) \ - { \ - if (++n == i) this.wepvar_##fld = Read_##T(); \ - } - .void(Weapon this, int i) wr_net; - NET_HANDLE(WeaponUpdate, bool isnew) - { - Weapon w = REGISTRY_GET(Weapons, ReadByte()); - for (int i; (i = ReadByte()); ) - { - w.wr_net(w, i); - } - return true; - } - #define W_NET_END() } - #elif defined(SVQC) - REGISTER_NET_TEMP(WeaponUpdate) - #define W_NET_BEGIN(class) \ - METHOD(class, wr_net, void(class this, int chan)) \ - { \ - bool commit = false; \ - int i = 0; - #define _W_NET(class, fld, T, wepname) \ - { \ - ++i; \ - T it = this.wepvar_##fld; \ - if (chan == MSG_ONE || it != this.baseline.wepvar_##fld) \ - { \ - if (!commit) { commit = true; WriteHeader(chan, WeaponUpdate); WriteByte(chan, this.m_id); } \ - WriteByte(chan, i); Write_##T(chan, it); \ - } \ - } - #define W_NET_END() if (commit) WriteByte(chan, 0); } - #else - #define W_NET_BEGIN(class) - #define _W_NET(class, fld, T, wepname) - #define W_NET_END() - #endif + #define W_NET(class, wepname, fld, T, m) W_NET_##m(class, fld, T, wepname) + #define W_NET_NONE(class, fld, T, wepname) _W_NET(class, fld, T, wepname) + #define W_NET_PRI(class, fld, T, wepname) _W_NET(class, primary_##fld, T, wepname) + #define W_NET_SEC(class, fld, T, wepname) _W_NET(class, secondary_##fld, T, wepname) + #define W_NET_BOTH(class, fld, T, wepname) \ + W_NET_PRI(class, fld, T, wepname) \ + W_NET_SEC(class, fld, T, wepname) + #if defined(CSQC) + REGISTER_NET_TEMP(WeaponUpdate) + #define W_NET_BEGIN(class) METHOD(class, wr_net, void(class this, int i)) { int n = 0; + #define _W_NET(class, fld, T, wepname) \ + { \ + if (++n == i) this.wepvar_##fld = Read_##T(); \ + } + .void(Weapon this, int i) wr_net; + NET_HANDLE(WeaponUpdate, bool isnew) + { + Weapon w = REGISTRY_GET(Weapons, ReadByte()); + for (int i; (i = ReadByte()); ) + { + w.wr_net(w, i); + } + return true; + } + #define W_NET_END() } + #elif defined(SVQC) + REGISTER_NET_TEMP(WeaponUpdate) + #define W_NET_BEGIN(class) \ + METHOD(class, wr_net, void(class this, int chan)) \ + { \ + bool commit = false; \ + int i = 0; + #define _W_NET(class, fld, T, wepname) \ + { \ + ++i; \ + T it = this.wepvar_##fld; \ + if (chan == MSG_ONE || it != this.baseline.wepvar_##fld) \ + { \ + if (!commit) \ + { \ + commit = true; \ + WriteHeader(chan, WeaponUpdate); \ + WriteByte(chan, this.m_id); \ + } \ + WriteByte(chan, i); Write_##T(chan, it); \ + } \ + } + #define W_NET_END() if (commit) WriteByte(chan, 0); } + #else + #define W_NET_BEGIN(class) + #define _W_NET(class, fld, T, wepname) + #define W_NET_END() + #endif @@ -312,26 +320,26 @@ REGISTRY_CHECK(Weapons) STATIC_INIT(register_weapons_done) { string inaccessible = ""; - FOREACH(Weapons, true, { - WepSet set = it.m_wepset = _WepSet_FromWeapon(it.m_id = i); - WEPSET_ALL |= set; - if (it.spawnflags & WEP_FLAG_SUPERWEAPON) WEPSET_SUPERWEAPONS |= set; - if (it == WEP_Null) continue; - int imp = WEP_IMPULSE_BEGIN + it.m_id - 1; - if (imp <= WEP_IMPULSE_END) - localcmd(sprintf("alias weapon_%s \"impulse %d\"\n", it.netname, imp)); - else - inaccessible = strcat(inaccessible, "\n", it.netname); - }); - if (inaccessible != "" && autocvar_developer > 0) LOG_TRACEF("Impulse limit exceeded, weapon(s) will not be directly accessible: %s", inaccessible); - #ifdef CSQC - FOREACH(Weapons, true, it.wr_init(it)); - #endif - weaponorder_byid = ""; - for (int i = REGISTRY_MAX(Weapons) - 1; i >= 1; --i) - if (REGISTRY_GET(Weapons, i)) - weaponorder_byid = strcat(weaponorder_byid, " ", ftos(i)); - weaponorder_byid = strzone(substring(weaponorder_byid, 1, -1)); + FOREACH(Weapons, true, { + WepSet set = it.m_wepset = _WepSet_FromWeapon(it.m_id = i); + WEPSET_ALL |= set; + if (it.spawnflags & WEP_FLAG_SUPERWEAPON) WEPSET_SUPERWEAPONS |= set; + if (it == WEP_Null) continue; + int imp = WEP_IMPULSE_BEGIN + it.m_id - 1; + if (imp <= WEP_IMPULSE_END) + localcmd(sprintf("alias weapon_%s \"impulse %d\"\n", it.netname, imp)); + else + inaccessible = strcat(inaccessible, "\n", it.netname); + }); + if (inaccessible != "" && autocvar_developer > 0) LOG_TRACEF("Impulse limit exceeded, weapon(s) will not be directly accessible: %s", inaccessible); + #ifdef CSQC + FOREACH(Weapons, true, it.wr_init(it)); + #endif + weaponorder_byid = ""; + for (int i = REGISTRY_MAX(Weapons) - 1; i >= 1; --i) + if (REGISTRY_GET(Weapons, i)) + weaponorder_byid = strcat(weaponorder_byid, " ", ftos(i)); + weaponorder_byid = strzone(substring(weaponorder_byid, 1, -1)); } #ifdef GAMEQC @@ -340,9 +348,9 @@ STATIC_INIT(register_weapons_done) .entity exteriorweaponentity; vector weaponentity_glowmod(Weapon wep, int c, entity wepent) { - vector g; - if (!(g = wep.wr_glow(wep, c, wepent))) g = colormapPaletteColor(c & 0x0F, true); - return g; + vector g; + if (!(g = wep.wr_glow(wep, c, wepent))) g = colormapPaletteColor(c & 0x0F, true); + return g; } .int m_gunalign; @@ -377,11 +385,11 @@ ENUMCLASS_END(WFRAME) .WFRAME wframe; #ifdef SVQC - string autocvar_g_shootfromfixedorigin; - #define G_SHOOTFROMFIXEDORIGIN autocvar_g_shootfromfixedorigin + string autocvar_g_shootfromfixedorigin; + #define G_SHOOTFROMFIXEDORIGIN autocvar_g_shootfromfixedorigin #elif defined(CSQC) - string autocvar_cl_shootfromfixedorigin; - #define G_SHOOTFROMFIXEDORIGIN autocvar_cl_shootfromfixedorigin + string autocvar_cl_shootfromfixedorigin; + #define G_SHOOTFROMFIXEDORIGIN autocvar_cl_shootfromfixedorigin #endif vector shotorg_adjust(vector vecs, bool y_is_right, bool visual, int algn); diff --git a/qcsrc/common/weapons/weapon.qh b/qcsrc/common/weapons/weapon.qh index 14afd2b7c..19a81029c 100644 --- a/qcsrc/common/weapons/weapon.qh +++ b/qcsrc/common/weapons/weapon.qh @@ -41,91 +41,91 @@ const int WS_READY = 4; CLASS(Weapon, Object) ATTRIB(Weapon, m_id, int, 0); /** the canonical spawnfunc name */ - ATTRIB(Weapon, m_canonical_spawnfunc, string); - /** control what happens when this weapon is spawned */ - METHOD(Weapon, m_spawnfunc_hookreplace, Weapon(Weapon this, entity e)) { return this; } - /** M: ammotype : main ammo type */ - ATTRIB(Weapon, ammo_type, Resource, RES_NONE); - /** M: impulse : weapon impulse */ - ATTRIB(Weapon, impulse, int, -1); - /** M: flags : WEPSPAWNFLAG_... combined */ - ATTRIB(Weapon, spawnflags, int, 0); - /** M: rating : bot weapon priority */ - ATTRIB(Weapon, bot_pickupbasevalue, float, 0); - /** M: color : waypointsprite color */ - ATTRIB(Weapon, wpcolor, vector, '0 0 0'); - /** M: modelname : name of model (without g_ v_ or h_ prefixes) */ - ATTRIB(Weapon, mdl, string, ""); + ATTRIB(Weapon, m_canonical_spawnfunc, string); + /** control what happens when this weapon is spawned */ + METHOD(Weapon, m_spawnfunc_hookreplace, Weapon(Weapon this, entity e)) { return this; } + /** M: ammotype : main ammo type */ + ATTRIB(Weapon, ammo_type, Resource, RES_NONE); + /** M: impulse : weapon impulse */ + ATTRIB(Weapon, impulse, int, -1); + /** M: flags : WEPSPAWNFLAG_... combined */ + ATTRIB(Weapon, spawnflags, int, 0); + /** M: rating : bot weapon priority */ + ATTRIB(Weapon, bot_pickupbasevalue, float, 0); + /** M: color : waypointsprite color */ + ATTRIB(Weapon, wpcolor, vector, '0 0 0'); + /** M: modelname : name of model (without g_ v_ or h_ prefixes) */ + ATTRIB(Weapon, mdl, string, ""); #ifdef GAMEQC - /** M: model MDL_id_ITEM */ - ATTRIB(Weapon, m_model, entity); - /** M: flash model MDL_id_MUZZLEFLASH */ - ATTRIB(Weapon, m_muzzlemodel, entity, MDL_Null); - /** M: flash effect EFFECT_id_MUZZLEFLASH */ - ATTRIB(Weapon, m_muzzleeffect, entity); + /** M: model MDL_id_ITEM */ + ATTRIB(Weapon, m_model, entity); + /** M: flash model MDL_id_MUZZLEFLASH */ + ATTRIB(Weapon, m_muzzlemodel, entity, MDL_Null); + /** M: flash effect EFFECT_id_MUZZLEFLASH */ + ATTRIB(Weapon, m_muzzleeffect, entity); #endif - /** M: crosshair : per-weapon crosshair: "CrosshairImage Size" */ - ATTRIB(Weapon, w_crosshair, string, "gfx/crosshairmoustache"); - /** A: crosshair : per-weapon crosshair size (argument two of "crosshair" field) */ - ATTRIB(Weapon, w_crosshair_size, float, 1); - /** A: reticle : per-weapon zoom reticle */ - ATTRIB(Weapon, w_reticle, string, string_null); - /** M: wepimg : "weaponfoobar" side view image file of weapon. WEAPONTODO: Move out of skin files, move to common files */ - ATTRIB(Weapon, model2, string, ""); - /** M: refname : reference name name */ - ATTRIB(Weapon, netname, string, ""); - /** M: wepname : human readable name */ - ATTRIB(Weapon, m_name, string, "AOL CD Thrower"); - /** M: deprecated refname : old reference name for compatibility with weapons that were renamed */ - ATTRIB(Weapon, m_deprecated_netname, string, ""); - - ATTRIB(Weapon, m_pickup, entity); - - /** (SERVER) setup weapon data */ - METHOD(Weapon, wr_setup, void(Weapon this, entity actor, .entity weaponentity)) {} - /** (SERVER) logic to run every frame */ - METHOD(Weapon, wr_think, void(Weapon this, entity actor, .entity weaponentity, int fire)) {} - /** (SERVER) checks ammo for weapon primary */ - METHOD(Weapon, wr_checkammo1, bool(Weapon this, entity actor, .entity weaponentity)) {return false;} - /** (SERVER) checks ammo for weapon second */ - METHOD(Weapon, wr_checkammo2, bool(Weapon this, entity actor, .entity weaponentity)) {return false;} - /** (SERVER) runs bot aiming code for this weapon */ - METHOD(Weapon, wr_aim, void(Weapon this, entity actor, .entity weaponentity)) {} - /** (BOTH) precaches models/sounds used by this weapon, also sets up weapon properties */ - METHOD(Weapon, wr_init, void(Weapon this)) {} - /** (SERVER) notification number for suicide message (may inspect w_deathtype for details) */ - METHOD(Weapon, wr_suicidemessage, entity(Weapon this)) {return NULL;} - /** (SERVER) notification number for kill message (may inspect w_deathtype for details) */ - METHOD(Weapon, wr_killmessage, entity(Weapon this)) {return NULL;} - /** (SERVER) handles reloading for weapon */ - METHOD(Weapon, wr_reload, void(Weapon this, entity actor, .entity weaponentity)) {} - /** (SERVER) clears fields that the weapon may use */ - METHOD(Weapon, wr_resetplayer, void(Weapon this, entity actor)) {} - /** (CLIENT) impact effect for weapon explosion */ - METHOD(Weapon, wr_impacteffect, void(Weapon this, entity actor)) {} - /** (SERVER) called whenever a player dies */ - METHOD(Weapon, wr_playerdeath, void(Weapon this, entity actor, .entity weaponentity)) {} - /** (SERVER) logic to run when weapon is lost */ - METHOD(Weapon, wr_gonethink, void(Weapon this, entity actor, .entity weaponentity)) {} - /** (SERVER) dump weapon cvars to config in data directory (see: sv_cmd dumpweapons) */ - METHOD(Weapon, wr_config, void(Weapon this)) {} - /** (BOTH) weapon specific zoom reticle */ - METHOD(Weapon, wr_zoom, bool(Weapon this, entity actor)) { - // no weapon specific image for this weapon - return false; - } - /** (CLIENT) check whether the weapon should zoom (special handling) */ - METHOD(Weapon, wr_zoomdir, bool(Weapon this)) {return false;} - /** (CLIENT) weapon specific view model */ - METHOD(Weapon, wr_viewmodel, string(Weapon this, entity wep)) { return string_null; } - /** (BOTH) weapon specific glow */ - METHOD(Weapon, wr_glow, vector(Weapon this, int actor_colors, entity wepent)) { return '0 0 0'; } - /** (SERVER) the weapon is dropped */ - METHOD(Weapon, wr_drop, void(Weapon this, entity actor, .entity weaponentity)) {} - /** (SERVER) a weapon is picked up */ - METHOD(Weapon, wr_pickup, void(Weapon this, entity actor, .entity weaponentity)) {} - /** (SERVER) update cvar based properties */ - METHOD(Weapon, wr_update, void(Weapon this)) {} + /** M: crosshair : per-weapon crosshair: "CrosshairImage Size" */ + ATTRIB(Weapon, w_crosshair, string, "gfx/crosshairmoustache"); + /** A: crosshair : per-weapon crosshair size (argument two of "crosshair" field) */ + ATTRIB(Weapon, w_crosshair_size, float, 1); + /** A: reticle : per-weapon zoom reticle */ + ATTRIB(Weapon, w_reticle, string, string_null); + /** M: wepimg : "weaponfoobar" side view image file of weapon. WEAPONTODO: Move out of skin files, move to common files */ + ATTRIB(Weapon, model2, string, ""); + /** M: refname : reference name name */ + ATTRIB(Weapon, netname, string, ""); + /** M: wepname : human readable name */ + ATTRIB(Weapon, m_name, string, "AOL CD Thrower"); + /** M: deprecated refname : old reference name for compatibility with weapons that were renamed */ + ATTRIB(Weapon, m_deprecated_netname, string, ""); + + ATTRIB(Weapon, m_pickup, entity); + + /** (SERVER) setup weapon data */ + METHOD(Weapon, wr_setup, void(Weapon this, entity actor, .entity weaponentity)) {} + /** (SERVER) logic to run every frame */ + METHOD(Weapon, wr_think, void(Weapon this, entity actor, .entity weaponentity, int fire)) {} + /** (SERVER) checks ammo for weapon primary */ + METHOD(Weapon, wr_checkammo1, bool(Weapon this, entity actor, .entity weaponentity)) {return false;} + /** (SERVER) checks ammo for weapon second */ + METHOD(Weapon, wr_checkammo2, bool(Weapon this, entity actor, .entity weaponentity)) {return false;} + /** (SERVER) runs bot aiming code for this weapon */ + METHOD(Weapon, wr_aim, void(Weapon this, entity actor, .entity weaponentity)) {} + /** (BOTH) precaches models/sounds used by this weapon, also sets up weapon properties */ + METHOD(Weapon, wr_init, void(Weapon this)) {} + /** (SERVER) notification number for suicide message (may inspect w_deathtype for details) */ + METHOD(Weapon, wr_suicidemessage, entity(Weapon this)) {return NULL;} + /** (SERVER) notification number for kill message (may inspect w_deathtype for details) */ + METHOD(Weapon, wr_killmessage, entity(Weapon this)) {return NULL;} + /** (SERVER) handles reloading for weapon */ + METHOD(Weapon, wr_reload, void(Weapon this, entity actor, .entity weaponentity)) {} + /** (SERVER) clears fields that the weapon may use */ + METHOD(Weapon, wr_resetplayer, void(Weapon this, entity actor)) {} + /** (CLIENT) impact effect for weapon explosion */ + METHOD(Weapon, wr_impacteffect, void(Weapon this, entity actor)) {} + /** (SERVER) called whenever a player dies */ + METHOD(Weapon, wr_playerdeath, void(Weapon this, entity actor, .entity weaponentity)) {} + /** (SERVER) logic to run when weapon is lost */ + METHOD(Weapon, wr_gonethink, void(Weapon this, entity actor, .entity weaponentity)) {} + /** (SERVER) dump weapon cvars to config in data directory (see: sv_cmd dumpweapons) */ + METHOD(Weapon, wr_config, void(Weapon this)) {} + /** (BOTH) weapon specific zoom reticle */ + METHOD(Weapon, wr_zoom, bool(Weapon this, entity actor)) { + // no weapon specific image for this weapon + return false; + } + /** (CLIENT) check whether the weapon should zoom (special handling) */ + METHOD(Weapon, wr_zoomdir, bool(Weapon this)) {return false;} + /** (CLIENT) weapon specific view model */ + METHOD(Weapon, wr_viewmodel, string(Weapon this, entity wep)) { return string_null; } + /** (BOTH) weapon specific glow */ + METHOD(Weapon, wr_glow, vector(Weapon this, int actor_colors, entity wepent)) { return '0 0 0'; } + /** (SERVER) the weapon is dropped */ + METHOD(Weapon, wr_drop, void(Weapon this, entity actor, .entity weaponentity)) {} + /** (SERVER) a weapon is picked up */ + METHOD(Weapon, wr_pickup, void(Weapon this, entity actor, .entity weaponentity)) {} + /** (SERVER) update cvar based properties */ + METHOD(Weapon, wr_update, void(Weapon this)) {} METHOD(Weapon, display, void(entity this, void(string name, string icon) returns)) { returns(this.m_name, this.model2 ? sprintf("/gfx/hud/%s/%s", cvar_string("menu_skin"), this.model2) : string_null); } @@ -135,7 +135,7 @@ ENDCLASS(Weapon) void weapon_defaultspawnfunc(entity this, Weapon e); #define SPAWNFUNC_WEAPON(name, weapon) \ - spawnfunc(name) { weapon_defaultspawnfunc(this, weapon); } + spawnfunc(name) { weapon_defaultspawnfunc(this, weapon); } #define SPAWNFUNC_WEAPON_COND(name, cond, wep1, wep2) \ SPAWNFUNC_WEAPON(name, (cond ? wep1 : wep2)) @@ -148,41 +148,41 @@ void weapon_defaultspawnfunc(entity this, Weapon e); #include CLASS(WeaponPickup, Pickup) - ATTRIB(WeaponPickup, m_weapon, Weapon); - ATTRIB(WeaponPickup, m_name, string); + ATTRIB(WeaponPickup, m_weapon, Weapon); + ATTRIB(WeaponPickup, m_name, string); #ifdef GAMEQC - ATTRIB(WeaponPickup, m_sound, Sound, SND_WEAPONPICKUP); + ATTRIB(WeaponPickup, m_sound, Sound, SND_WEAPONPICKUP); #endif #ifdef SVQC - ATTRIB(WeaponPickup, m_itemflags, int, FL_WEAPON); - float weapon_pickupevalfunc(entity player, entity item); - ATTRIB(WeaponPickup, m_pickupevalfunc, float(entity player, entity item), weapon_pickupevalfunc); + ATTRIB(WeaponPickup, m_itemflags, int, FL_WEAPON); + float weapon_pickupevalfunc(entity player, entity item); + ATTRIB(WeaponPickup, m_pickupevalfunc, float(entity player, entity item), weapon_pickupevalfunc); #endif - CONSTRUCTOR(WeaponPickup, Weapon w) { - CONSTRUCT(WeaponPickup); - this.m_weapon = w; - this.m_name = w.m_name; + CONSTRUCTOR(WeaponPickup, Weapon w) { + CONSTRUCT(WeaponPickup); + this.m_weapon = w; + this.m_name = w.m_name; #ifdef GAMEQC - this.m_model = w.m_model; + this.m_model = w.m_model; #endif #ifdef SVQC - this.m_botvalue = w.bot_pickupbasevalue; + this.m_botvalue = w.bot_pickupbasevalue; #endif - } + } #ifdef SVQC - METHOD(WeaponPickup, giveTo, bool(entity this, entity item, entity player)) - { - bool b = Item_GiveTo(item, player); - //if (b) { - //LOG_TRACEF("entity %i picked up %s", player, this.m_name); - //} - return b; - } + METHOD(WeaponPickup, giveTo, bool(entity this, entity item, entity player)) + { + bool b = Item_GiveTo(item, player); + //if (b) { + //LOG_TRACEF("entity %i picked up %s", player, this.m_name); + //} + return b; + } #endif ENDCLASS(WeaponPickup) CLASS(OffhandWeapon, Object) - METHOD(OffhandWeapon, offhand_think, void(OffhandWeapon this, entity player, bool key_pressed)) {} + METHOD(OffhandWeapon, offhand_think, void(OffhandWeapon this, entity player, bool key_pressed)) {} ENDCLASS(OffhandWeapon) #ifdef SVQC diff --git a/qcsrc/common/weapons/weapon/arc.qc b/qcsrc/common/weapons/weapon/arc.qc index 4139bcc24..02199bb8d 100644 --- a/qcsrc/common/weapons/weapon/arc.qc +++ b/qcsrc/common/weapons/weapon/arc.qc @@ -571,187 +571,187 @@ void Arc_Smoke(Weapon thiswep, entity actor, .entity weaponentity, int fire) METHOD(Arc, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { - if(WEP_CVAR(WEP_ARC, beam_botaimspeed)) - { - PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim( - actor, - weaponentity, - WEP_CVAR(WEP_ARC, beam_botaimspeed), - 0, - WEP_CVAR(WEP_ARC, beam_botaimlifetime), - false, true - ); - } - else - { - PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim( - actor, - weaponentity, - 1000000, - 0, - 0.001, - false, true - ); - } + if(WEP_CVAR(WEP_ARC, beam_botaimspeed)) + { + PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim( + actor, + weaponentity, + WEP_CVAR(WEP_ARC, beam_botaimspeed), + 0, + WEP_CVAR(WEP_ARC, beam_botaimlifetime), + false, true + ); + } + else + { + PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim( + actor, + weaponentity, + 1000000, + 0, + 0.001, + false, true + ); + } } METHOD(Arc, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) { - Arc_Player_SetHeat(actor, weaponentity); - Arc_Smoke(thiswep, actor, weaponentity, fire); - - bool beam_fire2 = ((fire & 2) && !WEP_CVAR(WEP_ARC, bolt)); - - if (time >= actor.arc_overheat) - if ((fire & 1) || beam_fire2 || actor.(weaponentity).arc_beam.beam_bursting) - { - #if 0 - if(actor.(weaponentity).arc_BUTTON_ATCK_prev) - { - #if 0 - if(actor.animstate_startframe == actor.anim_shoot.x && actor.animstate_numframes == actor.anim_shoot.y) - weapon_thinkf(actor, weaponentity, WFRAME_DONTCHANGE, autocvar_g_balance_arc_primary_animtime, w_ready); - else - #endif - weapon_thinkf(actor, weaponentity, WFRAME_DONTCHANGE, WEP_CVAR(WEP_ARC, beam_animtime), w_ready); - } - #endif - - if((!actor.(weaponentity).arc_beam) || wasfreed(actor.(weaponentity).arc_beam)) - { - if(weapon_prepareattack(thiswep, actor, weaponentity, boolean(beam_fire2), 0)) - { - W_Arc_Beam(boolean(beam_fire2), actor, weaponentity); - - if(!actor.(weaponentity).arc_BUTTON_ATCK_prev) - { - actor.(weaponentity).wframe = WFRAME_FIRE1; - weapon_thinkf(actor, weaponentity, WFRAME_DONTCHANGE, WEP_CVAR(WEP_ARC, beam_animtime), W_Arc_Attack); - actor.(weaponentity).arc_BUTTON_ATCK_prev = true; - } - } - } - - return; - } - else if(fire & 2) - { - if(weapon_prepareattack(thiswep, actor, weaponentity, true, 0)) - { - if(!thiswep.wr_checkammo2(thiswep, actor, weaponentity)) - if(!(actor.items & IT_UNLIMITED_AMMO)) - { - W_SwitchWeapon_Force(actor, w_getbestweapon(actor, weaponentity), weaponentity); - w_ready(thiswep, actor, weaponentity, fire); - return; - } - float ammo_available = GetResource(actor, thiswep.ammo_type); - // We don't want to shoot 3 rounds if there's 2 left in the mag, so we'll use a fraction. - // Also keep the fraction <= 1 otherwise we'd mag dump in one burst. - float burst_fraction = min(1, ammo_available / WEP_CVAR(WEP_ARC, bolt_ammo)); - int to_shoot = floor(WEP_CVAR(WEP_ARC, bolt_count) * burst_fraction); - - // We also don't want to use 3 rounds if there's only 2 left. - int to_use = min(WEP_CVAR(WEP_ARC, bolt_ammo), ammo_available); - W_DecreaseAmmo(thiswep, actor, to_use, weaponentity); - - // Bursting counts up to 0 from a negative. - actor.(weaponentity).misc_bulletcounter = -to_shoot; - W_Arc_Attack_Bolt(thiswep, actor, weaponentity, fire); - } - } - - if(actor.(weaponentity).arc_BUTTON_ATCK_prev) - { - sound(actor, CH_WEAPON_A, SND_ARC_STOP, VOL_BASE, ATTN_NORM); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(WEP_ARC, beam_animtime), w_ready); - ATTACK_FINISHED(actor, weaponentity) = time + WEP_CVAR(WEP_ARC, beam_refire) * W_WeaponRateFactor(actor); - } - actor.(weaponentity).arc_BUTTON_ATCK_prev = false; - - #if 0 - if(fire & 2) - if(weapon_prepareattack(thiswep, actor, weaponentity, true, autocvar_g_balance_arc_secondary_refire)) - { - W_Arc_Attack2(); - actor.arc_count = autocvar_g_balance_arc_secondary_count; - weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, autocvar_g_balance_arc_secondary_animtime, w_arc_checkattack); - actor.arc_secondarytime = time + autocvar_g_balance_arc_secondary_refire2 * W_WeaponRateFactor(actor); - } - #endif + Arc_Player_SetHeat(actor, weaponentity); + Arc_Smoke(thiswep, actor, weaponentity, fire); + + bool beam_fire2 = ((fire & 2) && !WEP_CVAR(WEP_ARC, bolt)); + + if (time >= actor.arc_overheat) + if ((fire & 1) || beam_fire2 || actor.(weaponentity).arc_beam.beam_bursting) + { + #if 0 + if(actor.(weaponentity).arc_BUTTON_ATCK_prev) + { + #if 0 + if(actor.animstate_startframe == actor.anim_shoot.x && actor.animstate_numframes == actor.anim_shoot.y) + weapon_thinkf(actor, weaponentity, WFRAME_DONTCHANGE, autocvar_g_balance_arc_primary_animtime, w_ready); + else + #endif + weapon_thinkf(actor, weaponentity, WFRAME_DONTCHANGE, WEP_CVAR(WEP_ARC, beam_animtime), w_ready); + } + #endif + + if((!actor.(weaponentity).arc_beam) || wasfreed(actor.(weaponentity).arc_beam)) + { + if(weapon_prepareattack(thiswep, actor, weaponentity, boolean(beam_fire2), 0)) + { + W_Arc_Beam(boolean(beam_fire2), actor, weaponentity); + + if(!actor.(weaponentity).arc_BUTTON_ATCK_prev) + { + actor.(weaponentity).wframe = WFRAME_FIRE1; + weapon_thinkf(actor, weaponentity, WFRAME_DONTCHANGE, WEP_CVAR(WEP_ARC, beam_animtime), W_Arc_Attack); + actor.(weaponentity).arc_BUTTON_ATCK_prev = true; + } + } + } + + return; + } + else if(fire & 2) + { + if(weapon_prepareattack(thiswep, actor, weaponentity, true, 0)) + { + if(!thiswep.wr_checkammo2(thiswep, actor, weaponentity)) + if(!(actor.items & IT_UNLIMITED_AMMO)) + { + W_SwitchWeapon_Force(actor, w_getbestweapon(actor, weaponentity), weaponentity); + w_ready(thiswep, actor, weaponentity, fire); + return; + } + float ammo_available = GetResource(actor, thiswep.ammo_type); + // We don't want to shoot 3 rounds if there's 2 left in the mag, so we'll use a fraction. + // Also keep the fraction <= 1 otherwise we'd mag dump in one burst. + float burst_fraction = min(1, ammo_available / WEP_CVAR(WEP_ARC, bolt_ammo)); + int to_shoot = floor(WEP_CVAR(WEP_ARC, bolt_count) * burst_fraction); + + // We also don't want to use 3 rounds if there's only 2 left. + int to_use = min(WEP_CVAR(WEP_ARC, bolt_ammo), ammo_available); + W_DecreaseAmmo(thiswep, actor, to_use, weaponentity); + + // Bursting counts up to 0 from a negative. + actor.(weaponentity).misc_bulletcounter = -to_shoot; + W_Arc_Attack_Bolt(thiswep, actor, weaponentity, fire); + } + } + + if(actor.(weaponentity).arc_BUTTON_ATCK_prev) + { + sound(actor, CH_WEAPON_A, SND_ARC_STOP, VOL_BASE, ATTN_NORM); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(WEP_ARC, beam_animtime), w_ready); + ATTACK_FINISHED(actor, weaponentity) = time + WEP_CVAR(WEP_ARC, beam_refire) * W_WeaponRateFactor(actor); + } + actor.(weaponentity).arc_BUTTON_ATCK_prev = false; + + #if 0 + if(fire & 2) + if(weapon_prepareattack(thiswep, actor, weaponentity, true, autocvar_g_balance_arc_secondary_refire)) + { + W_Arc_Attack2(); + actor.arc_count = autocvar_g_balance_arc_secondary_count; + weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, autocvar_g_balance_arc_secondary_animtime, w_arc_checkattack); + actor.arc_secondarytime = time + autocvar_g_balance_arc_secondary_refire2 * W_WeaponRateFactor(actor); + } + #endif } METHOD(Arc, wr_suicidemessage, Notification(entity thiswep)) { - if(w_deathtype & HITTYPE_SECONDARY) - return WEAPON_ARC_SUICIDE_BOLT; - else - return WEAPON_THINKING_WITH_PORTALS; + if(w_deathtype & HITTYPE_SECONDARY) + return WEAPON_ARC_SUICIDE_BOLT; + else + return WEAPON_THINKING_WITH_PORTALS; } METHOD(Arc, wr_init, void(entity thiswep)) { - if(!arc_shotorigin[0]) - { - vector vecs = CL_Weapon_GetShotOrg(WEP_ARC.m_id); - arc_shotorigin[0] = shotorg_adjust(vecs, false, false, 1); - arc_shotorigin[1] = shotorg_adjust(vecs, false, false, 2); - arc_shotorigin[2] = shotorg_adjust(vecs, false, false, 3); - arc_shotorigin[3] = shotorg_adjust(vecs, false, false, 4); - } + if(!arc_shotorigin[0]) + { + vector vecs = CL_Weapon_GetShotOrg(WEP_ARC.m_id); + arc_shotorigin[0] = shotorg_adjust(vecs, false, false, 1); + arc_shotorigin[1] = shotorg_adjust(vecs, false, false, 2); + arc_shotorigin[2] = shotorg_adjust(vecs, false, false, 3); + arc_shotorigin[3] = shotorg_adjust(vecs, false, false, 4); + } } METHOD(Arc, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity)) { - return ((!WEP_CVAR(WEP_ARC, beam_ammo)) || (GetResource(actor, thiswep.ammo_type) > 0)); + return ((!WEP_CVAR(WEP_ARC, beam_ammo)) || (GetResource(actor, thiswep.ammo_type) > 0)); } METHOD(Arc, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity)) { - if(WEP_CVAR(WEP_ARC, bolt)) - { - float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR(WEP_ARC, bolt_ammo); - ammo_amount += actor.(weaponentity).(weapon_load[WEP_ARC.m_id]) >= WEP_CVAR(WEP_ARC, bolt_ammo); - return ammo_amount; - } - else - return WEP_CVAR(WEP_ARC, overheat_max) > 0 && - ((!WEP_CVAR(WEP_ARC, burst_ammo)) || (GetResource(actor, thiswep.ammo_type) > 0)); + if(WEP_CVAR(WEP_ARC, bolt)) + { + float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR(WEP_ARC, bolt_ammo); + ammo_amount += actor.(weaponentity).(weapon_load[WEP_ARC.m_id]) >= WEP_CVAR(WEP_ARC, bolt_ammo); + return ammo_amount; + } + else + return WEP_CVAR(WEP_ARC, overheat_max) > 0 && + ((!WEP_CVAR(WEP_ARC, burst_ammo)) || (GetResource(actor, thiswep.ammo_type) > 0)); } METHOD(Arc, wr_killmessage, Notification(entity thiswep)) { - if(w_deathtype & HITTYPE_SECONDARY) - return WEAPON_ARC_MURDER_SPRAY; - else - return WEAPON_ARC_MURDER; + if(w_deathtype & HITTYPE_SECONDARY) + return WEAPON_ARC_MURDER_SPRAY; + else + return WEAPON_ARC_MURDER; } METHOD(Arc, wr_drop, void(entity thiswep, entity actor, .entity weaponentity)) { - weapon_dropevent_item.arc_overheat = actor.arc_overheat; - weapon_dropevent_item.arc_cooldown = actor.arc_cooldown; - actor.arc_overheat = 0; - actor.arc_cooldown = 0; - actor.(weaponentity).arc_BUTTON_ATCK_prev = false; + weapon_dropevent_item.arc_overheat = actor.arc_overheat; + weapon_dropevent_item.arc_cooldown = actor.arc_cooldown; + actor.arc_overheat = 0; + actor.arc_cooldown = 0; + actor.(weaponentity).arc_BUTTON_ATCK_prev = false; } METHOD(Arc, wr_pickup, void(entity thiswep, entity actor, .entity weaponentity)) { - if ( !client_hasweapon(actor, thiswep, weaponentity, false, false) && - weapon_dropevent_item.arc_overheat > time ) - { - actor.arc_overheat = weapon_dropevent_item.arc_overheat; - actor.arc_cooldown = weapon_dropevent_item.arc_cooldown; - } + if ( !client_hasweapon(actor, thiswep, weaponentity, false, false) && + weapon_dropevent_item.arc_overheat > time ) + { + actor.arc_overheat = weapon_dropevent_item.arc_overheat; + actor.arc_cooldown = weapon_dropevent_item.arc_cooldown; + } } METHOD(Arc, wr_resetplayer, void(entity thiswep, entity actor)) { - actor.arc_overheat = 0; - actor.arc_cooldown = 0; - for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) - { - .entity weaponentity = weaponentities[slot]; - actor.(weaponentity).arc_BUTTON_ATCK_prev = false; - } + actor.arc_overheat = 0; + actor.arc_cooldown = 0; + for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + { + .entity weaponentity = weaponentities[slot]; + actor.(weaponentity).arc_BUTTON_ATCK_prev = false; + } } METHOD(Arc, wr_playerdeath, void(entity thiswep, entity actor, .entity weaponentity)) { - actor.arc_overheat = 0; - actor.arc_cooldown = 0; - actor.(weaponentity).arc_BUTTON_ATCK_prev = false; + actor.arc_overheat = 0; + actor.arc_cooldown = 0; + actor.(weaponentity).arc_BUTTON_ATCK_prev = false; } #endif #ifdef CSQC @@ -762,12 +762,12 @@ bool autocvar_cl_arcbeam_simple = true; METHOD(Arc, wr_impacteffect, void(entity thiswep, entity actor)) { - if(w_deathtype & HITTYPE_SECONDARY) - { - vector org2 = w_org + w_backoff * 2; - pointparticles(EFFECT_ELECTRO_IMPACT, org2, w_backoff * 1000, 1); - if(!w_issilent) { sound(actor, CH_SHOTS, SND_ELECTRO_IMPACT, VOL_BASE, ATTN_NORM); } - } + if(w_deathtype & HITTYPE_SECONDARY) + { + vector org2 = w_org + w_backoff * 2; + pointparticles(EFFECT_ELECTRO_IMPACT, org2, w_backoff * 1000, 1); + if(!w_issilent) { sound(actor, CH_SHOTS, SND_ELECTRO_IMPACT, VOL_BASE, ATTN_NORM); } + } } void Draw_ArcBeam_callback(vector start, vector hit, vector end) diff --git a/qcsrc/common/weapons/weapon/arc.qh b/qcsrc/common/weapons/weapon/arc.qh index a7d289c07..993f392bb 100644 --- a/qcsrc/common/weapons/weapon/arc.qh +++ b/qcsrc/common/weapons/weapon/arc.qh @@ -23,60 +23,60 @@ CLASS(Arc, Weapon) BEGIN(class) \ P(class, prefix, bolt, float, NONE) \ P(class, prefix, bolt_ammo, float, NONE) \ - P(class, prefix, bolt_bounce_count, float, NONE) \ - P(class, prefix, bolt_bounce_explode, float, NONE) \ - P(class, prefix, bolt_bounce_lifetime, float, NONE) \ - P(class, prefix, bolt_count, float, NONE) \ - P(class, prefix, bolt_damageforcescale, float, NONE) \ - P(class, prefix, bolt_damage, float, NONE) \ - P(class, prefix, bolt_edgedamage, float, NONE) \ - P(class, prefix, bolt_force, float, NONE) \ - P(class, prefix, bolt_health, float, NONE) \ - P(class, prefix, bolt_lifetime, float, NONE) \ - P(class, prefix, bolt_radius, float, NONE) \ - P(class, prefix, bolt_refire, float, NONE) \ - P(class, prefix, bolt_refire2, float, NONE) \ - P(class, prefix, bolt_speed, float, NONE) \ - P(class, prefix, bolt_spread, float, NONE) \ + P(class, prefix, bolt_bounce_count, float, NONE) \ + P(class, prefix, bolt_bounce_explode, float, NONE) \ + P(class, prefix, bolt_bounce_lifetime, float, NONE) \ + P(class, prefix, bolt_count, float, NONE) \ + P(class, prefix, bolt_damageforcescale, float, NONE) \ + P(class, prefix, bolt_damage, float, NONE) \ + P(class, prefix, bolt_edgedamage, float, NONE) \ + P(class, prefix, bolt_force, float, NONE) \ + P(class, prefix, bolt_health, float, NONE) \ + P(class, prefix, bolt_lifetime, float, NONE) \ + P(class, prefix, bolt_radius, float, NONE) \ + P(class, prefix, bolt_refire, float, NONE) \ + P(class, prefix, bolt_refire2, float, NONE) \ + P(class, prefix, bolt_speed, float, NONE) \ + P(class, prefix, bolt_spread, float, NONE) \ P(class, prefix, beam_ammo, float, NONE) \ - P(class, prefix, beam_animtime, float, NONE) \ - P(class, prefix, beam_botaimlifetime, float, NONE) \ - P(class, prefix, beam_botaimspeed, float, NONE) \ - P(class, prefix, beam_damage, float, NONE) \ - P(class, prefix, beam_degreespersegment, float, NONE) \ - P(class, prefix, beam_distancepersegment, float, NONE) \ - P(class, prefix, beam_falloff_halflifedist, float, NONE) \ - P(class, prefix, beam_falloff_maxdist, float, NONE) \ - P(class, prefix, beam_falloff_mindist, float, NONE) \ - P(class, prefix, beam_force, float, NONE) \ - P(class, prefix, beam_healing_amax, float, NONE) \ - P(class, prefix, beam_healing_aps, float, NONE) \ - P(class, prefix, beam_healing_hmax, float, NONE) \ - P(class, prefix, beam_healing_hps, float, NONE) \ - P(class, prefix, beam_heat, float, NONE) /* heat increase per second (primary) */ \ - P(class, prefix, beam_maxangle, float, NONE) \ - P(class, prefix, beam_nonplayerdamage, float, NONE) \ - P(class, prefix, beam_range, float, NONE) \ - P(class, prefix, beam_refire, float, NONE) \ - P(class, prefix, beam_returnspeed, float, NONE) \ - P(class, prefix, beam_tightness, float, NONE) \ - P(class, prefix, burst_ammo, float, NONE) \ - P(class, prefix, burst_damage, float, NONE) \ - P(class, prefix, burst_healing_aps, float, NONE) \ - P(class, prefix, burst_healing_hps, float, NONE) \ - P(class, prefix, burst_heat, float, NONE) /* heat increase per second (secondary) */ \ - P(class, prefix, cooldown, float, NONE) /* heat decrease per second when resting */ \ - P(class, prefix, cooldown_release, float, NONE) /* delay weapon re-use when releasing button */ \ - P(class, prefix, overheat_max, float, NONE) /* maximum heat before jamming */ \ - P(class, prefix, overheat_min, float, NONE) /* minimum heat to wait for cooldown */ \ - P(class, prefix, switchdelay_drop, float, NONE) \ - P(class, prefix, switchdelay_raise, float, NONE) \ - P(class, prefix, weaponreplace, string, NONE) \ - P(class, prefix, weaponstartoverride, float, NONE) \ - P(class, prefix, weaponstart, float, NONE) \ - P(class, prefix, weaponthrowable, float, NONE) \ - END() - W_PROPS(X, Arc, arc) + P(class, prefix, beam_animtime, float, NONE) \ + P(class, prefix, beam_botaimlifetime, float, NONE) \ + P(class, prefix, beam_botaimspeed, float, NONE) \ + P(class, prefix, beam_damage, float, NONE) \ + P(class, prefix, beam_degreespersegment, float, NONE) \ + P(class, prefix, beam_distancepersegment, float, NONE) \ + P(class, prefix, beam_falloff_halflifedist, float, NONE) \ + P(class, prefix, beam_falloff_maxdist, float, NONE) \ + P(class, prefix, beam_falloff_mindist, float, NONE) \ + P(class, prefix, beam_force, float, NONE) \ + P(class, prefix, beam_healing_amax, float, NONE) \ + P(class, prefix, beam_healing_aps, float, NONE) \ + P(class, prefix, beam_healing_hmax, float, NONE) \ + P(class, prefix, beam_healing_hps, float, NONE) \ + P(class, prefix, beam_heat, float, NONE) /* heat increase per second (primary) */ \ + P(class, prefix, beam_maxangle, float, NONE) \ + P(class, prefix, beam_nonplayerdamage, float, NONE) \ + P(class, prefix, beam_range, float, NONE) \ + P(class, prefix, beam_refire, float, NONE) \ + P(class, prefix, beam_returnspeed, float, NONE) \ + P(class, prefix, beam_tightness, float, NONE) \ + P(class, prefix, burst_ammo, float, NONE) \ + P(class, prefix, burst_damage, float, NONE) \ + P(class, prefix, burst_healing_aps, float, NONE) \ + P(class, prefix, burst_healing_hps, float, NONE) \ + P(class, prefix, burst_heat, float, NONE) /* heat increase per second (secondary) */ \ + P(class, prefix, cooldown, float, NONE) /* heat decrease per second when resting */ \ + P(class, prefix, cooldown_release, float, NONE) /* delay weapon re-use when releasing button */ \ + P(class, prefix, overheat_max, float, NONE) /* maximum heat before jamming */ \ + P(class, prefix, overheat_min, float, NONE) /* minimum heat to wait for cooldown */ \ + P(class, prefix, switchdelay_drop, float, NONE) \ + P(class, prefix, switchdelay_raise, float, NONE) \ + P(class, prefix, weaponreplace, string, NONE) \ + P(class, prefix, weaponstartoverride, float, NONE) \ + P(class, prefix, weaponstart, float, NONE) \ + P(class, prefix, weaponthrowable, float, NONE) \ + END() + W_PROPS(X, Arc, arc) #undef X ENDCLASS(Arc) diff --git a/qcsrc/common/weapons/weapon/crylink.qc b/qcsrc/common/weapons/weapon/crylink.qc index 494a203f4..7306aef9f 100644 --- a/qcsrc/common/weapons/weapon/crylink.qc +++ b/qcsrc/common/weapons/weapon/crylink.qc @@ -504,116 +504,127 @@ void W_Crylink_Attack2(Weapon thiswep, entity actor, .entity weaponentity) METHOD(Crylink, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { - if(random() < 0.10) - PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, WEP_CVAR_PRI(WEP_CRYLINK, speed), 0, WEP_CVAR_PRI(WEP_CRYLINK, middle_lifetime), false, true); - else - PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, weaponentity, WEP_CVAR_SEC(WEP_CRYLINK, speed), 0, WEP_CVAR_SEC(WEP_CRYLINK, middle_lifetime), false, true); + if(random() < 0.10) + PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, WEP_CVAR_PRI(WEP_CRYLINK, speed), 0, WEP_CVAR_PRI(WEP_CRYLINK, middle_lifetime), false, true); + else + PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, weaponentity, WEP_CVAR_SEC(WEP_CRYLINK, speed), 0, WEP_CVAR_SEC(WEP_CRYLINK, middle_lifetime), false, true); } + METHOD(Crylink, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) { - if(autocvar_g_balance_crylink_reload_ammo && actor.(weaponentity).clip_load < min(WEP_CVAR_PRI(WEP_CRYLINK, ammo), WEP_CVAR_SEC(WEP_CRYLINK, ammo))) { // forced reload - thiswep.wr_reload(thiswep, actor, weaponentity); - } - - else if(fire & 1) - { - if(actor.(weaponentity).crylink_waitrelease != 1) - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(WEP_CRYLINK, refire))) - { - W_Crylink_Attack(thiswep, actor, weaponentity); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(WEP_CRYLINK, animtime), w_ready); - } - } - - else if((fire & 2) && autocvar_g_balance_crylink_secondary) - { - if(actor.(weaponentity).crylink_waitrelease != 2) - if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(WEP_CRYLINK, refire))) - { - W_Crylink_Attack2(thiswep, actor, weaponentity); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(WEP_CRYLINK, animtime), w_ready); - } - } - - if((actor.(weaponentity).crylink_waitrelease == 1 && !(fire & 1)) || (actor.(weaponentity).crylink_waitrelease == 2 && !(fire & 2))) - { - if(!actor.(weaponentity).crylink_lastgroup || time > actor.(weaponentity).crylink_lastgroup.teleport_time) - { - // fired and released now! - if(actor.(weaponentity).crylink_lastgroup) - { - vector pos; - entity linkjoineffect; - float isprimary = (actor.(weaponentity).crylink_waitrelease == 1); - - pos = W_Crylink_LinkJoin(actor.(weaponentity).crylink_lastgroup, WEP_CVAR_BOTH(WEP_CRYLINK, isprimary, joinspread) * WEP_CVAR_BOTH(WEP_CRYLINK, isprimary, speed)); - - linkjoineffect = new(linkjoineffect); - linkjoineffect.weaponentity_fld = weaponentity; - setthink(linkjoineffect, W_Crylink_LinkJoinEffect_Think); - linkjoineffect.nextthink = time + w_crylink_linkjoin_time; - linkjoineffect.owner = actor; - setorigin(linkjoineffect, pos); - } - actor.(weaponentity).crylink_waitrelease = 0; - if(!thiswep.wr_checkammo1(thiswep, actor, weaponentity) && !thiswep.wr_checkammo2(thiswep, actor, weaponentity)) - if(!(actor.items & IT_UNLIMITED_AMMO)) - { - // ran out of ammo! - actor.cnt = thiswep.m_id; - actor.(weaponentity).m_switchweapon = w_getbestweapon(actor, weaponentity); - } - } - } + if (autocvar_g_balance_crylink_reload_ammo + && actor.(weaponentity).clip_load < min(WEP_CVAR_PRI(WEP_CRYLINK, ammo), WEP_CVAR_SEC(WEP_CRYLINK, ammo))) + { // forced reload + thiswep.wr_reload(thiswep, actor, weaponentity); + } + + else if(fire & 1) + { + if(actor.(weaponentity).crylink_waitrelease != 1) + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(WEP_CRYLINK, refire))) + { + W_Crylink_Attack(thiswep, actor, weaponentity); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(WEP_CRYLINK, animtime), w_ready); + } + } + + else if((fire & 2) && autocvar_g_balance_crylink_secondary) + { + if(actor.(weaponentity).crylink_waitrelease != 2) + if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(WEP_CRYLINK, refire))) + { + W_Crylink_Attack2(thiswep, actor, weaponentity); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(WEP_CRYLINK, animtime), w_ready); + } + } + + if((actor.(weaponentity).crylink_waitrelease == 1 && !(fire & 1)) || (actor.(weaponentity).crylink_waitrelease == 2 && !(fire & 2))) + { + if(!actor.(weaponentity).crylink_lastgroup || time > actor.(weaponentity).crylink_lastgroup.teleport_time) + { + // fired and released now! + if(actor.(weaponentity).crylink_lastgroup) + { + vector pos; + entity linkjoineffect; + float isprimary = (actor.(weaponentity).crylink_waitrelease == 1); + + pos = W_Crylink_LinkJoin(actor.(weaponentity).crylink_lastgroup, WEP_CVAR_BOTH(WEP_CRYLINK, isprimary, joinspread) * WEP_CVAR_BOTH(WEP_CRYLINK, isprimary, speed)); + + linkjoineffect = new(linkjoineffect); + linkjoineffect.weaponentity_fld = weaponentity; + setthink(linkjoineffect, W_Crylink_LinkJoinEffect_Think); + linkjoineffect.nextthink = time + w_crylink_linkjoin_time; + linkjoineffect.owner = actor; + setorigin(linkjoineffect, pos); + } + actor.(weaponentity).crylink_waitrelease = 0; + if(!thiswep.wr_checkammo1(thiswep, actor, weaponentity) && !thiswep.wr_checkammo2(thiswep, actor, weaponentity)) + if(!(actor.items & IT_UNLIMITED_AMMO)) + { + // ran out of ammo! + actor.cnt = thiswep.m_id; + actor.(weaponentity).m_switchweapon = w_getbestweapon(actor, weaponentity); + } + } + } } + METHOD(Crylink, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity)) { - // don't "run out of ammo" and switch weapons while waiting for release - if(actor.(weaponentity).crylink_lastgroup && actor.(weaponentity).crylink_waitrelease) - return true; + // don't "run out of ammo" and switch weapons while waiting for release + if(actor.(weaponentity).crylink_lastgroup && actor.(weaponentity).crylink_waitrelease) + return true; - float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_PRI(WEP_CRYLINK, ammo); - ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_PRI(WEP_CRYLINK, ammo); - return ammo_amount; + float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_PRI(WEP_CRYLINK, ammo); + ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_PRI(WEP_CRYLINK, ammo); + return ammo_amount; } + METHOD(Crylink, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity)) { - // don't "run out of ammo" and switch weapons while waiting for release - if(actor.(weaponentity).crylink_lastgroup && actor.(weaponentity).crylink_waitrelease) - return true; + // don't "run out of ammo" and switch weapons while waiting for release + if(actor.(weaponentity).crylink_lastgroup && actor.(weaponentity).crylink_waitrelease) + return true; - float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_SEC(WEP_CRYLINK, ammo); - ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_SEC(WEP_CRYLINK, ammo); - return ammo_amount; + float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_SEC(WEP_CRYLINK, ammo); + ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_SEC(WEP_CRYLINK, ammo); + return ammo_amount; } + METHOD(Crylink, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) { - W_Reload(actor, weaponentity, min(WEP_CVAR_PRI(WEP_CRYLINK, ammo), WEP_CVAR_SEC(WEP_CRYLINK, ammo)), SND_RELOAD); + W_Reload(actor, weaponentity, min(WEP_CVAR_PRI(WEP_CRYLINK, ammo), WEP_CVAR_SEC(WEP_CRYLINK, ammo)), SND_RELOAD); } + METHOD(Crylink, wr_suicidemessage, Notification(entity thiswep)) { - return WEAPON_CRYLINK_SUICIDE; + return WEAPON_CRYLINK_SUICIDE; } + METHOD(Crylink, wr_killmessage, Notification(entity thiswep)) { - return WEAPON_CRYLINK_MURDER; + return WEAPON_CRYLINK_MURDER; } + #endif #ifdef CSQC + METHOD(Crylink, wr_impacteffect, void(entity thiswep, entity actor)) { - vector org2 = w_org + w_backoff * 2; - if(w_deathtype & HITTYPE_SECONDARY) - { - pointparticles(EFFECT_CRYLINK_IMPACT2, org2, '0 0 0', 1); - if(!w_issilent) - sound(actor, CH_SHOTS, SND_CRYLINK_IMPACT2, VOL_BASE, ATTN_NORM); - } - else - { - pointparticles(EFFECT_CRYLINK_IMPACT, org2, '0 0 0', 1); - if(!w_issilent) - sound(actor, CH_SHOTS, SND_CRYLINK_IMPACT, VOL_BASE, ATTN_NORM); - } + vector org2 = w_org + w_backoff * 2; + if(w_deathtype & HITTYPE_SECONDARY) + { + pointparticles(EFFECT_CRYLINK_IMPACT2, org2, '0 0 0', 1); + if(!w_issilent) + sound(actor, CH_SHOTS, SND_CRYLINK_IMPACT2, VOL_BASE, ATTN_NORM); + } + else + { + pointparticles(EFFECT_CRYLINK_IMPACT, org2, '0 0 0', 1); + if(!w_issilent) + sound(actor, CH_SHOTS, SND_CRYLINK_IMPACT, VOL_BASE, ATTN_NORM); + } } + #endif diff --git a/qcsrc/common/weapons/weapon/crylink.qh b/qcsrc/common/weapons/weapon/crylink.qh index 872bbcb1a..15b46ba72 100644 --- a/qcsrc/common/weapons/weapon/crylink.qh +++ b/qcsrc/common/weapons/weapon/crylink.qh @@ -22,39 +22,39 @@ CLASS(Crylink, Weapon) #define X(BEGIN, P, END, class, prefix) \ BEGIN(class) \ P(class, prefix, ammo, float, BOTH) \ - P(class, prefix, animtime, float, BOTH) \ - P(class, prefix, bouncedamagefactor, float, BOTH) \ - P(class, prefix, bounces, float, BOTH) \ - P(class, prefix, damage, float, BOTH) \ - P(class, prefix, edgedamage, float, BOTH) \ - P(class, prefix, force, float, BOTH) \ - P(class, prefix, joindelay, float, BOTH) \ - P(class, prefix, joinexplode, float, BOTH) \ - P(class, prefix, joinexplode_damage, float, BOTH) \ - P(class, prefix, joinexplode_edgedamage, float, BOTH) \ - P(class, prefix, joinexplode_force, float, BOTH) \ - P(class, prefix, joinexplode_radius, float, BOTH) \ - P(class, prefix, joinspread, float, BOTH) \ - P(class, prefix, linkexplode, float, BOTH) \ - P(class, prefix, middle_fadetime, float, BOTH) \ - P(class, prefix, middle_lifetime, float, BOTH) \ - P(class, prefix, other_fadetime, float, BOTH) \ - P(class, prefix, other_lifetime, float, BOTH) \ - P(class, prefix, radius, float, BOTH) \ - P(class, prefix, refire, float, BOTH) \ - P(class, prefix, reload_ammo, float, NONE) \ - P(class, prefix, reload_time, float, NONE) \ - P(class, prefix, secondary, float, NONE) \ - P(class, prefix, shots, float, BOTH) \ - P(class, prefix, speed, float, BOTH) \ - P(class, prefix, spreadtype, float, SEC) \ - P(class, prefix, spread, float, BOTH) \ - P(class, prefix, switchdelay_drop, float, NONE) \ - P(class, prefix, switchdelay_raise, float, NONE) \ - P(class, prefix, weaponreplace, string, NONE) \ - P(class, prefix, weaponstartoverride, float, NONE) \ - P(class, prefix, weaponstart, float, NONE) \ - P(class, prefix, weaponthrowable, float, NONE) \ + P(class, prefix, animtime, float, BOTH) \ + P(class, prefix, bouncedamagefactor, float, BOTH) \ + P(class, prefix, bounces, float, BOTH) \ + P(class, prefix, damage, float, BOTH) \ + P(class, prefix, edgedamage, float, BOTH) \ + P(class, prefix, force, float, BOTH) \ + P(class, prefix, joindelay, float, BOTH) \ + P(class, prefix, joinexplode, float, BOTH) \ + P(class, prefix, joinexplode_damage, float, BOTH) \ + P(class, prefix, joinexplode_edgedamage, float, BOTH) \ + P(class, prefix, joinexplode_force, float, BOTH) \ + P(class, prefix, joinexplode_radius, float, BOTH) \ + P(class, prefix, joinspread, float, BOTH) \ + P(class, prefix, linkexplode, float, BOTH) \ + P(class, prefix, middle_fadetime, float, BOTH) \ + P(class, prefix, middle_lifetime, float, BOTH) \ + P(class, prefix, other_fadetime, float, BOTH) \ + P(class, prefix, other_lifetime, float, BOTH) \ + P(class, prefix, radius, float, BOTH) \ + P(class, prefix, refire, float, BOTH) \ + P(class, prefix, reload_ammo, float, NONE) \ + P(class, prefix, reload_time, float, NONE) \ + P(class, prefix, secondary, float, NONE) \ + P(class, prefix, shots, float, BOTH) \ + P(class, prefix, speed, float, BOTH) \ + P(class, prefix, spreadtype, float, SEC) \ + P(class, prefix, spread, float, BOTH) \ + P(class, prefix, switchdelay_drop, float, NONE) \ + P(class, prefix, switchdelay_raise, float, NONE) \ + P(class, prefix, weaponreplace, string, NONE) \ + P(class, prefix, weaponstartoverride, float, NONE) \ + P(class, prefix, weaponstart, float, NONE) \ + P(class, prefix, weaponthrowable, float, NONE) \ END() W_PROPS(X, Crylink, crylink) #undef X diff --git a/qcsrc/common/weapons/weapon/devastator.qc b/qcsrc/common/weapons/weapon/devastator.qc index d1f22665d..150e1b043 100644 --- a/qcsrc/common/weapons/weapon/devastator.qc +++ b/qcsrc/common/weapons/weapon/devastator.qc @@ -360,223 +360,230 @@ void W_Devastator_Attack(Weapon thiswep, entity actor, .entity weaponentity, int METHOD(Devastator, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { - if (!WEP_CVAR(WEP_DEVASTATOR, guidestop) && !actor.(weaponentity).rl_release) - { - int fired_rockets = 0; - IL_EACH(g_projectiles, it.realowner == actor && it.classname == "rocket", - { - fired_rockets++; - }); - // release PHYS_INPUT_BUTTON_ATCK after all fired rocket exploded otherwise bot can't fire again - if (!fired_rockets) - return; - } - - // aim and decide to fire if appropriate - float spd = WEP_CVAR(WEP_DEVASTATOR, speed); - // simulate rocket guide by calculating rocket trajectory with higher speed - // 20 times faster at 90 degrees guide rate - if (WEP_CVAR(WEP_DEVASTATOR, guiderate) > 0) - spd *= sqrt(WEP_CVAR(WEP_DEVASTATOR, guiderate)) * (20 / 9.489); // 9.489 ~= sqrt(90) - // no need to fire with high accuracy on large distances if rockets can be guided - bool shot_accurate = (WEP_CVAR(WEP_DEVASTATOR, guiderate) < 50); - PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, spd, 0, WEP_CVAR(WEP_DEVASTATOR, lifetime), false, shot_accurate); - float pred_time = bound(0.02, 0.02 + (8 - skill) * 0.01, 0.1); - if(skill >= 2) // skill 0 and 1 bots won't detonate rockets! - { - // decide whether to detonate rockets - float selfdamage = 0, teamdamage = 0, enemydamage = 0; - float pred_selfdamage = 0, pred_teamdamage = 0, pred_enemydamage = 0; - float edgedamage = WEP_CVAR(WEP_DEVASTATOR, edgedamage); - float coredamage = WEP_CVAR(WEP_DEVASTATOR, damage); - float edgeradius = WEP_CVAR(WEP_DEVASTATOR, radius); - IL_EACH(g_projectiles, it.realowner == actor && it.classname == "rocket", - { - entity rocket = it; - IL_EACH(g_bot_targets, it.bot_attack, - { - // code to calculate damage is similar to the one used in RadiusDamageForSource with some simplifications - vector target_pos = it.origin + (it.maxs - it.mins) * 0.5; - - float dist = vlen(target_pos - rocket.origin); - float dmg = 0; - if (dist <= edgeradius) - { - float f = (edgeradius > 0) ? max(0, 1 - (dist / edgeradius)) : 1; - dmg = coredamage * f + edgedamage * (1 - f); - } - - float pred_dist = vlen(target_pos + it.velocity * pred_time - (rocket.origin + rocket.velocity * pred_time)); - float pred_dmg = 0; - if (pred_dist <= edgeradius) - { - float f = (edgeradius > 0) ? max(0, 1 - (pred_dist / edgeradius)) : 1; - pred_dmg = coredamage * f + edgedamage * (1 - f); - } - - // count potential damage according to type of target - if(it == actor) - { - if(StatusEffects_active(STATUSEFFECT_Strength, it)) - dmg *= autocvar_g_balance_powerup_strength_damage; - if(StatusEffects_active(STATUSEFFECT_Shield, it)) - dmg *= autocvar_g_balance_powerup_invincible_takedamage; - // self damage reduction factor will be applied later to the total damage - selfdamage += dmg; - pred_selfdamage += pred_dmg; - } - else if(SAME_TEAM(it, actor)) - { - if(StatusEffects_active(STATUSEFFECT_Shield, it)) - dmg *= autocvar_g_balance_powerup_invincible_takedamage; - // bot strength factor will be applied later to the total damage - teamdamage += dmg; - pred_teamdamage += pred_dmg; - } - else if(bot_shouldattack(actor, it)) - { - if(StatusEffects_active(STATUSEFFECT_Shield, it)) - dmg *= autocvar_g_balance_powerup_invincible_takedamage; - // bot strength factor will be applied later to the total damage - enemydamage += dmg; - pred_enemydamage += pred_dmg; - } - }); - }); - - selfdamage *= autocvar_g_balance_selfdamagepercent; - pred_selfdamage *= autocvar_g_balance_selfdamagepercent; - if(StatusEffects_active(STATUSEFFECT_Strength, actor)) - { - // FIXME bots don't know whether team damage is enabled or not - teamdamage *= autocvar_g_balance_powerup_strength_damage; - pred_teamdamage *= autocvar_g_balance_powerup_strength_damage; - enemydamage *= autocvar_g_balance_powerup_strength_damage; - pred_enemydamage *= autocvar_g_balance_powerup_strength_damage; - } - - float good_damage = enemydamage; - float pred_good_damage = pred_enemydamage; - float bad_damage = selfdamage + teamdamage; - float pred_bad_damage = pred_selfdamage + pred_teamdamage; - - // detonate if predicted good damage is lower (current good damage is maximum) - // or if predicted bad damage is too much - if(good_damage > coredamage * 0.1 && good_damage > bad_damage * 1.5 - && (pred_good_damage < good_damage + 2 || pred_good_damage < pred_bad_damage * 1.5)) - { - PHYS_INPUT_BUTTON_ATCK2(actor) = true; - } - if(skill >= 7 && selfdamage > GetResource(actor, RES_HEALTH)) - PHYS_INPUT_BUTTON_ATCK2(actor) = false; - - // don't fire a new shot at the same time! - if(PHYS_INPUT_BUTTON_ATCK2(actor)) PHYS_INPUT_BUTTON_ATCK(actor) = false; - } + if (!WEP_CVAR(WEP_DEVASTATOR, guidestop) && !actor.(weaponentity).rl_release) + { + int fired_rockets = 0; + IL_EACH(g_projectiles, it.realowner == actor && it.classname == "rocket", + { + fired_rockets++; + }); + // release PHYS_INPUT_BUTTON_ATCK after all fired rocket exploded otherwise bot can't fire again + if (!fired_rockets) + return; + } + + // aim and decide to fire if appropriate + float spd = WEP_CVAR(WEP_DEVASTATOR, speed); + // simulate rocket guide by calculating rocket trajectory with higher speed + // 20 times faster at 90 degrees guide rate + if (WEP_CVAR(WEP_DEVASTATOR, guiderate) > 0) + spd *= sqrt(WEP_CVAR(WEP_DEVASTATOR, guiderate)) * (20 / 9.489); // 9.489 ~= sqrt(90) + // no need to fire with high accuracy on large distances if rockets can be guided + bool shot_accurate = (WEP_CVAR(WEP_DEVASTATOR, guiderate) < 50); + PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, spd, 0, WEP_CVAR(WEP_DEVASTATOR, lifetime), false, shot_accurate); + float pred_time = bound(0.02, 0.02 + (8 - skill) * 0.01, 0.1); + if(skill >= 2) // skill 0 and 1 bots won't detonate rockets! + { + // decide whether to detonate rockets + float selfdamage = 0, teamdamage = 0, enemydamage = 0; + float pred_selfdamage = 0, pred_teamdamage = 0, pred_enemydamage = 0; + float edgedamage = WEP_CVAR(WEP_DEVASTATOR, edgedamage); + float coredamage = WEP_CVAR(WEP_DEVASTATOR, damage); + float edgeradius = WEP_CVAR(WEP_DEVASTATOR, radius); + IL_EACH(g_projectiles, it.realowner == actor && it.classname == "rocket", + { + entity rocket = it; + IL_EACH(g_bot_targets, it.bot_attack, + { + // code to calculate damage is similar to the one used in RadiusDamageForSource with some simplifications + vector target_pos = it.origin + (it.maxs - it.mins) * 0.5; + + float dist = vlen(target_pos - rocket.origin); + float dmg = 0; + if (dist <= edgeradius) + { + float f = (edgeradius > 0) ? max(0, 1 - (dist / edgeradius)) : 1; + dmg = coredamage * f + edgedamage * (1 - f); + } + + float pred_dist = vlen(target_pos + it.velocity * pred_time - (rocket.origin + rocket.velocity * pred_time)); + float pred_dmg = 0; + if (pred_dist <= edgeradius) + { + float f = (edgeradius > 0) ? max(0, 1 - (pred_dist / edgeradius)) : 1; + pred_dmg = coredamage * f + edgedamage * (1 - f); + } + + // count potential damage according to type of target + if(it == actor) + { + if(StatusEffects_active(STATUSEFFECT_Strength, it)) + dmg *= autocvar_g_balance_powerup_strength_damage; + if(StatusEffects_active(STATUSEFFECT_Shield, it)) + dmg *= autocvar_g_balance_powerup_invincible_takedamage; + // self damage reduction factor will be applied later to the total damage + selfdamage += dmg; + pred_selfdamage += pred_dmg; + } + else if(SAME_TEAM(it, actor)) + { + if(StatusEffects_active(STATUSEFFECT_Shield, it)) + dmg *= autocvar_g_balance_powerup_invincible_takedamage; + // bot strength factor will be applied later to the total damage + teamdamage += dmg; + pred_teamdamage += pred_dmg; + } + else if(bot_shouldattack(actor, it)) + { + if(StatusEffects_active(STATUSEFFECT_Shield, it)) + dmg *= autocvar_g_balance_powerup_invincible_takedamage; + // bot strength factor will be applied later to the total damage + enemydamage += dmg; + pred_enemydamage += pred_dmg; + } + }); + }); + + selfdamage *= autocvar_g_balance_selfdamagepercent; + pred_selfdamage *= autocvar_g_balance_selfdamagepercent; + if(StatusEffects_active(STATUSEFFECT_Strength, actor)) + { + // FIXME bots don't know whether team damage is enabled or not + teamdamage *= autocvar_g_balance_powerup_strength_damage; + pred_teamdamage *= autocvar_g_balance_powerup_strength_damage; + enemydamage *= autocvar_g_balance_powerup_strength_damage; + pred_enemydamage *= autocvar_g_balance_powerup_strength_damage; + } + + float good_damage = enemydamage; + float pred_good_damage = pred_enemydamage; + float bad_damage = selfdamage + teamdamage; + float pred_bad_damage = pred_selfdamage + pred_teamdamage; + + // detonate if predicted good damage is lower (current good damage is maximum) + // or if predicted bad damage is too much + if(good_damage > coredamage * 0.1 && good_damage > bad_damage * 1.5 + && (pred_good_damage < good_damage + 2 || pred_good_damage < pred_bad_damage * 1.5)) + { + PHYS_INPUT_BUTTON_ATCK2(actor) = true; + } + if(skill >= 7 && selfdamage > GetResource(actor, RES_HEALTH)) + PHYS_INPUT_BUTTON_ATCK2(actor) = false; + + // don't fire a new shot at the same time! + if(PHYS_INPUT_BUTTON_ATCK2(actor)) PHYS_INPUT_BUTTON_ATCK(actor) = false; + } } METHOD(Devastator, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) { - if(WEP_CVAR(WEP_DEVASTATOR, reload_ammo) && actor.(weaponentity).clip_load < WEP_CVAR(WEP_DEVASTATOR, ammo)) { // forced reload - thiswep.wr_reload(thiswep, actor, weaponentity); - } else { - if(fire & 1) - { - if(actor.(weaponentity).rl_release || WEP_CVAR(WEP_DEVASTATOR, guidestop)) - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(WEP_DEVASTATOR, refire))) - { - W_Devastator_Attack(thiswep, actor, weaponentity, fire); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(WEP_DEVASTATOR, animtime), w_ready); - actor.(weaponentity).rl_release = 0; - } - } - else - actor.(weaponentity).rl_release = 1; - - if(fire & 2) - if(actor.(weaponentity).m_switchweapon == thiswep) - { - bool rockfound = false; - IL_EACH(g_projectiles, it.realowner == actor && it.classname == "rocket", - { - if(!it.rl_detonate_later) - { - it.rl_detonate_later = true; - rockfound = true; - } - }); - if(rockfound) - sound(actor, CH_WEAPON_B, SND_ROCKET_DET, VOL_BASE, ATTN_NORM); - } - } + if(WEP_CVAR(WEP_DEVASTATOR, reload_ammo) && actor.(weaponentity).clip_load < WEP_CVAR(WEP_DEVASTATOR, ammo)) { // forced reload + thiswep.wr_reload(thiswep, actor, weaponentity); + } else { + if(fire & 1) + { + if(actor.(weaponentity).rl_release || WEP_CVAR(WEP_DEVASTATOR, guidestop)) + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(WEP_DEVASTATOR, refire))) + { + W_Devastator_Attack(thiswep, actor, weaponentity, fire); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(WEP_DEVASTATOR, animtime), w_ready); + actor.(weaponentity).rl_release = 0; + } + } + else + actor.(weaponentity).rl_release = 1; + + if(fire & 2) + if(actor.(weaponentity).m_switchweapon == thiswep) + { + bool rockfound = false; + IL_EACH(g_projectiles, it.realowner == actor && it.classname == "rocket", + { + if(!it.rl_detonate_later) + { + it.rl_detonate_later = true; + rockfound = true; + } + }); + if(rockfound) + sound(actor, CH_WEAPON_B, SND_ROCKET_DET, VOL_BASE, ATTN_NORM); + } + } } + METHOD(Devastator, wr_setup, void(entity thiswep, entity actor, .entity weaponentity)) { - actor.(weaponentity).rl_release = 1; + actor.(weaponentity).rl_release = 1; } + METHOD(Devastator, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity)) { - #if 0 - // don't switch while guiding a missile - if(ATTACK_FINISHED(actor, weaponentity) <= time || PS(actor).m_weapon != WEP_DEVASTATOR) - { - ammo_amount = false; - if(WEP_CVAR(WEP_DEVASTATOR, reload_ammo)) - { - if(GetResource(actor, thiswep.ammo_type) < WEP_CVAR(WEP_DEVASTATOR, ammo) && actor.(weaponentity).(weapon_load[WEP_DEVASTATOR.m_id]) < WEP_CVAR(WEP_DEVASTATOR, ammo)) - ammo_amount = true; - } - else if(GetResource(actor, thiswep.ammo_type) < WEP_CVAR(WEP_DEVASTATOR, ammo)) - ammo_amount = true; - return !ammo_amount; - } - #endif - #if 0 - if(actor.rl_release == 0) - { - LOG_INFOF("W_Devastator(WR_CHECKAMMO1): %d, %.2f, %d: TRUE", actor.rl_release, GetResource(actor, thiswep.ammo_type), WEP_CVAR(WEP_DEVASTATOR, ammo)); - return true; - } - else - { - ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR(WEP_DEVASTATOR, ammo); - ammo_amount += actor.(weaponentity).(weapon_load[WEP_DEVASTATOR.m_id]) >= WEP_CVAR(WEP_DEVASTATOR, ammo); - LOG_INFOF("W_Devastator(WR_CHECKAMMO1): %d, %.2f, %d: %s", actor.rl_release, GetResource(actor, thiswep.ammo_type), WEP_CVAR(WEP_DEVASTATOR, ammo), (ammo_amount ? "TRUE" : "FALSE")); - return ammo_amount; - } - #else - float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR(WEP_DEVASTATOR, ammo); - ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR(WEP_DEVASTATOR, ammo); - return ammo_amount; - #endif + #if 0 + // don't switch while guiding a missile + if(ATTACK_FINISHED(actor, weaponentity) <= time || PS(actor).m_weapon != WEP_DEVASTATOR) + { + ammo_amount = false; + if(WEP_CVAR(WEP_DEVASTATOR, reload_ammo)) + { + if(GetResource(actor, thiswep.ammo_type) < WEP_CVAR(WEP_DEVASTATOR, ammo) && actor.(weaponentity).(weapon_load[WEP_DEVASTATOR.m_id]) < WEP_CVAR(WEP_DEVASTATOR, ammo)) + ammo_amount = true; + } + else if(GetResource(actor, thiswep.ammo_type) < WEP_CVAR(WEP_DEVASTATOR, ammo)) + ammo_amount = true; + return !ammo_amount; + } + #endif + #if 0 + if(actor.rl_release == 0) + { + LOG_INFOF("W_Devastator(WR_CHECKAMMO1): %d, %.2f, %d: TRUE", actor.rl_release, GetResource(actor, thiswep.ammo_type), WEP_CVAR(WEP_DEVASTATOR, ammo)); + return true; + } + else + { + ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR(WEP_DEVASTATOR, ammo); + ammo_amount += actor.(weaponentity).(weapon_load[WEP_DEVASTATOR.m_id]) >= WEP_CVAR(WEP_DEVASTATOR, ammo); + LOG_INFOF("W_Devastator(WR_CHECKAMMO1): %d, %.2f, %d: %s", actor.rl_release, GetResource(actor, thiswep.ammo_type), WEP_CVAR(WEP_DEVASTATOR, ammo), (ammo_amount ? "TRUE" : "FALSE")); + return ammo_amount; + } + #else + float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR(WEP_DEVASTATOR, ammo); + ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR(WEP_DEVASTATOR, ammo); + return ammo_amount; + #endif } + METHOD(Devastator, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity)) { - return false; + return false; } + METHOD(Devastator, wr_resetplayer, void(entity thiswep, entity actor)) { - for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) - { - .entity weaponentity = weaponentities[slot]; - actor.(weaponentity).lastrocket = NULL; // stop rocket guiding, no revenge from the grave! - actor.(weaponentity).rl_release = 0; - } + for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + { + .entity weaponentity = weaponentities[slot]; + actor.(weaponentity).lastrocket = NULL; // stop rocket guiding, no revenge from the grave! + actor.(weaponentity).rl_release = 0; + } } + METHOD(Devastator, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) { - W_Reload(actor, weaponentity, WEP_CVAR(WEP_DEVASTATOR, ammo), SND_RELOAD); + W_Reload(actor, weaponentity, WEP_CVAR(WEP_DEVASTATOR, ammo), SND_RELOAD); } + METHOD(Devastator, wr_suicidemessage, Notification(entity thiswep)) { - return WEAPON_DEVASTATOR_SUICIDE; + return WEAPON_DEVASTATOR_SUICIDE; } + METHOD(Devastator, wr_killmessage, Notification(entity thiswep)) { - if((w_deathtype & HITTYPE_BOUNCE) || (w_deathtype & HITTYPE_SPLASH)) - return WEAPON_DEVASTATOR_MURDER_SPLASH; - else - return WEAPON_DEVASTATOR_MURDER_DIRECT; + if((w_deathtype & HITTYPE_BOUNCE) || (w_deathtype & HITTYPE_SPLASH)) + return WEAPON_DEVASTATOR_MURDER_SPLASH; + else + return WEAPON_DEVASTATOR_MURDER_DIRECT; } #endif @@ -584,10 +591,10 @@ METHOD(Devastator, wr_killmessage, Notification(entity thiswep)) METHOD(Devastator, wr_impacteffect, void(entity thiswep, entity actor)) { - vector org2 = w_org + w_backoff * 2; - pointparticles(EFFECT_ROCKET_EXPLODE, org2, '0 0 0', 1); - if(!w_issilent) - sound(actor, CH_SHOTS, SND_ROCKET_IMPACT, VOL_BASE, ATTN_NORM); + vector org2 = w_org + w_backoff * 2; + pointparticles(EFFECT_ROCKET_EXPLODE, org2, '0 0 0', 1); + if(!w_issilent) + sound(actor, CH_SHOTS, SND_ROCKET_IMPACT, VOL_BASE, ATTN_NORM); } #endif diff --git a/qcsrc/common/weapons/weapon/devastator.qh b/qcsrc/common/weapons/weapon/devastator.qh index 39fa37613..01f3b59f3 100644 --- a/qcsrc/common/weapons/weapon/devastator.qh +++ b/qcsrc/common/weapons/weapon/devastator.qh @@ -23,37 +23,37 @@ CLASS(Devastator, Weapon) #define X(BEGIN, P, END, class, prefix) \ BEGIN(class) \ P(class, prefix, ammo, float, NONE) \ - P(class, prefix, animtime, float, NONE) \ - P(class, prefix, damageforcescale, float, NONE) \ - P(class, prefix, damage, float, NONE) \ - P(class, prefix, detonatedelay, float, NONE) \ - P(class, prefix, edgedamage, float, NONE) \ - P(class, prefix, force, float, NONE) \ - P(class, prefix, guidedelay, float, NONE) \ - P(class, prefix, guidegoal, float, NONE) \ - P(class, prefix, guideratedelay, float, NONE) \ - P(class, prefix, guiderate, float, NONE) \ - P(class, prefix, guidestop, float, NONE) \ - P(class, prefix, health, float, NONE) \ - P(class, prefix, lifetime, float, NONE) \ - P(class, prefix, radius, float, NONE) \ - P(class, prefix, refire, float, NONE) \ + P(class, prefix, animtime, float, NONE) \ + P(class, prefix, damageforcescale, float, NONE) \ + P(class, prefix, damage, float, NONE) \ + P(class, prefix, detonatedelay, float, NONE) \ + P(class, prefix, edgedamage, float, NONE) \ + P(class, prefix, force, float, NONE) \ + P(class, prefix, guidedelay, float, NONE) \ + P(class, prefix, guidegoal, float, NONE) \ + P(class, prefix, guideratedelay, float, NONE) \ + P(class, prefix, guiderate, float, NONE) \ + P(class, prefix, guidestop, float, NONE) \ + P(class, prefix, health, float, NONE) \ + P(class, prefix, lifetime, float, NONE) \ + P(class, prefix, radius, float, NONE) \ + P(class, prefix, refire, float, NONE) \ P(class, prefix, reload_ammo, float, NONE) \ P(class, prefix, reload_time, float, NONE) \ - P(class, prefix, remote_damage, float, NONE) \ - P(class, prefix, remote_edgedamage, float, NONE) \ - P(class, prefix, remote_force, float, NONE) \ - P(class, prefix, remote_jump, float, NONE) \ - P(class, prefix, remote_jump_damage, float, NONE) \ - P(class, prefix, remote_jump_force, float, NONE) \ - P(class, prefix, remote_jump_radius, float, NONE) \ - P(class, prefix, remote_jump_velocity_z_add, float, NONE) \ - P(class, prefix, remote_jump_velocity_z_max, float, NONE) \ - P(class, prefix, remote_jump_velocity_z_min, float, NONE) \ - P(class, prefix, remote_radius, float, NONE) \ - P(class, prefix, speedaccel, float, NONE) \ - P(class, prefix, speedstart, float, NONE) \ - P(class, prefix, speed, float, NONE) \ + P(class, prefix, remote_damage, float, NONE) \ + P(class, prefix, remote_edgedamage, float, NONE) \ + P(class, prefix, remote_force, float, NONE) \ + P(class, prefix, remote_jump, float, NONE) \ + P(class, prefix, remote_jump_damage, float, NONE) \ + P(class, prefix, remote_jump_force, float, NONE) \ + P(class, prefix, remote_jump_radius, float, NONE) \ + P(class, prefix, remote_jump_velocity_z_add, float, NONE) \ + P(class, prefix, remote_jump_velocity_z_max, float, NONE) \ + P(class, prefix, remote_jump_velocity_z_min, float, NONE) \ + P(class, prefix, remote_radius, float, NONE) \ + P(class, prefix, speedaccel, float, NONE) \ + P(class, prefix, speedstart, float, NONE) \ + P(class, prefix, speed, float, NONE) \ P(class, prefix, switchdelay_drop, float, NONE) \ P(class, prefix, switchdelay_raise, float, NONE) \ P(class, prefix, weaponreplace, string,NONE) \ diff --git a/qcsrc/common/weapons/weapon/electro.qc b/qcsrc/common/weapons/weapon/electro.qc index d45810c08..8d4b85628 100644 --- a/qcsrc/common/weapons/weapon/electro.qc +++ b/qcsrc/common/weapons/weapon/electro.qc @@ -329,11 +329,10 @@ void W_Electro_Orb_Stick(entity this, entity to) newproj.weaponentity_fld = this.weaponentity_fld; settouch(newproj, func_null); - if(WEP_CVAR_SEC(WEP_ELECTRO, stick_lifetime) > 0){ + if(WEP_CVAR_SEC(WEP_ELECTRO, stick_lifetime) > 0) newproj.death_time = time + WEP_CVAR_SEC(WEP_ELECTRO, stick_lifetime); - }else{ + else newproj.death_time = this.death_time; - } newproj.use = this.use; newproj.flags = this.flags; IL_PUSH(g_projectiles, newproj); @@ -365,19 +364,21 @@ void W_Electro_Orb_Touch(entity this, entity toucher) { PROJECTILE_TOUCH(this, toucher); if(toucher.takedamage == DAMAGE_AIM && WEP_CVAR_SEC(WEP_ELECTRO, touchexplode)) - { W_Electro_Explode(this, toucher); } + { + W_Electro_Explode(this, toucher); + } else if(toucher.owner != this.owner && toucher.classname != this.classname) // don't stick to player's other projectiles! { //UpdateCSQCProjectile(this); spamsound(this, CH_SHOTS, SND_ELECTRO_BOUNCE, VOL_BASE, ATTEN_NORM); this.projectiledeathtype |= HITTYPE_BOUNCE; - if(WEP_CVAR_SEC(WEP_ELECTRO, stick)){ - if(WEP_CVAR_SEC(WEP_ELECTRO, stick_lifetime) == 0){ + if(WEP_CVAR_SEC(WEP_ELECTRO, stick)) + { + if(WEP_CVAR_SEC(WEP_ELECTRO, stick_lifetime) == 0) W_Electro_Explode(this, toucher); - } else { + else W_Electro_Orb_Stick(this, toucher); - } } } } @@ -505,115 +506,121 @@ void W_Electro_CheckAttack(Weapon thiswep, entity actor, .entity weaponentity, i METHOD(Electro, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { - PHYS_INPUT_BUTTON_ATCK(actor) = PHYS_INPUT_BUTTON_ATCK2(actor) = false; - if(vdist(actor.origin - actor.enemy.origin, >, 1000)) { actor.bot_secondary_electromooth = 0; } - if(actor.bot_secondary_electromooth == 0) - { - float shoot; - - if(WEP_CVAR_PRI(WEP_ELECTRO, speed)) - shoot = bot_aim(actor, weaponentity, WEP_CVAR_PRI(WEP_ELECTRO, speed), 0, WEP_CVAR_PRI(WEP_ELECTRO, lifetime), false, true); - else - shoot = bot_aim(actor, weaponentity, 1000000, 0, 0.001, false, true); - - if(shoot) - { - PHYS_INPUT_BUTTON_ATCK(actor) = true; - if(random() < 0.01) actor.bot_secondary_electromooth = 1; - } - } - else - { - if(bot_aim(actor, weaponentity, WEP_CVAR_SEC(WEP_ELECTRO, speed), WEP_CVAR_SEC(WEP_ELECTRO, speed_up), WEP_CVAR_SEC(WEP_ELECTRO, lifetime), true, true)) - { - PHYS_INPUT_BUTTON_ATCK2(actor) = true; - if(random() < 0.03) actor.bot_secondary_electromooth = 0; - } - } + PHYS_INPUT_BUTTON_ATCK(actor) = PHYS_INPUT_BUTTON_ATCK2(actor) = false; + if(vdist(actor.origin - actor.enemy.origin, >, 1000)) { actor.bot_secondary_electromooth = 0; } + if(actor.bot_secondary_electromooth == 0) + { + float shoot; + + if(WEP_CVAR_PRI(WEP_ELECTRO, speed)) + shoot = bot_aim(actor, weaponentity, WEP_CVAR_PRI(WEP_ELECTRO, speed), 0, WEP_CVAR_PRI(WEP_ELECTRO, lifetime), false, true); + else + shoot = bot_aim(actor, weaponentity, 1000000, 0, 0.001, false, true); + + if(shoot) + { + PHYS_INPUT_BUTTON_ATCK(actor) = true; + if(random() < 0.01) actor.bot_secondary_electromooth = 1; + } + } + else + { + if(bot_aim(actor, weaponentity, WEP_CVAR_SEC(WEP_ELECTRO, speed), WEP_CVAR_SEC(WEP_ELECTRO, speed_up), WEP_CVAR_SEC(WEP_ELECTRO, lifetime), true, true)) + { + PHYS_INPUT_BUTTON_ATCK2(actor) = true; + if(random() < 0.03) actor.bot_secondary_electromooth = 0; + } + } } + METHOD(Electro, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) { - if(autocvar_g_balance_electro_reload_ammo) // forced reload // WEAPONTODO - { - float ammo_amount = 0; - if(actor.(weaponentity).clip_load >= WEP_CVAR_PRI(WEP_ELECTRO, ammo)) - ammo_amount = 1; - if(actor.(weaponentity).clip_load >= WEP_CVAR_SEC(WEP_ELECTRO, ammo)) - ammo_amount += 1; - - if(!ammo_amount) - { - thiswep.wr_reload(thiswep, actor, weaponentity); - return; - } - } - - if(fire & 1) - { - if(time >= actor.(weaponentity).electro_secondarytime + WEP_CVAR_SEC(WEP_ELECTRO, refire2) * W_WeaponRateFactor(actor)) - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(WEP_ELECTRO, refire))) - { - W_Electro_Attack_Bolt(thiswep, actor, weaponentity); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(WEP_ELECTRO, animtime), w_ready); - } - } - else if(fire & 2) - { - if(time >= actor.(weaponentity).electro_secondarytime + WEP_CVAR_SEC(WEP_ELECTRO, refire) * W_WeaponRateFactor(actor)) - if(weapon_prepareattack(thiswep, actor, weaponentity, true, -1)) - { - W_Electro_Attack_Orb(thiswep, actor, weaponentity); - actor.(weaponentity).electro_count = WEP_CVAR_SEC(WEP_ELECTRO, count); - actor.(weaponentity).electro_secondarytime = time; - weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(WEP_ELECTRO, animtime), W_Electro_CheckAttack); - } - } + if(autocvar_g_balance_electro_reload_ammo) // forced reload // WEAPONTODO + { + float ammo_amount = 0; + if(actor.(weaponentity).clip_load >= WEP_CVAR_PRI(WEP_ELECTRO, ammo)) + ammo_amount = 1; + if(actor.(weaponentity).clip_load >= WEP_CVAR_SEC(WEP_ELECTRO, ammo)) + ammo_amount += 1; + + if(!ammo_amount) + { + thiswep.wr_reload(thiswep, actor, weaponentity); + return; + } + } + + if(fire & 1) + { + if(time >= actor.(weaponentity).electro_secondarytime + WEP_CVAR_SEC(WEP_ELECTRO, refire2) * W_WeaponRateFactor(actor)) + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(WEP_ELECTRO, refire))) + { + W_Electro_Attack_Bolt(thiswep, actor, weaponentity); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(WEP_ELECTRO, animtime), w_ready); + } + } + else if(fire & 2) + { + if(time >= actor.(weaponentity).electro_secondarytime + WEP_CVAR_SEC(WEP_ELECTRO, refire) * W_WeaponRateFactor(actor)) + if(weapon_prepareattack(thiswep, actor, weaponentity, true, -1)) + { + W_Electro_Attack_Orb(thiswep, actor, weaponentity); + actor.(weaponentity).electro_count = WEP_CVAR_SEC(WEP_ELECTRO, count); + actor.(weaponentity).electro_secondarytime = time; + weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(WEP_ELECTRO, animtime), W_Electro_CheckAttack); + } + } } + METHOD(Electro, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity)) { - float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_PRI(WEP_ELECTRO, ammo); - ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_PRI(WEP_ELECTRO, ammo); - return ammo_amount; + float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_PRI(WEP_ELECTRO, ammo); + ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_PRI(WEP_ELECTRO, ammo); + return ammo_amount; } + METHOD(Electro, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity)) { - float ammo_amount; - if(WEP_CVAR(WEP_ELECTRO, combo_safeammocheck)) // true if you can fire at least one secondary blob AND one primary shot after it, otherwise false. - { - ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_SEC(WEP_ELECTRO, ammo) + WEP_CVAR_PRI(WEP_ELECTRO, ammo); - ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_SEC(WEP_ELECTRO, ammo) + WEP_CVAR_PRI(WEP_ELECTRO, ammo); - } - else - { - ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_SEC(WEP_ELECTRO, ammo); - ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_SEC(WEP_ELECTRO, ammo); - } - return ammo_amount; + float ammo_amount; + if(WEP_CVAR(WEP_ELECTRO, combo_safeammocheck)) // true if you can fire at least one secondary blob AND one primary shot after it, otherwise false. + { + ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_SEC(WEP_ELECTRO, ammo) + WEP_CVAR_PRI(WEP_ELECTRO, ammo); + ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_SEC(WEP_ELECTRO, ammo) + WEP_CVAR_PRI(WEP_ELECTRO, ammo); + } + else + { + ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_SEC(WEP_ELECTRO, ammo); + ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_SEC(WEP_ELECTRO, ammo); + } + return ammo_amount; } + METHOD(Electro, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) { - W_Reload(actor, weaponentity, min(WEP_CVAR_PRI(WEP_ELECTRO, ammo), WEP_CVAR_SEC(WEP_ELECTRO, ammo)), SND_RELOAD); + W_Reload(actor, weaponentity, min(WEP_CVAR_PRI(WEP_ELECTRO, ammo), WEP_CVAR_SEC(WEP_ELECTRO, ammo)), SND_RELOAD); } + METHOD(Electro, wr_suicidemessage, Notification(entity thiswep)) { - if(w_deathtype & HITTYPE_SECONDARY) - return WEAPON_ELECTRO_SUICIDE_ORBS; - else - return WEAPON_ELECTRO_SUICIDE_BOLT; + if(w_deathtype & HITTYPE_SECONDARY) + return WEAPON_ELECTRO_SUICIDE_ORBS; + else + return WEAPON_ELECTRO_SUICIDE_BOLT; } + METHOD(Electro, wr_killmessage, Notification(entity thiswep)) { - if(w_deathtype & HITTYPE_SECONDARY) - { - return WEAPON_ELECTRO_MURDER_ORBS; - } - else - { - if(w_deathtype & HITTYPE_BOUNCE) - return WEAPON_ELECTRO_MURDER_COMBO; - else - return WEAPON_ELECTRO_MURDER_BOLT; - } + if(w_deathtype & HITTYPE_SECONDARY) + { + return WEAPON_ELECTRO_MURDER_ORBS; + } + else + { + if(w_deathtype & HITTYPE_BOUNCE) + return WEAPON_ELECTRO_MURDER_COMBO; + else + return WEAPON_ELECTRO_MURDER_BOLT; + } } #endif @@ -621,29 +628,29 @@ METHOD(Electro, wr_killmessage, Notification(entity thiswep)) METHOD(Electro, wr_impacteffect, void(entity thiswep, entity actor)) { - vector org2 = w_org + w_backoff * 2; - if(w_deathtype & HITTYPE_SECONDARY) - { - pointparticles(EFFECT_ELECTRO_BALLEXPLODE, org2, '0 0 0', 1); - if(!w_issilent) - sound(actor, CH_SHOTS, SND_ELECTRO_IMPACT, VOL_BASE, ATTEN_NORM); - } - else - { - if(w_deathtype & HITTYPE_BOUNCE) - { - // this is sent as "primary (w_deathtype & HITTYPE_BOUNCE)" to distinguish it from (w_deathtype & HITTYPE_SECONDARY) bounced balls - pointparticles(EFFECT_ELECTRO_COMBO, org2, '0 0 0', 1); - if(!w_issilent) - sound(actor, CH_SHOTS, SND_ELECTRO_IMPACT_COMBO, VOL_BASE, ATTEN_NORM); - } - else - { - pointparticles(EFFECT_ELECTRO_IMPACT, org2, '0 0 0', 1); - if(!w_issilent) - sound(actor, CH_SHOTS, SND_ELECTRO_IMPACT, VOL_BASE, ATTEN_NORM); - } - } + vector org2 = w_org + w_backoff * 2; + if(w_deathtype & HITTYPE_SECONDARY) + { + pointparticles(EFFECT_ELECTRO_BALLEXPLODE, org2, '0 0 0', 1); + if(!w_issilent) + sound(actor, CH_SHOTS, SND_ELECTRO_IMPACT, VOL_BASE, ATTEN_NORM); + } + else + { + if(w_deathtype & HITTYPE_BOUNCE) + { + // this is sent as "primary (w_deathtype & HITTYPE_BOUNCE)" to distinguish it from (w_deathtype & HITTYPE_SECONDARY) bounced balls + pointparticles(EFFECT_ELECTRO_COMBO, org2, '0 0 0', 1); + if(!w_issilent) + sound(actor, CH_SHOTS, SND_ELECTRO_IMPACT_COMBO, VOL_BASE, ATTEN_NORM); + } + else + { + pointparticles(EFFECT_ELECTRO_IMPACT, org2, '0 0 0', 1); + if(!w_issilent) + sound(actor, CH_SHOTS, SND_ELECTRO_IMPACT, VOL_BASE, ATTEN_NORM); + } + } } #endif diff --git a/qcsrc/common/weapons/weapon/fireball.qc b/qcsrc/common/weapons/weapon/fireball.qc index 323da5c11..6e6cc8a68 100644 --- a/qcsrc/common/weapons/weapon/fireball.qc +++ b/qcsrc/common/weapons/weapon/fireball.qc @@ -338,74 +338,80 @@ void W_Fireball_Attack2(entity actor, .entity weaponentity) METHOD(Fireball, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { - PHYS_INPUT_BUTTON_ATCK(actor) = false; - PHYS_INPUT_BUTTON_ATCK2(actor) = false; - if(actor.bot_primary_fireballmooth == 0) - { - if(bot_aim(actor, weaponentity, WEP_CVAR_PRI(WEP_FIREBALL, speed), 0, WEP_CVAR_PRI(WEP_FIREBALL, lifetime), false, false)) - { - PHYS_INPUT_BUTTON_ATCK(actor) = true; - if(random() < 0.02) actor.bot_primary_fireballmooth = 1; - } - } - else - { - if(bot_aim(actor, weaponentity, WEP_CVAR_SEC(WEP_FIREBALL, speed), WEP_CVAR_SEC(WEP_FIREBALL, speed_up), WEP_CVAR_SEC(WEP_FIREBALL, lifetime), true, false)) - { - PHYS_INPUT_BUTTON_ATCK2(actor) = true; - if(random() < 0.01) actor.bot_primary_fireballmooth = 0; - } - } + PHYS_INPUT_BUTTON_ATCK(actor) = false; + PHYS_INPUT_BUTTON_ATCK2(actor) = false; + if(actor.bot_primary_fireballmooth == 0) + { + if(bot_aim(actor, weaponentity, WEP_CVAR_PRI(WEP_FIREBALL, speed), 0, WEP_CVAR_PRI(WEP_FIREBALL, lifetime), false, false)) + { + PHYS_INPUT_BUTTON_ATCK(actor) = true; + if(random() < 0.02) actor.bot_primary_fireballmooth = 1; + } + } + else + { + if(bot_aim(actor, weaponentity, WEP_CVAR_SEC(WEP_FIREBALL, speed), WEP_CVAR_SEC(WEP_FIREBALL, speed_up), WEP_CVAR_SEC(WEP_FIREBALL, lifetime), true, false)) + { + PHYS_INPUT_BUTTON_ATCK2(actor) = true; + if(random() < 0.01) actor.bot_primary_fireballmooth = 0; + } + } } + METHOD(Fireball, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) { - if(fire & 1) - { - if(time >= actor.(weaponentity).fireball_primarytime) - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(WEP_FIREBALL, refire))) - { - W_Fireball_Attack1_Frame0(thiswep, actor, weaponentity, fire); - actor.(weaponentity).fireball_primarytime = time + WEP_CVAR_PRI(WEP_FIREBALL, refire2) * W_WeaponRateFactor(actor); - } - } - else if(fire & 2) - { - if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(WEP_FIREBALL, refire))) - { - W_Fireball_Attack2(actor, weaponentity); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(WEP_FIREBALL, animtime), w_ready); - } - } + if(fire & 1) + { + if(time >= actor.(weaponentity).fireball_primarytime) + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(WEP_FIREBALL, refire))) + { + W_Fireball_Attack1_Frame0(thiswep, actor, weaponentity, fire); + actor.(weaponentity).fireball_primarytime = time + WEP_CVAR_PRI(WEP_FIREBALL, refire2) * W_WeaponRateFactor(actor); + } + } + else if(fire & 2) + { + if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(WEP_FIREBALL, refire))) + { + W_Fireball_Attack2(actor, weaponentity); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(WEP_FIREBALL, animtime), w_ready); + } + } } + METHOD(Fireball, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity)) { - return true; // infinite ammo + return true; // infinite ammo } + METHOD(Fireball, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity)) { - return true; // fireball has infinite ammo + return true; // fireball has infinite ammo } + METHOD(Fireball, wr_resetplayer, void(entity thiswep, entity actor)) { for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) { .entity weaponentity = weaponentities[slot]; - actor.(weaponentity).fireball_primarytime = time; + actor.(weaponentity).fireball_primarytime = time; } } + METHOD(Fireball, wr_suicidemessage, Notification(entity thiswep)) { - if(w_deathtype & HITTYPE_SECONDARY) - return WEAPON_FIREBALL_SUICIDE_FIREMINE; - else - return WEAPON_FIREBALL_SUICIDE_BLAST; + if(w_deathtype & HITTYPE_SECONDARY) + return WEAPON_FIREBALL_SUICIDE_FIREMINE; + else + return WEAPON_FIREBALL_SUICIDE_BLAST; } + METHOD(Fireball, wr_killmessage, Notification(entity thiswep)) { - if(w_deathtype & HITTYPE_SECONDARY) - return WEAPON_FIREBALL_MURDER_FIREMINE; - else - return WEAPON_FIREBALL_MURDER_BLAST; + if(w_deathtype & HITTYPE_SECONDARY) + return WEAPON_FIREBALL_MURDER_FIREMINE; + else + return WEAPON_FIREBALL_MURDER_BLAST; } #endif @@ -413,17 +419,17 @@ METHOD(Fireball, wr_killmessage, Notification(entity thiswep)) METHOD(Fireball, wr_impacteffect, void(entity thiswep, entity actor)) { - if(w_deathtype & HITTYPE_SECONDARY) - { - // firemine goes out silently - } - else - { - vector org2 = w_org + w_backoff * 2; - pointparticles(EFFECT_FIREBALL_EXPLODE, org2, '0 0 0', 1); - if(!w_issilent) - sound(actor, CH_SHOTS, SND_FIREBALL_IMPACT2, VOL_BASE, ATTEN_NORM * 0.25); // long range boom - } + if(w_deathtype & HITTYPE_SECONDARY) + { + // firemine goes out silently + } + else + { + vector org2 = w_org + w_backoff * 2; + pointparticles(EFFECT_FIREBALL_EXPLODE, org2, '0 0 0', 1); + if(!w_issilent) + sound(actor, CH_SHOTS, SND_FIREBALL_IMPACT2, VOL_BASE, ATTEN_NORM * 0.25); // long range boom + } } #endif diff --git a/qcsrc/common/weapons/weapon/hagar.qc b/qcsrc/common/weapons/weapon/hagar.qc index fb404d998..15d8203d8 100644 --- a/qcsrc/common/weapons/weapon/hagar.qc +++ b/qcsrc/common/weapons/weapon/hagar.qc @@ -377,94 +377,104 @@ void W_Hagar_Attack_Auto(Weapon thiswep, entity actor, .entity weaponentity, int METHOD(Hagar, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { - if(random()>0.15) - PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, WEP_CVAR_PRI(WEP_HAGAR, speed), 0, WEP_CVAR_PRI(WEP_HAGAR, lifetime), false, true); - else // not using secondary_speed since these are only 15% and should cause some ricochets without re-aiming - PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, weaponentity, WEP_CVAR_PRI(WEP_HAGAR, speed), 0, WEP_CVAR_PRI(WEP_HAGAR, lifetime), false, true); + if(random()>0.15) + PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, WEP_CVAR_PRI(WEP_HAGAR, speed), 0, WEP_CVAR_PRI(WEP_HAGAR, lifetime), false, true); + else // not using secondary_speed since these are only 15% and should cause some ricochets without re-aiming + PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, weaponentity, WEP_CVAR_PRI(WEP_HAGAR, speed), 0, WEP_CVAR_PRI(WEP_HAGAR, lifetime), false, true); } + METHOD(Hagar, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) { - float loadable_secondary; - loadable_secondary = (WEP_CVAR_SEC(WEP_HAGAR, load) && WEP_CVAR(WEP_HAGAR, secondary)); - - if(loadable_secondary) - W_Hagar_Attack2_Load(thiswep, actor, weaponentity); // must always run each frame - if(autocvar_g_balance_hagar_reload_ammo && actor.(weaponentity).clip_load < min(WEP_CVAR_PRI(WEP_HAGAR, ammo), WEP_CVAR_SEC(WEP_HAGAR, ammo))) { // forced reload - thiswep.wr_reload(thiswep, actor, weaponentity); - } - else if((fire & 1) && !actor.(weaponentity).hagar_load && !actor.(weaponentity).hagar_loadblock) // not while secondary is loaded or awaiting reset + float loadable_secondary; + loadable_secondary = (WEP_CVAR_SEC(WEP_HAGAR, load) && WEP_CVAR(WEP_HAGAR, secondary)); + + if(loadable_secondary) + W_Hagar_Attack2_Load(thiswep, actor, weaponentity); // must always run each frame + if(autocvar_g_balance_hagar_reload_ammo && actor.(weaponentity).clip_load < min(WEP_CVAR_PRI(WEP_HAGAR, ammo), WEP_CVAR_SEC(WEP_HAGAR, ammo))) { // forced reload + thiswep.wr_reload(thiswep, actor, weaponentity); + } + else if((fire & 1) && !actor.(weaponentity).hagar_load && !actor.(weaponentity).hagar_loadblock) // not while secondary is loaded or awaiting reset { if(weapon_prepareattack(thiswep, actor, weaponentity, false, 0)) W_Hagar_Attack_Auto(thiswep, actor, weaponentity, fire); } - else if((fire & 2) && !loadable_secondary && WEP_CVAR(WEP_HAGAR, secondary)) - { - if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(WEP_HAGAR, refire))) - { - W_Hagar_Attack2(thiswep, actor, weaponentity); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(WEP_HAGAR, refire), w_ready); - } - } + else if((fire & 2) && !loadable_secondary && WEP_CVAR(WEP_HAGAR, secondary)) + { + if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(WEP_HAGAR, refire))) + { + W_Hagar_Attack2(thiswep, actor, weaponentity); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(WEP_HAGAR, refire), w_ready); + } + } } + METHOD(Hagar, wr_gonethink, void(entity thiswep, entity actor, .entity weaponentity)) { - // we lost the weapon and want to prepare switching away - if(actor.(weaponentity).hagar_load) - { - actor.(weaponentity).state = WS_READY; - W_Hagar_Attack2_Load_Release(thiswep, actor, weaponentity); - } + // we lost the weapon and want to prepare switching away + if(actor.(weaponentity).hagar_load) + { + actor.(weaponentity).state = WS_READY; + W_Hagar_Attack2_Load_Release(thiswep, actor, weaponentity); + } } + METHOD(Hagar, wr_setup, void(entity thiswep, entity actor, .entity weaponentity)) { - actor.(weaponentity).hagar_loadblock = false; - if(actor.(weaponentity).hagar_load) - { - W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(WEP_HAGAR, ammo) * actor.(weaponentity).hagar_load * -1, weaponentity); // give back ammo if necessary - actor.(weaponentity).hagar_load = 0; - } + actor.(weaponentity).hagar_loadblock = false; + if(actor.(weaponentity).hagar_load) + { + W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(WEP_HAGAR, ammo) * actor.(weaponentity).hagar_load * -1, weaponentity); // give back ammo if necessary + actor.(weaponentity).hagar_load = 0; + } } + METHOD(Hagar, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity)) { - float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_PRI(WEP_HAGAR, ammo); - ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_PRI(WEP_HAGAR, ammo); - return ammo_amount; + float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_PRI(WEP_HAGAR, ammo); + ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_PRI(WEP_HAGAR, ammo); + return ammo_amount; } + METHOD(Hagar, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity)) { - float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_SEC(WEP_HAGAR, ammo); - ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_SEC(WEP_HAGAR, ammo); - return ammo_amount; + float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_SEC(WEP_HAGAR, ammo); + ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_SEC(WEP_HAGAR, ammo); + return ammo_amount; } + METHOD(Hagar, wr_resetplayer, void(entity thiswep, entity actor)) { - for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) - { - .entity weaponentity = weaponentities[slot]; - actor.(weaponentity).hagar_load = 0; - } + for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + { + .entity weaponentity = weaponentities[slot]; + actor.(weaponentity).hagar_load = 0; + } } + METHOD(Hagar, wr_playerdeath, void(entity thiswep, entity actor, .entity weaponentity)) { - // if we have any rockets loaded when we die, release them - if(actor.(weaponentity).hagar_load && WEP_CVAR_SEC(WEP_HAGAR, load_releasedeath)) - W_Hagar_Attack2_Load_Release(thiswep, actor, weaponentity); + // if we have any rockets loaded when we die, release them + if(actor.(weaponentity).hagar_load && WEP_CVAR_SEC(WEP_HAGAR, load_releasedeath)) + W_Hagar_Attack2_Load_Release(thiswep, actor, weaponentity); } + METHOD(Hagar, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) { - if(!actor.(weaponentity).hagar_load) // require releasing loaded rockets first - W_Reload(actor, weaponentity, min(WEP_CVAR_PRI(WEP_HAGAR, ammo), WEP_CVAR_SEC(WEP_HAGAR, ammo)), SND_RELOAD); + if(!actor.(weaponentity).hagar_load) // require releasing loaded rockets first + W_Reload(actor, weaponentity, min(WEP_CVAR_PRI(WEP_HAGAR, ammo), WEP_CVAR_SEC(WEP_HAGAR, ammo)), SND_RELOAD); } + METHOD(Hagar, wr_suicidemessage, Notification(entity thiswep)) { - return WEAPON_HAGAR_SUICIDE; + return WEAPON_HAGAR_SUICIDE; } + METHOD(Hagar, wr_killmessage, Notification(entity thiswep)) { - if(w_deathtype & HITTYPE_SECONDARY) - return WEAPON_HAGAR_MURDER_BURST; - else - return WEAPON_HAGAR_MURDER_SPRAY; + if(w_deathtype & HITTYPE_SECONDARY) + return WEAPON_HAGAR_MURDER_BURST; + else + return WEAPON_HAGAR_MURDER_SPRAY; } #endif @@ -472,17 +482,17 @@ METHOD(Hagar, wr_killmessage, Notification(entity thiswep)) METHOD(Hagar, wr_impacteffect, void(entity thiswep, entity actor)) { - vector org2 = w_org + w_backoff * 2; - pointparticles(EFFECT_HAGAR_EXPLODE, org2, '0 0 0', 1); - if(!w_issilent) - { - if(w_random<0.15) - sound(actor, CH_SHOTS, SND_HAGEXP1, VOL_BASE, ATTN_NORM); - else if(w_random<0.7) - sound(actor, CH_SHOTS, SND_HAGEXP2, VOL_BASE, ATTN_NORM); - else - sound(actor, CH_SHOTS, SND_HAGEXP3, VOL_BASE, ATTN_NORM); - } + vector org2 = w_org + w_backoff * 2; + pointparticles(EFFECT_HAGAR_EXPLODE, org2, '0 0 0', 1); + if(!w_issilent) + { + if(w_random<0.15) + sound(actor, CH_SHOTS, SND_HAGEXP1, VOL_BASE, ATTN_NORM); + else if(w_random<0.7) + sound(actor, CH_SHOTS, SND_HAGEXP2, VOL_BASE, ATTN_NORM); + else + sound(actor, CH_SHOTS, SND_HAGEXP3, VOL_BASE, ATTN_NORM); + } } #endif diff --git a/qcsrc/common/weapons/weapon/hagar.qh b/qcsrc/common/weapons/weapon/hagar.qh index 1d5ea28d6..42e5cbd3e 100644 --- a/qcsrc/common/weapons/weapon/hagar.qh +++ b/qcsrc/common/weapons/weapon/hagar.qh @@ -22,39 +22,39 @@ CLASS(Hagar, Weapon) #define X(BEGIN, P, END, class, prefix) \ BEGIN(class) \ P(class, prefix, ammo, float, BOTH) \ - P(class, prefix, damageforcescale, float, BOTH) \ - P(class, prefix, damage, float, BOTH) \ - P(class, prefix, edgedamage, float, BOTH) \ - P(class, prefix, force, float, BOTH) \ - P(class, prefix, health, float, BOTH) \ - P(class, prefix, lifetime, float, PRI) \ - P(class, prefix, lifetime_min, float, SEC) \ - P(class, prefix, lifetime_rand, float, SEC) \ - P(class, prefix, load, float, SEC) \ - P(class, prefix, load_abort, float, SEC) \ - P(class, prefix, load_animtime, float, SEC) \ - P(class, prefix, load_hold, float, SEC) \ - P(class, prefix, load_linkexplode, float, SEC) \ - P(class, prefix, load_max, float, SEC) \ - P(class, prefix, load_releasedeath, float, SEC) \ - P(class, prefix, load_speed, float, SEC) \ - P(class, prefix, load_spread, float, SEC) \ - P(class, prefix, load_spread_bias, float, SEC) \ - P(class, prefix, radius, float, BOTH) \ - P(class, prefix, refire, float, BOTH) \ - P(class, prefix, reload_ammo, float, NONE) \ - P(class, prefix, reload_time, float, NONE) \ - P(class, prefix, secondary, float, NONE) \ - P(class, prefix, speed, float, BOTH) \ - P(class, prefix, spread, float, BOTH) \ - P(class, prefix, switchdelay_drop, float, NONE) \ - P(class, prefix, switchdelay_raise, float, NONE) \ - P(class, prefix, weaponreplace, string,NONE) \ - P(class, prefix, weaponstartoverride, float, NONE) \ - P(class, prefix, weaponstart, float, NONE) \ - P(class, prefix, weaponthrowable, float, NONE) \ + P(class, prefix, damageforcescale, float, BOTH) \ + P(class, prefix, damage, float, BOTH) \ + P(class, prefix, edgedamage, float, BOTH) \ + P(class, prefix, force, float, BOTH) \ + P(class, prefix, health, float, BOTH) \ + P(class, prefix, lifetime, float, PRI) \ + P(class, prefix, lifetime_min, float, SEC) \ + P(class, prefix, lifetime_rand, float, SEC) \ + P(class, prefix, load, float, SEC) \ + P(class, prefix, load_abort, float, SEC) \ + P(class, prefix, load_animtime, float, SEC) \ + P(class, prefix, load_hold, float, SEC) \ + P(class, prefix, load_linkexplode, float, SEC) \ + P(class, prefix, load_max, float, SEC) \ + P(class, prefix, load_releasedeath, float, SEC) \ + P(class, prefix, load_speed, float, SEC) \ + P(class, prefix, load_spread, float, SEC) \ + P(class, prefix, load_spread_bias, float, SEC) \ + P(class, prefix, radius, float, BOTH) \ + P(class, prefix, refire, float, BOTH) \ + P(class, prefix, reload_ammo, float, NONE) \ + P(class, prefix, reload_time, float, NONE) \ + P(class, prefix, secondary, float, NONE) \ + P(class, prefix, speed, float, BOTH) \ + P(class, prefix, spread, float, BOTH) \ + P(class, prefix, switchdelay_drop, float, NONE) \ + P(class, prefix, switchdelay_raise, float, NONE) \ + P(class, prefix, weaponreplace, string,NONE) \ + P(class, prefix, weaponstartoverride, float, NONE) \ + P(class, prefix, weaponstart, float, NONE) \ + P(class, prefix, weaponthrowable, float, NONE) \ END() - W_PROPS(X, Hagar, hagar) + W_PROPS(X, Hagar, hagar) #undef X ENDCLASS(Hagar) diff --git a/qcsrc/common/weapons/weapon/hlac.qc b/qcsrc/common/weapons/weapon/hlac.qc index b62d9478e..81f06fc1c 100644 --- a/qcsrc/common/weapons/weapon/hlac.qc +++ b/qcsrc/common/weapons/weapon/hlac.qc @@ -12,8 +12,13 @@ void W_HLAC_Touch(entity this, entity toucher) isprimary = !(this.projectiledeathtype & HITTYPE_SECONDARY); - RadiusDamage(this, this.realowner, WEP_CVAR_BOTH(WEP_HLAC, isprimary, damage), WEP_CVAR_BOTH(WEP_HLAC, isprimary, edgedamage), WEP_CVAR_BOTH(WEP_HLAC, isprimary, radius), - NULL, NULL, WEP_CVAR_BOTH(WEP_HLAC, isprimary, force), this.projectiledeathtype, this.weaponentity_fld, toucher); + RadiusDamage(this, this.realowner, + WEP_CVAR_BOTH(WEP_HLAC, isprimary, damage), + WEP_CVAR_BOTH(WEP_HLAC, isprimary, edgedamage), + WEP_CVAR_BOTH(WEP_HLAC, isprimary, radius), + NULL, NULL, + WEP_CVAR_BOTH(WEP_HLAC, isprimary, force), + this.projectiledeathtype, this.weaponentity_fld, toucher); delete(this); } @@ -153,54 +158,60 @@ void W_HLAC_Attack_Frame(Weapon thiswep, entity actor, .entity weaponentity, int METHOD(HLAC, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { - PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, WEP_CVAR_PRI(WEP_HLAC, speed), 0, WEP_CVAR_PRI(WEP_HLAC, lifetime), false, true); + PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, WEP_CVAR_PRI(WEP_HLAC, speed), 0, WEP_CVAR_PRI(WEP_HLAC, lifetime), false, true); } + METHOD(HLAC, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) { - if(autocvar_g_balance_hlac_reload_ammo && actor.(weaponentity).clip_load < min(WEP_CVAR_PRI(WEP_HLAC, ammo), WEP_CVAR_SEC(WEP_HLAC, ammo))) { // forced reload - thiswep.wr_reload(thiswep, actor, weaponentity); - } else if(fire & 1) - { - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(WEP_HLAC, refire))) - { - actor.(weaponentity).misc_bulletcounter = 0; - W_HLAC_Attack(thiswep, actor, weaponentity); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(WEP_HLAC, refire), W_HLAC_Attack_Frame); - } - } - - else if((fire & 2) && WEP_CVAR(WEP_HLAC, secondary)) - { - if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(WEP_HLAC, refire))) - { - W_HLAC_Attack2(thiswep, actor, weaponentity); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(WEP_HLAC, animtime), w_ready); - } - } + if(autocvar_g_balance_hlac_reload_ammo && actor.(weaponentity).clip_load < min(WEP_CVAR_PRI(WEP_HLAC, ammo), WEP_CVAR_SEC(WEP_HLAC, ammo))) { // forced reload + thiswep.wr_reload(thiswep, actor, weaponentity); + } else if(fire & 1) + { + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(WEP_HLAC, refire))) + { + actor.(weaponentity).misc_bulletcounter = 0; + W_HLAC_Attack(thiswep, actor, weaponentity); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(WEP_HLAC, refire), W_HLAC_Attack_Frame); + } + } + + else if((fire & 2) && WEP_CVAR(WEP_HLAC, secondary)) + { + if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(WEP_HLAC, refire))) + { + W_HLAC_Attack2(thiswep, actor, weaponentity); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(WEP_HLAC, animtime), w_ready); + } + } } + METHOD(HLAC, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity)) { - float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_PRI(WEP_HLAC, ammo); - ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_PRI(WEP_HLAC, ammo); - return ammo_amount; + float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_PRI(WEP_HLAC, ammo); + ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_PRI(WEP_HLAC, ammo); + return ammo_amount; } + METHOD(HLAC, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity)) { - float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_SEC(WEP_HLAC, ammo); - ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_SEC(WEP_HLAC, ammo); - return ammo_amount; + float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_SEC(WEP_HLAC, ammo); + ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_SEC(WEP_HLAC, ammo); + return ammo_amount; } + METHOD(HLAC, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) { - W_Reload(actor, weaponentity, min(WEP_CVAR_PRI(WEP_HLAC, ammo), WEP_CVAR_SEC(WEP_HLAC, ammo)), SND_RELOAD); + W_Reload(actor, weaponentity, min(WEP_CVAR_PRI(WEP_HLAC, ammo), WEP_CVAR_SEC(WEP_HLAC, ammo)), SND_RELOAD); } + METHOD(HLAC, wr_suicidemessage, Notification(entity thiswep)) { - return WEAPON_HLAC_SUICIDE; + return WEAPON_HLAC_SUICIDE; } + METHOD(HLAC, wr_killmessage, Notification(entity thiswep)) { - return WEAPON_HLAC_MURDER; + return WEAPON_HLAC_MURDER; } #endif @@ -208,10 +219,10 @@ METHOD(HLAC, wr_killmessage, Notification(entity thiswep)) METHOD(HLAC, wr_impacteffect, void(entity thiswep, entity actor)) { - vector org2 = w_org + w_backoff * 2; - pointparticles(EFFECT_BLASTER_IMPACT, org2, w_backoff * 1000, 1); - if(!w_issilent) - sound(actor, CH_SHOTS, SND_LASERIMPACT, VOL_BASE, ATTN_NORM); + vector org2 = w_org + w_backoff * 2; + pointparticles(EFFECT_BLASTER_IMPACT, org2, w_backoff * 1000, 1); + if(!w_issilent) + sound(actor, CH_SHOTS, SND_LASERIMPACT, VOL_BASE, ATTN_NORM); } #endif diff --git a/qcsrc/common/weapons/weapon/hlac.qh b/qcsrc/common/weapons/weapon/hlac.qh index 2d7e655d6..77cc7046f 100644 --- a/qcsrc/common/weapons/weapon/hlac.qh +++ b/qcsrc/common/weapons/weapon/hlac.qh @@ -46,7 +46,7 @@ CLASS(HLAC, Weapon) P(class, prefix, weaponstart, float, NONE) \ P(class, prefix, weaponthrowable, float, NONE) \ END() - W_PROPS(X, HLAC, hlac) + W_PROPS(X, HLAC, hlac) #undef X ENDCLASS(HLAC) diff --git a/qcsrc/common/weapons/weapon/hook.qc b/qcsrc/common/weapons/weapon/hook.qc index e383760d3..d8174d3bd 100644 --- a/qcsrc/common/weapons/weapon/hook.qc +++ b/qcsrc/common/weapons/weapon/hook.qc @@ -114,128 +114,136 @@ void W_Hook_Attack2(Weapon thiswep, entity actor, .entity weaponentity) METHOD(Hook, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) { - if (fire & 1) { - if(!actor.(weaponentity).hook) - if(!(actor.(weaponentity).hook_state & HOOK_WAITING_FOR_RELEASE)) - if(time > actor.(weaponentity).hook_refire) - if(weapon_prepareattack(thiswep, actor, weaponentity, false, -1)) - { - W_DecreaseAmmo(thiswep, actor, thiswep.ammo_factor * WEP_CVAR_PRI(WEP_HOOK, ammo), weaponentity); - actor.(weaponentity).hook_state |= HOOK_FIRING; - actor.(weaponentity).hook_state |= HOOK_WAITING_FOR_RELEASE; - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(WEP_HOOK, animtime), w_ready); - } - } else { - actor.(weaponentity).hook_state |= HOOK_REMOVING; - actor.(weaponentity).hook_state &= ~HOOK_WAITING_FOR_RELEASE; - } - - if(fire & 2) - { - if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(WEP_HOOK, refire))) - { - W_Hook_Attack2(thiswep, actor, weaponentity); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(WEP_HOOK, animtime), w_ready); - } - } - - if(actor.(weaponentity).hook) - { - // if hooked, no bombs, and increase the timer - actor.(weaponentity).hook_refire = max(actor.(weaponentity).hook_refire, time + WEP_CVAR_PRI(WEP_HOOK, refire) * W_WeaponRateFactor(actor)); - - // hook also inhibits health regeneration, but only for 1 second - if(!(actor.items & IT_UNLIMITED_AMMO)) - actor.pauseregen_finished = max(actor.pauseregen_finished, time + autocvar_g_balance_pause_fuel_regen); - } - - if(actor.(weaponentity).hook && actor.(weaponentity).hook.state == 1) - { - float hooked_time_max = WEP_CVAR_PRI(WEP_HOOK, hooked_time_max); - if(hooked_time_max > 0) - { - if( time > actor.(weaponentity).hook_time_hooked + hooked_time_max ) - actor.(weaponentity).hook_state |= HOOK_REMOVING; - } - - float hooked_fuel = thiswep.ammo_factor * WEP_CVAR_PRI(WEP_HOOK, hooked_ammo); - if(hooked_fuel > 0) - { - if( time > actor.(weaponentity).hook_time_fueldecrease ) - { - if(!(actor.items & IT_UNLIMITED_AMMO)) - { - if( GetResource(actor, RES_FUEL) >= (time - actor.(weaponentity).hook_time_fueldecrease) * hooked_fuel ) - { - W_DecreaseAmmo(thiswep, actor, (time - actor.(weaponentity).hook_time_fueldecrease) * hooked_fuel, weaponentity); - actor.(weaponentity).hook_time_fueldecrease = time; - // decrease next frame again - } - else - { - SetResource(actor, RES_FUEL, 0); - actor.(weaponentity).hook_state |= HOOK_REMOVING; - if(actor.(weaponentity).m_weapon != WEP_Null) // offhand - W_SwitchWeapon_Force(actor, w_getbestweapon(actor, weaponentity), weaponentity); - } - } - } - } - } - else - { - actor.(weaponentity).hook_time_hooked = time; - actor.(weaponentity).hook_time_fueldecrease = time + WEP_CVAR_PRI(WEP_HOOK, hooked_time_free); - } - - actor.(weaponentity).hook_state = BITSET(actor.(weaponentity).hook_state, HOOK_PULLING, (!PHYS_INPUT_BUTTON_CROUCH(actor) || !autocvar_g_balance_grapplehook_crouchslide)); - - if (actor.(weaponentity).hook_state & HOOK_FIRING) - { - if (actor.(weaponentity).hook) - RemoveHook(actor.(weaponentity).hook); - FireGrapplingHook(actor, weaponentity); - actor.(weaponentity).hook_state &= ~HOOK_FIRING; - actor.(weaponentity).hook_refire = max(actor.(weaponentity).hook_refire, time + autocvar_g_balance_grapplehook_refire * W_WeaponRateFactor(actor)); - } - else if (actor.(weaponentity).hook_state & HOOK_REMOVING) - { - if (actor.(weaponentity).hook) - RemoveHook(actor.(weaponentity).hook); - actor.(weaponentity).hook_state &= ~HOOK_REMOVING; - } + if (fire & 1) + { + if(!actor.(weaponentity).hook) + if(!(actor.(weaponentity).hook_state & HOOK_WAITING_FOR_RELEASE)) + if(time > actor.(weaponentity).hook_refire) + if(weapon_prepareattack(thiswep, actor, weaponentity, false, -1)) + { + W_DecreaseAmmo(thiswep, actor, thiswep.ammo_factor * WEP_CVAR_PRI(WEP_HOOK, ammo), weaponentity); + actor.(weaponentity).hook_state |= HOOK_FIRING; + actor.(weaponentity).hook_state |= HOOK_WAITING_FOR_RELEASE; + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(WEP_HOOK, animtime), w_ready); + } + } + else + { + actor.(weaponentity).hook_state |= HOOK_REMOVING; + actor.(weaponentity).hook_state &= ~HOOK_WAITING_FOR_RELEASE; + } + + if(fire & 2) + { + if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(WEP_HOOK, refire))) + { + W_Hook_Attack2(thiswep, actor, weaponentity); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(WEP_HOOK, animtime), w_ready); + } + } + + if(actor.(weaponentity).hook) + { + // if hooked, no bombs, and increase the timer + actor.(weaponentity).hook_refire = max(actor.(weaponentity).hook_refire, time + WEP_CVAR_PRI(WEP_HOOK, refire) * W_WeaponRateFactor(actor)); + + // hook also inhibits health regeneration, but only for 1 second + if(!(actor.items & IT_UNLIMITED_AMMO)) + actor.pauseregen_finished = max(actor.pauseregen_finished, time + autocvar_g_balance_pause_fuel_regen); + } + + if(actor.(weaponentity).hook && actor.(weaponentity).hook.state == 1) + { + float hooked_time_max = WEP_CVAR_PRI(WEP_HOOK, hooked_time_max); + if(hooked_time_max > 0) + { + if(time > actor.(weaponentity).hook_time_hooked + hooked_time_max) + actor.(weaponentity).hook_state |= HOOK_REMOVING; + } + + float hooked_fuel = thiswep.ammo_factor * WEP_CVAR_PRI(WEP_HOOK, hooked_ammo); + if(hooked_fuel > 0) + { + if(time > actor.(weaponentity).hook_time_fueldecrease) + { + if(!(actor.items & IT_UNLIMITED_AMMO)) + { + if(GetResource(actor, RES_FUEL) >= (time - actor.(weaponentity).hook_time_fueldecrease) * hooked_fuel) + { + W_DecreaseAmmo(thiswep, actor, (time - actor.(weaponentity).hook_time_fueldecrease) * hooked_fuel, weaponentity); + actor.(weaponentity).hook_time_fueldecrease = time; + // decrease next frame again + } + else + { + SetResource(actor, RES_FUEL, 0); + actor.(weaponentity).hook_state |= HOOK_REMOVING; + if(actor.(weaponentity).m_weapon != WEP_Null) // offhand + W_SwitchWeapon_Force(actor, w_getbestweapon(actor, weaponentity), weaponentity); + } + } + } + } + } + else + { + actor.(weaponentity).hook_time_hooked = time; + actor.(weaponentity).hook_time_fueldecrease = time + WEP_CVAR_PRI(WEP_HOOK, hooked_time_free); + } + + actor.(weaponentity).hook_state = BITSET(actor.(weaponentity).hook_state, HOOK_PULLING, (!PHYS_INPUT_BUTTON_CROUCH(actor) || !autocvar_g_balance_grapplehook_crouchslide)); + + if (actor.(weaponentity).hook_state & HOOK_FIRING) + { + if (actor.(weaponentity).hook) + RemoveHook(actor.(weaponentity).hook); + FireGrapplingHook(actor, weaponentity); + actor.(weaponentity).hook_state &= ~HOOK_FIRING; + actor.(weaponentity).hook_refire = max(actor.(weaponentity).hook_refire, time + autocvar_g_balance_grapplehook_refire * W_WeaponRateFactor(actor)); + } + else if (actor.(weaponentity).hook_state & HOOK_REMOVING) + { + if (actor.(weaponentity).hook) + RemoveHook(actor.(weaponentity).hook); + actor.(weaponentity).hook_state &= ~HOOK_REMOVING; + } } + METHOD(Hook, wr_setup, void(entity thiswep, entity actor, .entity weaponentity)) { actor.(weaponentity).hook_state &= ~HOOK_WAITING_FOR_RELEASE; } + METHOD(Hook, wr_checkammo1, bool(Hook thiswep, entity actor, .entity weaponentity)) { - if (!thiswep.ammo_factor) return true; + if (!thiswep.ammo_factor) return true; - if(actor.(weaponentity).hook) - return GetResource(actor, RES_FUEL) > 0; + if(actor.(weaponentity).hook) + return GetResource(actor, RES_FUEL) > 0; - return GetResource(actor, RES_FUEL) >= WEP_CVAR_PRI(WEP_HOOK, ammo); + return GetResource(actor, RES_FUEL) >= WEP_CVAR_PRI(WEP_HOOK, ammo); } + METHOD(Hook, wr_checkammo2, bool(Hook thiswep, entity actor, .entity weaponentity)) { - // infinite ammo for now - return true; // actor.ammo_cells >= WEP_CVAR_SEC(WEP_HOOK, ammo); // WEAPONTODO: see above + // infinite ammo for now + return true; // actor.ammo_cells >= WEP_CVAR_SEC(WEP_HOOK, ammo); // WEAPONTODO: see above } + METHOD(Hook, wr_resetplayer, void(entity thiswep, entity actor)) { - RemoveGrapplingHooks(actor); - for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) - { - .entity weaponentity = weaponentities[slot]; - actor.(weaponentity).hook_time = 0; - actor.(weaponentity).hook_refire = time; - } + RemoveGrapplingHooks(actor); + for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + { + .entity weaponentity = weaponentities[slot]; + actor.(weaponentity).hook_time = 0; + actor.(weaponentity).hook_refire = time; + } } + METHOD(Hook, wr_killmessage, Notification(entity thiswep)) { - return WEAPON_HOOK_MURDER; + return WEAPON_HOOK_MURDER; } #endif @@ -243,11 +251,11 @@ METHOD(Hook, wr_killmessage, Notification(entity thiswep)) METHOD(Hook, wr_impacteffect, void(entity thiswep, entity actor)) { - // the hook bomb uses a negative w_backoff factor because it explodes slightly below the floor, unlike other projectiles - vector org2 = w_org + w_backoff * -2; - pointparticles(EFFECT_HOOK_EXPLODE, org2, '0 0 0', 1); - if(!w_issilent) - sound(actor, CH_SHOTS, SND_HOOKBOMB_IMPACT, VOL_BASE, ATTN_NORM); + // the hook bomb uses a negative w_backoff factor because it explodes slightly below the floor, unlike other projectiles + vector org2 = w_org + w_backoff * -2; + pointparticles(EFFECT_HOOK_EXPLODE, org2, '0 0 0', 1); + if(!w_issilent) + sound(actor, CH_SHOTS, SND_HOOKBOMB_IMPACT, VOL_BASE, ATTN_NORM); } #endif diff --git a/qcsrc/common/weapons/weapon/hook.qh b/qcsrc/common/weapons/weapon/hook.qh index 0bb7b84e1..538351835 100644 --- a/qcsrc/common/weapons/weapon/hook.qh +++ b/qcsrc/common/weapons/weapon/hook.qh @@ -39,14 +39,14 @@ CLASS(Hook, Weapon) P(class, prefix, radius, float, SEC) \ P(class, prefix, refire, float, BOTH) \ P(class, prefix, speed, float, SEC) \ - P(class, prefix, switchdelay_drop, float, NONE) \ + P(class, prefix, switchdelay_drop, float, NONE) \ P(class, prefix, switchdelay_raise, float, NONE) \ - P(class, prefix, weaponreplace, string, NONE) \ - P(class, prefix, weaponstartoverride, float, NONE) \ - P(class, prefix, weaponstart, float, NONE) \ - P(class, prefix, weaponthrowable, float, NONE) \ + P(class, prefix, weaponreplace, string, NONE) \ + P(class, prefix, weaponstartoverride, float, NONE) \ + P(class, prefix, weaponstart, float, NONE) \ + P(class, prefix, weaponthrowable, float, NONE) \ END() - W_PROPS(X, Hook, hook) + W_PROPS(X, Hook, hook) #undef X ENDCLASS(Hook) @@ -56,12 +56,12 @@ SPAWNFUNC_WEAPON(weapon_hook, WEP_HOOK) CLASS(OffhandHook, OffhandWeapon) #ifdef SVQC - METHOD(OffhandHook, offhand_think, void(OffhandHook this, entity actor, bool key_pressed)) - { - Weapon wep = WEP_HOOK; - .entity weaponentity = weaponentities[1]; - wep.wr_think(wep, actor, weaponentity, key_pressed ? 1 : 0); - } + METHOD(OffhandHook, offhand_think, void(OffhandHook this, entity actor, bool key_pressed)) + { + Weapon wep = WEP_HOOK; + .entity weaponentity = weaponentities[1]; + wep.wr_think(wep, actor, weaponentity, key_pressed ? 1 : 0); + } #endif ENDCLASS(OffhandHook) OffhandHook OFFHAND_HOOK; diff --git a/qcsrc/common/weapons/weapon/machinegun.qc b/qcsrc/common/weapons/weapon/machinegun.qc index bb68bdece..db979d61a 100644 --- a/qcsrc/common/weapons/weapon/machinegun.qc +++ b/qcsrc/common/weapons/weapon/machinegun.qc @@ -163,136 +163,145 @@ void W_MachineGun_Attack_Burst(Weapon thiswep, entity actor, .entity weaponentit METHOD(MachineGun, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { - if(vdist(actor.origin - actor.enemy.origin, <, 3000 - bound(0, skill, 10) * 200)) - PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, 1000000, 0, 0.001, false, true); - else - PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, weaponentity, 1000000, 0, 0.001, false, true); + if(vdist(actor.origin - actor.enemy.origin, <, 3000 - bound(0, skill, 10) * 200)) + PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, 1000000, 0, 0.001, false, true); + else + PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, weaponentity, 1000000, 0, 0.001, false, true); } + METHOD(MachineGun, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) { - // forced reload - wait until the bulletcounter is 0 so a burst loop can finish - if(WEP_CVAR(WEP_MACHINEGUN, reload_ammo) - && actor.(weaponentity).clip_load < min(max(WEP_CVAR(WEP_MACHINEGUN, sustained_ammo), WEP_CVAR(WEP_MACHINEGUN, first_ammo)), WEP_CVAR(WEP_MACHINEGUN, burst_ammo)) - && actor.(weaponentity).misc_bulletcounter >= 0) - { - thiswep.wr_reload(thiswep, actor, weaponentity); - } - else if(WEP_CVAR(WEP_MACHINEGUN, mode) == 1) - { - if(fire & 1) - if(weapon_prepareattack(thiswep, actor, weaponentity, false, 0)) - { - actor.(weaponentity).misc_bulletcounter = 0; - W_MachineGun_Attack_Auto(thiswep, actor, weaponentity, fire); - } - - // You can "shoot" more rounds than what's "used", and vice versa. - if(fire & 2) - if(weapon_prepareattack(thiswep, actor, weaponentity, true, 0)) - { - if(!thiswep.wr_checkammo2(thiswep, actor, weaponentity)) - if(!(actor.items & IT_UNLIMITED_AMMO)) - { - W_SwitchWeapon_Force(actor, w_getbestweapon(actor, weaponentity), weaponentity); - w_ready(thiswep, actor, weaponentity, fire); - return; - } - - float ammo_available; - if (WEP_CVAR(WEP_MACHINEGUN, reload_ammo) > 0) - { - ammo_available = actor.(weaponentity).clip_load; - } - else - { - ammo_available = GetResource(actor, thiswep.ammo_type); - } - - // We don't want to shoot 3 rounds if there's 2 left in the mag, so we'll use a fraction. - // Also keep the fraction <= 1 otherwise we'd mag dump in one burst. - float burst_fraction = min(1, ammo_available / WEP_CVAR(WEP_MACHINEGUN, burst_ammo)); - int to_shoot = floor(WEP_CVAR(WEP_MACHINEGUN, burst) * burst_fraction); - - // We also don't want to use 3 rounds if there's only 2 left. - int to_use = min(WEP_CVAR(WEP_MACHINEGUN, burst_ammo), ammo_available); - W_DecreaseAmmo(thiswep, actor, to_use, weaponentity); - - // Bursting counts up to 0 from a negative. - actor.(weaponentity).misc_bulletcounter = -to_shoot; - W_MachineGun_Attack_Burst(thiswep, actor, weaponentity, fire); - } - } - else - { - - if(fire & 1) - if(weapon_prepareattack(thiswep, actor, weaponentity, false, 0)) - { - actor.(weaponentity).misc_bulletcounter = 1; - W_MachineGun_Attack(thiswep, thiswep.m_id, actor, weaponentity); // sets attack_finished - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(WEP_MACHINEGUN, sustained_refire), W_MachineGun_Attack_Frame); - } - - if((fire & 2) && WEP_CVAR(WEP_MACHINEGUN, first)) - if(weapon_prepareattack(thiswep, actor, weaponentity, true, 0)) - { - actor.(weaponentity).misc_bulletcounter = 1; - W_MachineGun_Attack(thiswep, thiswep.m_id | HITTYPE_SECONDARY, actor, weaponentity); // sets attack_finished - weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR(WEP_MACHINEGUN, first_refire), w_ready); - } - } + // forced reload - wait until the bulletcounter is 0 so a burst loop can finish + if (WEP_CVAR(WEP_MACHINEGUN, reload_ammo) + && actor.(weaponentity).clip_load < min(max(WEP_CVAR(WEP_MACHINEGUN, sustained_ammo), WEP_CVAR(WEP_MACHINEGUN, first_ammo)), WEP_CVAR(WEP_MACHINEGUN, burst_ammo)) + && actor.(weaponentity).misc_bulletcounter >= 0) + { + thiswep.wr_reload(thiswep, actor, weaponentity); + } + else if(WEP_CVAR(WEP_MACHINEGUN, mode) == 1) + { + if(fire & 1) + if(weapon_prepareattack(thiswep, actor, weaponentity, false, 0)) + { + actor.(weaponentity).misc_bulletcounter = 0; + W_MachineGun_Attack_Auto(thiswep, actor, weaponentity, fire); + } + + // You can "shoot" more rounds than what's "used", and vice versa. + if(fire & 2) + if(weapon_prepareattack(thiswep, actor, weaponentity, true, 0)) + { + if(!thiswep.wr_checkammo2(thiswep, actor, weaponentity)) + if(!(actor.items & IT_UNLIMITED_AMMO)) + { + W_SwitchWeapon_Force(actor, w_getbestweapon(actor, weaponentity), weaponentity); + w_ready(thiswep, actor, weaponentity, fire); + return; + } + + float ammo_available; + if (WEP_CVAR(WEP_MACHINEGUN, reload_ammo) > 0) + { + ammo_available = actor.(weaponentity).clip_load; + } + else + { + ammo_available = GetResource(actor, thiswep.ammo_type); + } + + // We don't want to shoot 3 rounds if there's 2 left in the mag, so we'll use a fraction. + // Also keep the fraction <= 1 otherwise we'd mag dump in one burst. + float burst_fraction = min(1, ammo_available / WEP_CVAR(WEP_MACHINEGUN, burst_ammo)); + int to_shoot = floor(WEP_CVAR(WEP_MACHINEGUN, burst) * burst_fraction); + + // We also don't want to use 3 rounds if there's only 2 left. + int to_use = min(WEP_CVAR(WEP_MACHINEGUN, burst_ammo), ammo_available); + W_DecreaseAmmo(thiswep, actor, to_use, weaponentity); + + // Bursting counts up to 0 from a negative. + actor.(weaponentity).misc_bulletcounter = -to_shoot; + W_MachineGun_Attack_Burst(thiswep, actor, weaponentity, fire); + } + } + else + { + + if(fire & 1) + if(weapon_prepareattack(thiswep, actor, weaponentity, false, 0)) + { + actor.(weaponentity).misc_bulletcounter = 1; + W_MachineGun_Attack(thiswep, thiswep.m_id, actor, weaponentity); // sets attack_finished + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(WEP_MACHINEGUN, sustained_refire), W_MachineGun_Attack_Frame); + } + + if((fire & 2) && WEP_CVAR(WEP_MACHINEGUN, first)) + if(weapon_prepareattack(thiswep, actor, weaponentity, true, 0)) + { + actor.(weaponentity).misc_bulletcounter = 1; + W_MachineGun_Attack(thiswep, thiswep.m_id | HITTYPE_SECONDARY, actor, weaponentity); // sets attack_finished + weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR(WEP_MACHINEGUN, first_refire), w_ready); + } + } } + METHOD(MachineGun, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity)) { - float ammo_amount; - if(WEP_CVAR(WEP_MACHINEGUN, mode) == 1) - ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR(WEP_MACHINEGUN, sustained_ammo); - else - ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR(WEP_MACHINEGUN, first_ammo); - - if(WEP_CVAR(WEP_MACHINEGUN, reload_ammo)) - { - if(WEP_CVAR(WEP_MACHINEGUN, mode) == 1) - ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR(WEP_MACHINEGUN, sustained_ammo); - else - ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR(WEP_MACHINEGUN, first_ammo); - } - return ammo_amount; + float ammo_amount; + if(WEP_CVAR(WEP_MACHINEGUN, mode) == 1) + ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR(WEP_MACHINEGUN, sustained_ammo); + else + ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR(WEP_MACHINEGUN, first_ammo); + + if(WEP_CVAR(WEP_MACHINEGUN, reload_ammo)) + { + if(WEP_CVAR(WEP_MACHINEGUN, mode) == 1) + ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR(WEP_MACHINEGUN, sustained_ammo); + else + ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR(WEP_MACHINEGUN, first_ammo); + } + + return ammo_amount; } + METHOD(MachineGun, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity)) { - float ammo_amount; - float burst_ammo_per_shot = WEP_CVAR(WEP_MACHINEGUN, burst_ammo) / WEP_CVAR(WEP_MACHINEGUN, burst); - if(WEP_CVAR(WEP_MACHINEGUN, mode) == 1) - ammo_amount = GetResource(actor, thiswep.ammo_type) >= burst_ammo_per_shot; - else - ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR(WEP_MACHINEGUN, first_ammo); - - if(WEP_CVAR(WEP_MACHINEGUN, reload_ammo)) - { - if(WEP_CVAR(WEP_MACHINEGUN, mode) == 1) - ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= burst_ammo_per_shot; - else - ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR(WEP_MACHINEGUN, first_ammo); - } - return ammo_amount; + float ammo_amount; + float burst_ammo_per_shot = WEP_CVAR(WEP_MACHINEGUN, burst_ammo) / WEP_CVAR(WEP_MACHINEGUN, burst); + + if(WEP_CVAR(WEP_MACHINEGUN, mode) == 1) + ammo_amount = GetResource(actor, thiswep.ammo_type) >= burst_ammo_per_shot; + else + ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR(WEP_MACHINEGUN, first_ammo); + + if(WEP_CVAR(WEP_MACHINEGUN, reload_ammo)) + { + if(WEP_CVAR(WEP_MACHINEGUN, mode) == 1) + ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= burst_ammo_per_shot; + else + ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR(WEP_MACHINEGUN, first_ammo); + } + + return ammo_amount; } + METHOD(MachineGun, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) { if(actor.(weaponentity).misc_bulletcounter < 0) return; - W_Reload(actor, weaponentity, min(max(WEP_CVAR(WEP_MACHINEGUN, sustained_ammo), WEP_CVAR(WEP_MACHINEGUN, first_ammo)), WEP_CVAR(WEP_MACHINEGUN, burst_ammo)), SND_RELOAD); + W_Reload(actor, weaponentity, min(max(WEP_CVAR(WEP_MACHINEGUN, sustained_ammo), WEP_CVAR(WEP_MACHINEGUN, first_ammo)), WEP_CVAR(WEP_MACHINEGUN, burst_ammo)), SND_RELOAD); } + METHOD(MachineGun, wr_suicidemessage, Notification(entity thiswep)) { - return WEAPON_THINKING_WITH_PORTALS; + return WEAPON_THINKING_WITH_PORTALS; } + METHOD(MachineGun, wr_killmessage, Notification(entity thiswep)) { - if(w_deathtype & HITTYPE_SECONDARY) - return WEAPON_MACHINEGUN_MURDER_SNIPE; - else - return WEAPON_MACHINEGUN_MURDER_SPRAY; + if(w_deathtype & HITTYPE_SECONDARY) + return WEAPON_MACHINEGUN_MURDER_SNIPE; + else + return WEAPON_MACHINEGUN_MURDER_SPRAY; } #endif @@ -300,10 +309,10 @@ METHOD(MachineGun, wr_killmessage, Notification(entity thiswep)) METHOD(MachineGun, wr_impacteffect, void(entity thiswep, entity actor)) { - vector org2 = w_org + w_backoff * 2; - pointparticles(EFFECT_MACHINEGUN_IMPACT, org2, w_backoff * 1000, 1); - if(!w_issilent) - sound(actor, CH_SHOTS, SND_RIC_RANDOM(), VOL_BASE, ATTN_NORM); + vector org2 = w_org + w_backoff * 2; + pointparticles(EFFECT_MACHINEGUN_IMPACT, org2, w_backoff * 1000, 1); + if(!w_issilent) + sound(actor, CH_SHOTS, SND_RIC_RANDOM(), VOL_BASE, ATTN_NORM); } #endif diff --git a/qcsrc/common/weapons/weapon/machinegun.qh b/qcsrc/common/weapons/weapon/machinegun.qh index 450a12df9..cf6a17434 100644 --- a/qcsrc/common/weapons/weapon/machinegun.qh +++ b/qcsrc/common/weapons/weapon/machinegun.qh @@ -40,7 +40,7 @@ CLASS(MachineGun, Weapon) P(class, prefix, first_spread, float, NONE) \ P(class, prefix, mode, float, NONE) \ P(class, prefix, reload_ammo, float, NONE) \ - P(class, prefix, reload_time, float, NONE) \ + P(class, prefix, reload_time, float, NONE) \ P(class, prefix, solidpenetration, float, NONE) \ P(class, prefix, spread_add, float, NONE) \ P(class, prefix, spread_max, float, NONE) \ @@ -50,14 +50,14 @@ CLASS(MachineGun, Weapon) P(class, prefix, sustained_force, float, NONE) \ P(class, prefix, sustained_refire, float, NONE) \ P(class, prefix, sustained_spread, float, NONE) \ - P(class, prefix, switchdelay_drop, float, NONE) \ - P(class, prefix, switchdelay_raise, float, NONE) \ - P(class, prefix, weaponreplace, string,NONE) \ - P(class, prefix, weaponstartoverride, float, NONE) \ - P(class, prefix, weaponstart, float, NONE) \ - P(class, prefix, weaponthrowable, float, NONE) \ + P(class, prefix, switchdelay_drop, float, NONE) \ + P(class, prefix, switchdelay_raise, float, NONE) \ + P(class, prefix, weaponreplace, string,NONE) \ + P(class, prefix, weaponstartoverride, float, NONE) \ + P(class, prefix, weaponstart, float, NONE) \ + P(class, prefix, weaponthrowable, float, NONE) \ END() - W_PROPS(X, MachineGun, machinegun) + W_PROPS(X, MachineGun, machinegun) #undef X ENDCLASS(MachineGun) diff --git a/qcsrc/common/weapons/weapon/minelayer.qc b/qcsrc/common/weapons/weapon/minelayer.qc index 0131669bf..c272d4572 100644 --- a/qcsrc/common/weapons/weapon/minelayer.qc +++ b/qcsrc/common/weapons/weapon/minelayer.qc @@ -342,152 +342,159 @@ bool W_MineLayer_PlacedMines(entity this, .entity weaponentity, bool detonate) METHOD(MineLayer, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { - // aim and decide to fire if appropriate - int minecount = W_MineLayer_Count(actor, weaponentity); - if(minecount >= WEP_CVAR(WEP_MINE_LAYER, limit)) - PHYS_INPUT_BUTTON_ATCK(actor) = false; - else - PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, WEP_CVAR(WEP_MINE_LAYER, speed), 0, WEP_CVAR(WEP_MINE_LAYER, lifetime), false, false); - if(skill >= 2) // skill 0 and 1 bots won't detonate mines! - { - // decide whether to detonate mines - float edgedamage, coredamage, edgeradius, recipricoledgeradius; - float selfdamage, teamdamage, enemydamage; - edgedamage = WEP_CVAR(WEP_MINE_LAYER, edgedamage); - coredamage = WEP_CVAR(WEP_MINE_LAYER, damage); - edgeradius = WEP_CVAR(WEP_MINE_LAYER, radius); - recipricoledgeradius = 1 / edgeradius; - selfdamage = 0; - teamdamage = 0; - enemydamage = 0; - - IL_EACH(g_mines, it.realowner == actor, - { - entity mine = it; - IL_EACH(g_bot_targets, it.bot_attack, - { - float d = vlen(it.origin + (it.mins + it.maxs) * 0.5 - mine.origin); - d = bound(0, edgedamage + (coredamage - edgedamage) * sqrt(1 - d * recipricoledgeradius), 10000); - // count potential damage according to type of target - if(it == actor) - selfdamage = selfdamage + d; - else if(SAME_TEAM(it, actor)) - teamdamage = teamdamage + d; - else if(bot_shouldattack(actor, it)) - enemydamage = enemydamage + d; - }); - }); - - float desirabledamage; - desirabledamage = enemydamage; - if(StatusEffects_active(STATUSEFFECT_Shield, actor) && !StatusEffects_active(STATUSEFFECT_SpawnShield, actor)) - desirabledamage = desirabledamage - selfdamage * autocvar_g_balance_selfdamagepercent; - if(teamplay && actor.team) - desirabledamage = desirabledamage - teamdamage; - - makevectors(actor.v_angle); - IL_EACH(g_mines, it.realowner == actor, - { - if(skill > 9) // normal players only do this for the target they are tracking - { - entity mine = it; - IL_EACH(g_bot_targets, it.bot_attack, - { - if((v_forward * normalize(mine.origin - it.origin) < 0.1) - && desirabledamage > 0.1 * coredamage - ) PHYS_INPUT_BUTTON_ATCK2(actor) = true; - }); - } - else - { - //As the distance gets larger, a correct detonation gets near imposible - //Bots are assumed to use the mine spawnfunc_light to see if the mine gets near a player - if((v_forward * normalize(it.origin - actor.enemy.origin) < 0.1) - && IS_PLAYER(actor.enemy) - && (desirabledamage >= 0.1 * coredamage) - ) - { - float distance = bound(300, vlen(actor.origin - actor.enemy.origin), 30000); - if(random() / distance * 300 > frametime * bound(0, (10 - skill) * 0.2, 1)) - PHYS_INPUT_BUTTON_ATCK2(actor) = true; - } - } - }); - - // if we would be doing at X percent of the core damage, detonate it - // but don't fire a new shot at the same time! - if(desirabledamage >= 0.75 * coredamage) //this should do group damage in rare fortunate events - PHYS_INPUT_BUTTON_ATCK2(actor) = true; - if((skill > 6.5) && (selfdamage > GetResource(actor, RES_HEALTH))) - PHYS_INPUT_BUTTON_ATCK2(actor) = false; - //if(PHYS_INPUT_BUTTON_ATCK2(actor) == true) - // dprint(ftos(desirabledamage),"\n"); - if(PHYS_INPUT_BUTTON_ATCK2(actor)) PHYS_INPUT_BUTTON_ATCK(actor) = false; - } + // aim and decide to fire if appropriate + int minecount = W_MineLayer_Count(actor, weaponentity); + if(minecount >= WEP_CVAR(WEP_MINE_LAYER, limit)) + PHYS_INPUT_BUTTON_ATCK(actor) = false; + else + PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, WEP_CVAR(WEP_MINE_LAYER, speed), 0, WEP_CVAR(WEP_MINE_LAYER, lifetime), false, false); + if(skill >= 2) // skill 0 and 1 bots won't detonate mines! + { + // decide whether to detonate mines + float edgedamage, coredamage, edgeradius, recipricoledgeradius; + float selfdamage, teamdamage, enemydamage; + edgedamage = WEP_CVAR(WEP_MINE_LAYER, edgedamage); + coredamage = WEP_CVAR(WEP_MINE_LAYER, damage); + edgeradius = WEP_CVAR(WEP_MINE_LAYER, radius); + recipricoledgeradius = 1 / edgeradius; + selfdamage = 0; + teamdamage = 0; + enemydamage = 0; + + IL_EACH(g_mines, it.realowner == actor, + { + entity mine = it; + IL_EACH(g_bot_targets, it.bot_attack, + { + float d = vlen(it.origin + (it.mins + it.maxs) * 0.5 - mine.origin); + d = bound(0, edgedamage + (coredamage - edgedamage) * sqrt(1 - d * recipricoledgeradius), 10000); + // count potential damage according to type of target + if(it == actor) + selfdamage = selfdamage + d; + else if(SAME_TEAM(it, actor)) + teamdamage = teamdamage + d; + else if(bot_shouldattack(actor, it)) + enemydamage = enemydamage + d; + }); + }); + + float desirabledamage; + desirabledamage = enemydamage; + if(StatusEffects_active(STATUSEFFECT_Shield, actor) && !StatusEffects_active(STATUSEFFECT_SpawnShield, actor)) + desirabledamage = desirabledamage - selfdamage * autocvar_g_balance_selfdamagepercent; + if(teamplay && actor.team) + desirabledamage = desirabledamage - teamdamage; + + makevectors(actor.v_angle); + IL_EACH(g_mines, it.realowner == actor, + { + if(skill > 9) // normal players only do this for the target they are tracking + { + entity mine = it; + IL_EACH(g_bot_targets, it.bot_attack, + { + if((v_forward * normalize(mine.origin - it.origin) < 0.1) + && desirabledamage > 0.1 * coredamage + ) PHYS_INPUT_BUTTON_ATCK2(actor) = true; + }); + } + else + { + //As the distance gets larger, a correct detonation gets near imposible + //Bots are assumed to use the mine spawnfunc_light to see if the mine gets near a player + if((v_forward * normalize(it.origin - actor.enemy.origin) < 0.1) + && IS_PLAYER(actor.enemy) + && (desirabledamage >= 0.1 * coredamage) + ) + { + float distance = bound(300, vlen(actor.origin - actor.enemy.origin), 30000); + if(random() / distance * 300 > frametime * bound(0, (10 - skill) * 0.2, 1)) + PHYS_INPUT_BUTTON_ATCK2(actor) = true; + } + } + }); + + // if we would be doing at X percent of the core damage, detonate it + // but don't fire a new shot at the same time! + if(desirabledamage >= 0.75 * coredamage) //this should do group damage in rare fortunate events + PHYS_INPUT_BUTTON_ATCK2(actor) = true; + if((skill > 6.5) && (selfdamage > GetResource(actor, RES_HEALTH))) + PHYS_INPUT_BUTTON_ATCK2(actor) = false; + //if(PHYS_INPUT_BUTTON_ATCK2(actor) == true) + // dprint(ftos(desirabledamage),"\n"); + if(PHYS_INPUT_BUTTON_ATCK2(actor)) PHYS_INPUT_BUTTON_ATCK(actor) = false; + } } + METHOD(MineLayer, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) { actor.(weaponentity).minelayer_mines = W_MineLayer_Count(actor, weaponentity); - if(autocvar_g_balance_minelayer_reload_ammo && actor.(weaponentity).clip_load < WEP_CVAR(WEP_MINE_LAYER, ammo)) // forced reload - { - // not if we're holding the minelayer without enough ammo, but can detonate existing mines - if(!(W_MineLayer_PlacedMines(actor, weaponentity, false) && GetResource(actor, thiswep.ammo_type) < WEP_CVAR(WEP_MINE_LAYER, ammo))) { - thiswep.wr_reload(thiswep, actor, weaponentity); - } - } - else if(fire & 1) - { - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(WEP_MINE_LAYER, refire))) - { - W_MineLayer_Attack(thiswep, actor, weaponentity); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(WEP_MINE_LAYER, animtime), w_ready); - } - } - - if(fire & 2) - { - if(W_MineLayer_PlacedMines(actor, weaponentity, true)) - sound(actor, CH_WEAPON_B, SND_MINE_DET, VOL_BASE, ATTN_NORM); - } + if(autocvar_g_balance_minelayer_reload_ammo && actor.(weaponentity).clip_load < WEP_CVAR(WEP_MINE_LAYER, ammo)) // forced reload + { + // not if we're holding the minelayer without enough ammo, but can detonate existing mines + if(!(W_MineLayer_PlacedMines(actor, weaponentity, false) && GetResource(actor, thiswep.ammo_type) < WEP_CVAR(WEP_MINE_LAYER, ammo))) { + thiswep.wr_reload(thiswep, actor, weaponentity); + } + } + else if(fire & 1) + { + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(WEP_MINE_LAYER, refire))) + { + W_MineLayer_Attack(thiswep, actor, weaponentity); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(WEP_MINE_LAYER, animtime), w_ready); + } + } + + if(fire & 2) + { + if(W_MineLayer_PlacedMines(actor, weaponentity, true)) + sound(actor, CH_WEAPON_B, SND_MINE_DET, VOL_BASE, ATTN_NORM); + } } + METHOD(MineLayer, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity)) { - // actually do // don't switch while placing a mine - //if(ATTACK_FINISHED(actor, weaponentity) <= time || PS(actor).m_weapon != WEP_MINE_LAYER) - //{ - float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR(WEP_MINE_LAYER, ammo); - ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR(WEP_MINE_LAYER, ammo); - return ammo_amount; - //} - //return true; + // actually do // don't switch while placing a mine + //if(ATTACK_FINISHED(actor, weaponentity) <= time || PS(actor).m_weapon != WEP_MINE_LAYER) + //{ + float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR(WEP_MINE_LAYER, ammo); + ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR(WEP_MINE_LAYER, ammo); + return ammo_amount; + //} + //return true; } + METHOD(MineLayer, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity)) { - if(W_MineLayer_PlacedMines(actor, weaponentity, false)) - return true; - else - return false; + if(W_MineLayer_PlacedMines(actor, weaponentity, false)) + return true; + else + return false; } + METHOD(MineLayer, wr_resetplayer, void(entity thiswep, entity actor)) { - for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) - { - .entity weaponentity = weaponentities[slot]; - actor.(weaponentity).minelayer_mines = 0; - } + for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + { + .entity weaponentity = weaponentities[slot]; + actor.(weaponentity).minelayer_mines = 0; + } } + METHOD(MineLayer, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) { - W_Reload(actor, weaponentity, WEP_CVAR(WEP_MINE_LAYER, ammo), SND_RELOAD); + W_Reload(actor, weaponentity, WEP_CVAR(WEP_MINE_LAYER, ammo), SND_RELOAD); } + METHOD(MineLayer, wr_suicidemessage, Notification(entity thiswep)) { - return WEAPON_MINELAYER_SUICIDE; + return WEAPON_MINELAYER_SUICIDE; } + METHOD(MineLayer, wr_killmessage, Notification(entity thiswep)) { - return WEAPON_MINELAYER_MURDER; + return WEAPON_MINELAYER_MURDER; } #endif @@ -495,10 +502,10 @@ METHOD(MineLayer, wr_killmessage, Notification(entity thiswep)) METHOD(MineLayer, wr_impacteffect, void(entity thiswep, entity actor)) { - vector org2 = w_org + w_backoff * 2; - pointparticles(EFFECT_ROCKET_EXPLODE, org2, '0 0 0', 1); - if(!w_issilent) - sound(actor, CH_SHOTS, SND_MINE_EXP, VOL_BASE, ATTN_NORM); + vector org2 = w_org + w_backoff * 2; + pointparticles(EFFECT_ROCKET_EXPLODE, org2, '0 0 0', 1); + if(!w_issilent) + sound(actor, CH_SHOTS, SND_MINE_EXP, VOL_BASE, ATTN_NORM); } #endif diff --git a/qcsrc/common/weapons/weapon/minelayer.qh b/qcsrc/common/weapons/weapon/minelayer.qh index 1f503f7ff..11618fc65 100644 --- a/qcsrc/common/weapons/weapon/minelayer.qh +++ b/qcsrc/common/weapons/weapon/minelayer.qh @@ -37,21 +37,21 @@ CLASS(MineLayer, Weapon) P(class, prefix, radius, float, NONE) \ P(class, prefix, refire, float, NONE) \ P(class, prefix, reload_ammo, float, NONE) \ - P(class, prefix, reload_time, float, NONE) \ + P(class, prefix, reload_time, float, NONE) \ P(class, prefix, remote_damage, float, NONE) \ P(class, prefix, remote_edgedamage, float, NONE) \ P(class, prefix, remote_force, float, NONE) \ P(class, prefix, remote_radius, float, NONE) \ P(class, prefix, speed, float, NONE) \ - P(class, prefix, switchdelay_drop, float, NONE) \ - P(class, prefix, switchdelay_raise, float, NONE) \ + P(class, prefix, switchdelay_drop, float, NONE) \ + P(class, prefix, switchdelay_raise, float, NONE) \ P(class, prefix, time, float, NONE) \ - P(class, prefix, weaponreplace, string, NONE) \ - P(class, prefix, weaponstartoverride, float, NONE) \ - P(class, prefix, weaponstart, float, NONE) \ - P(class, prefix, weaponthrowable, float, NONE) \ + P(class, prefix, weaponreplace, string, NONE) \ + P(class, prefix, weaponstartoverride, float, NONE) \ + P(class, prefix, weaponstart, float, NONE) \ + P(class, prefix, weaponthrowable, float, NONE) \ END() - W_PROPS(X, MineLayer, minelayer) + W_PROPS(X, MineLayer, minelayer) #undef X ENDCLASS(MineLayer) REGISTER_WEAPON(MINE_LAYER, NEW(MineLayer)); diff --git a/qcsrc/common/weapons/weapon/mortar.qc b/qcsrc/common/weapons/weapon/mortar.qc index 986acd03d..180161795 100644 --- a/qcsrc/common/weapons/weapon/mortar.qc +++ b/qcsrc/common/weapons/weapon/mortar.qc @@ -252,105 +252,112 @@ void W_Mortar_Attack2(Weapon thiswep, entity actor, .entity weaponentity) METHOD(Mortar, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { - PHYS_INPUT_BUTTON_ATCK(actor) = false; - PHYS_INPUT_BUTTON_ATCK2(actor) = false; - if(actor.bot_secondary_grenademooth == 0) // WEAPONTODO: merge this into using WEP_CVAR_BOTH - { - if(bot_aim(actor, weaponentity, WEP_CVAR_PRI(WEP_MORTAR, speed), WEP_CVAR_PRI(WEP_MORTAR, speed_up), WEP_CVAR_PRI(WEP_MORTAR, lifetime), true, true)) - { - PHYS_INPUT_BUTTON_ATCK(actor) = true; - if(random() < 0.01) actor.bot_secondary_grenademooth = 1; - } - } - else - { - if(bot_aim(actor, weaponentity, WEP_CVAR_SEC(WEP_MORTAR, speed), WEP_CVAR_SEC(WEP_MORTAR, speed_up), WEP_CVAR_SEC(WEP_MORTAR, lifetime), true, true)) - { - PHYS_INPUT_BUTTON_ATCK2(actor) = true; - if(random() < 0.02) actor.bot_secondary_grenademooth = 0; - } - } + PHYS_INPUT_BUTTON_ATCK(actor) = false; + PHYS_INPUT_BUTTON_ATCK2(actor) = false; + if(actor.bot_secondary_grenademooth == 0) // WEAPONTODO: merge this into using WEP_CVAR_BOTH + { + if(bot_aim(actor, weaponentity, WEP_CVAR_PRI(WEP_MORTAR, speed), WEP_CVAR_PRI(WEP_MORTAR, speed_up), WEP_CVAR_PRI(WEP_MORTAR, lifetime), true, true)) + { + PHYS_INPUT_BUTTON_ATCK(actor) = true; + if(random() < 0.01) actor.bot_secondary_grenademooth = 1; + } + } + else + { + if(bot_aim(actor, weaponentity, WEP_CVAR_SEC(WEP_MORTAR, speed), WEP_CVAR_SEC(WEP_MORTAR, speed_up), WEP_CVAR_SEC(WEP_MORTAR, lifetime), true, true)) + { + PHYS_INPUT_BUTTON_ATCK2(actor) = true; + if(random() < 0.02) actor.bot_secondary_grenademooth = 0; + } + } } + /*case WR_CALCINFO: { - wepinfo_pri_refire = max3(sys_frametime, WEP_CVAR_PRI(WEP_MORTAR, refire), WEP_CVAR_PRI(WEP_MORTAR, animtime)); - wepinfo_pri_dps = (WEP_CVAR_PRI(WEP_MORTAR, damage) * (1 / wepinfo_pri_refire)); - wepinfo_pri_speed = (1 / max(1, (10000 / max(1, WEP_CVAR_PRI(WEP_MORTAR, speed))))); + wepinfo_pri_refire = max3(sys_frametime, WEP_CVAR_PRI(WEP_MORTAR, refire), WEP_CVAR_PRI(WEP_MORTAR, animtime)); + wepinfo_pri_dps = (WEP_CVAR_PRI(WEP_MORTAR, damage) * (1 / wepinfo_pri_refire)); + wepinfo_pri_speed = (1 / max(1, (10000 / max(1, WEP_CVAR_PRI(WEP_MORTAR, speed))))); + + // for the range calculation, closer to 1 is better + wepinfo_pri_range_max = 2000 * wepinfo_pri_speed; + wepinfo_pri_range = wepinfo_pri_speed * WEP_CVAR_PRI(WEP_MORTAR, - // for the range calculation, closer to 1 is better - wepinfo_pri_range_max = 2000 * wepinfo_pri_speed; - wepinfo_pri_range = wepinfo_pri_speed * WEP_CVAR_PRI(WEP_MORTAR, + wepinfo_sec_refire = max3(sys_frametime, WEP_CVAR_SEC(WEP_MORTAR, refire), WEP_CVAR_SEC(WEP_MORTAR, animtime)); + wepinfo_sec_dps = (WEP_CVAR_SEC(WEP_MORTAR, damage) * (1 / wepinfo_sec_refire)); - wepinfo_sec_refire = max3(sys_frametime, WEP_CVAR_SEC(WEP_MORTAR, refire), WEP_CVAR_SEC(WEP_MORTAR, animtime)); - wepinfo_sec_dps = (WEP_CVAR_SEC(WEP_MORTAR, damage) * (1 / wepinfo_sec_refire)); + wepinfo_sec_dps = (WEP_CVAR_SEC(WEP_MORTAR, damage) * (1 / max3(sys_frametime, WEP_CVAR_SEC(WEP_MORTAR, refire), WEP_CVAR_SEC(WEP_MORTAR, animtime)))); + wepinfo_ter_dps = 0; + */ - wepinfo_sec_dps = (WEP_CVAR_SEC(WEP_MORTAR, damage) * (1 / max3(sys_frametime, WEP_CVAR_SEC(WEP_MORTAR, refire), WEP_CVAR_SEC(WEP_MORTAR, animtime)))); - wepinfo_ter_dps = 0; - */ METHOD(Mortar, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) { - if(autocvar_g_balance_mortar_reload_ammo && actor.(weaponentity).clip_load < min(WEP_CVAR_PRI(WEP_MORTAR, ammo), WEP_CVAR_SEC(WEP_MORTAR, ammo))) { // forced reload - thiswep.wr_reload(thiswep, actor, weaponentity); - } else if(fire & 1) - { - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(WEP_MORTAR, refire))) - { - W_Mortar_Attack(thiswep, actor, weaponentity); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(WEP_MORTAR, animtime), w_ready); - } - } - else if(fire & 2) - { - if(WEP_CVAR_SEC(WEP_MORTAR, remote_detonateprimary)) - { - bool nadefound = false; - IL_EACH(g_projectiles, it.realowner == actor && it.classname == "grenade", - { - if(!it.gl_detonate_later) - { - it.gl_detonate_later = true; - nadefound = true; - } - }); - if(nadefound) - sound(actor, CH_WEAPON_B, SND_ROCKET_DET, VOL_BASE, ATTN_NORM); - } - else if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(WEP_MORTAR, refire))) - { - W_Mortar_Attack2(thiswep, actor, weaponentity); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(WEP_MORTAR, animtime), w_ready); - } - } + if(autocvar_g_balance_mortar_reload_ammo && actor.(weaponentity).clip_load < min(WEP_CVAR_PRI(WEP_MORTAR, ammo), WEP_CVAR_SEC(WEP_MORTAR, ammo))) { // forced reload + thiswep.wr_reload(thiswep, actor, weaponentity); + } else if(fire & 1) + { + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(WEP_MORTAR, refire))) + { + W_Mortar_Attack(thiswep, actor, weaponentity); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(WEP_MORTAR, animtime), w_ready); + } + } + else if(fire & 2) + { + if(WEP_CVAR_SEC(WEP_MORTAR, remote_detonateprimary)) + { + bool nadefound = false; + IL_EACH(g_projectiles, it.realowner == actor && it.classname == "grenade", + { + if(!it.gl_detonate_later) + { + it.gl_detonate_later = true; + nadefound = true; + } + }); + if(nadefound) + sound(actor, CH_WEAPON_B, SND_ROCKET_DET, VOL_BASE, ATTN_NORM); + } + else if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(WEP_MORTAR, refire))) + { + W_Mortar_Attack2(thiswep, actor, weaponentity); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(WEP_MORTAR, animtime), w_ready); + } + } } + METHOD(Mortar, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity)) { - float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_PRI(WEP_MORTAR, ammo); - ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_PRI(WEP_MORTAR, ammo); - return ammo_amount; + float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_PRI(WEP_MORTAR, ammo); + ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_PRI(WEP_MORTAR, ammo); + return ammo_amount; } + METHOD(Mortar, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity)) { - float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_SEC(WEP_MORTAR, ammo); - ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_SEC(WEP_MORTAR, ammo); - return ammo_amount; + float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_SEC(WEP_MORTAR, ammo); + ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_SEC(WEP_MORTAR, ammo); + return ammo_amount; } + METHOD(Mortar, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) { - W_Reload(actor, weaponentity, min(WEP_CVAR_PRI(WEP_MORTAR, ammo), WEP_CVAR_SEC(WEP_MORTAR, ammo)), SND_RELOAD); // WEAPONTODO + W_Reload(actor, weaponentity, min(WEP_CVAR_PRI(WEP_MORTAR, ammo), WEP_CVAR_SEC(WEP_MORTAR, ammo)), SND_RELOAD); // WEAPONTODO } + METHOD(Mortar, wr_suicidemessage, Notification(entity thiswep)) { - if(w_deathtype & HITTYPE_SECONDARY) - return WEAPON_MORTAR_SUICIDE_BOUNCE; - else - return WEAPON_MORTAR_SUICIDE_EXPLODE; + if(w_deathtype & HITTYPE_SECONDARY) + return WEAPON_MORTAR_SUICIDE_BOUNCE; + else + return WEAPON_MORTAR_SUICIDE_EXPLODE; } + METHOD(Mortar, wr_killmessage, Notification(entity thiswep)) { - if(w_deathtype & HITTYPE_SECONDARY) - return WEAPON_MORTAR_MURDER_BOUNCE; - else - return WEAPON_MORTAR_MURDER_EXPLODE; + if(w_deathtype & HITTYPE_SECONDARY) + return WEAPON_MORTAR_MURDER_BOUNCE; + else + return WEAPON_MORTAR_MURDER_EXPLODE; } #endif @@ -358,10 +365,10 @@ METHOD(Mortar, wr_killmessage, Notification(entity thiswep)) METHOD(Mortar, wr_impacteffect, void(entity thiswep, entity actor)) { - vector org2 = w_org + w_backoff * 2; - pointparticles(EFFECT_GRENADE_EXPLODE, org2, '0 0 0', 1); - if(!w_issilent) - sound(actor, CH_SHOTS, SND_GRENADE_IMPACT, VOL_BASE, ATTN_NORM); + vector org2 = w_org + w_backoff * 2; + pointparticles(EFFECT_GRENADE_EXPLODE, org2, '0 0 0', 1); + if(!w_issilent) + sound(actor, CH_SHOTS, SND_GRENADE_IMPACT, VOL_BASE, ATTN_NORM); } #endif diff --git a/qcsrc/common/weapons/weapon/mortar.qh b/qcsrc/common/weapons/weapon/mortar.qh index ce333250a..880965022 100644 --- a/qcsrc/common/weapons/weapon/mortar.qh +++ b/qcsrc/common/weapons/weapon/mortar.qh @@ -52,7 +52,7 @@ CLASS(Mortar, Weapon) P(class, prefix, weaponstart, float, NONE) \ P(class, prefix, weaponthrowable, float, NONE) \ END() - W_PROPS(X, Mortar, mortar) + W_PROPS(X, Mortar, mortar) #undef X ENDCLASS(Mortar) REGISTER_WEAPON(MORTAR, NEW(Mortar)); diff --git a/qcsrc/common/weapons/weapon/porto.qc b/qcsrc/common/weapons/weapon/porto.qc index d54b6a714..ef5c5d778 100644 --- a/qcsrc/common/weapons/weapon/porto.qc +++ b/qcsrc/common/weapons/weapon/porto.qc @@ -1,6 +1,7 @@ #include "porto.qh" #ifdef CSQC + STATIC_INIT(Porto) { entity e = new_pure(porto); @@ -77,9 +78,11 @@ void Porto_Draw(entity this) } } } + #endif #ifdef SVQC + #include #include @@ -336,79 +339,87 @@ void W_Porto_Attack(Weapon thiswep, entity actor, .entity weaponentity, float ty METHOD(PortoLaunch, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { - PHYS_INPUT_BUTTON_ATCK(actor) = false; - PHYS_INPUT_BUTTON_ATCK2(actor) = false; - if(!WEP_CVAR(WEP_PORTO, secondary)) - if(bot_aim(actor, weaponentity, WEP_CVAR_PRI(WEP_PORTO, speed), 0, WEP_CVAR_PRI(WEP_PORTO, lifetime), false, true)) - PHYS_INPUT_BUTTON_ATCK(actor) = true; + PHYS_INPUT_BUTTON_ATCK(actor) = false; + PHYS_INPUT_BUTTON_ATCK2(actor) = false; + if(!WEP_CVAR(WEP_PORTO, secondary)) + if(bot_aim(actor, weaponentity, WEP_CVAR_PRI(WEP_PORTO, speed), 0, WEP_CVAR_PRI(WEP_PORTO, lifetime), false, true)) + PHYS_INPUT_BUTTON_ATCK(actor) = true; } + METHOD(PortoLaunch, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) { - if(WEP_CVAR(WEP_PORTO, secondary)) - { - if(fire & 1) - if(!actor.porto_current) - if(!actor.porto_forbidden) - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(WEP_PORTO, refire))) - { - W_Porto_Attack(thiswep, actor, weaponentity, 0); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(WEP_PORTO, animtime), w_ready); - } - - if(fire & 2) - if(!actor.porto_current) - if(!actor.porto_forbidden) - if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(WEP_PORTO, refire))) - { - W_Porto_Attack(thiswep, actor, weaponentity, 1); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(WEP_PORTO, animtime), w_ready); - } - } - else - { - if(actor.(weaponentity).porto_v_angle_held) - { - if(!(fire & 2)) - actor.(weaponentity).porto_v_angle_held = 0; - } - else - { - if(fire & 2) - { - actor.(weaponentity).porto_v_angle = actor.v_angle; - actor.(weaponentity).porto_v_angle_held = 1; - } - } - if(actor.(weaponentity).porto_v_angle_held) - makevectors(actor.(weaponentity).porto_v_angle); // override the previously set angles - - if(fire & 1) - if(!actor.porto_current) - if(!actor.porto_forbidden) - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(WEP_PORTO, refire))) - { - W_Porto_Attack(thiswep, actor, weaponentity, -1); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(WEP_PORTO, animtime), w_ready); - } - } + if(WEP_CVAR(WEP_PORTO, secondary)) + { + if(fire & 1) + if(!actor.porto_current) + if(!actor.porto_forbidden) + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(WEP_PORTO, refire))) + { + W_Porto_Attack(thiswep, actor, weaponentity, 0); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(WEP_PORTO, animtime), w_ready); + } + + if(fire & 2) + if(!actor.porto_current) + if(!actor.porto_forbidden) + if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(WEP_PORTO, refire))) + { + W_Porto_Attack(thiswep, actor, weaponentity, 1); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(WEP_PORTO, animtime), w_ready); + } + } + else + { + if(actor.(weaponentity).porto_v_angle_held) + { + if(!(fire & 2)) + actor.(weaponentity).porto_v_angle_held = 0; + } + else + { + if(fire & 2) + { + actor.(weaponentity).porto_v_angle = actor.v_angle; + actor.(weaponentity).porto_v_angle_held = 1; + } + } + if(actor.(weaponentity).porto_v_angle_held) + makevectors(actor.(weaponentity).porto_v_angle); // override the previously set angles + + if(fire & 1) + if(!actor.porto_current) + if(!actor.porto_forbidden) + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(WEP_PORTO, refire))) + { + W_Porto_Attack(thiswep, actor, weaponentity, -1); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(WEP_PORTO, animtime), w_ready); + } + } } + METHOD(PortoLaunch, wr_checkammo1, bool(entity thiswep, entity this, .entity weaponentity)) { - // always allow infinite ammo - return true; + // always allow infinite ammo + return true; } + METHOD(PortoLaunch, wr_checkammo2, bool(entity thiswep, entity this, .entity weaponentity)) { - // always allow infinite ammo - return true; + // always allow infinite ammo + return true; } + METHOD(PortoLaunch, wr_resetplayer, void(entity thiswep, entity actor)) { - actor.porto_current = NULL; + actor.porto_current = NULL; } + #endif + #ifdef CSQC + METHOD(PortoLaunch, wr_impacteffect, void(entity this, entity actor)) { - LOG_WARN("Since when does Porto send DamageInfo?"); + LOG_WARN("Since when does Porto send DamageInfo?"); } + #endif diff --git a/qcsrc/common/weapons/weapon/porto.qh b/qcsrc/common/weapons/weapon/porto.qh index 30d76908b..75cd7474c 100644 --- a/qcsrc/common/weapons/weapon/porto.qh +++ b/qcsrc/common/weapons/weapon/porto.qh @@ -24,14 +24,14 @@ CLASS(PortoLaunch, Weapon) P(class, prefix, refire, float, BOTH) \ P(class, prefix, secondary, float, NONE) \ P(class, prefix, speed, float, BOTH) \ - P(class, prefix, switchdelay_drop, float, NONE) \ + P(class, prefix, switchdelay_drop, float, NONE) \ P(class, prefix, switchdelay_raise, float, NONE) \ - P(class, prefix, weaponreplace, string,NONE) \ - P(class, prefix, weaponstartoverride, float, NONE) \ - P(class, prefix, weaponstart, float, NONE) \ - P(class, prefix, weaponthrowable, float, NONE) \ + P(class, prefix, weaponreplace, string,NONE) \ + P(class, prefix, weaponstartoverride, float, NONE) \ + P(class, prefix, weaponstart, float, NONE) \ + P(class, prefix, weaponthrowable, float, NONE) \ END() - W_PROPS(X, PortoLaunch, porto) + W_PROPS(X, PortoLaunch, porto) #undef X ENDCLASS(PortoLaunch) REGISTER_WEAPON(PORTO, NEW(PortoLaunch)); diff --git a/qcsrc/common/weapons/weapon/rifle.qc b/qcsrc/common/weapons/weapon/rifle.qc index a97326954..7a1fb2cfa 100644 --- a/qcsrc/common/weapons/weapon/rifle.qc +++ b/qcsrc/common/weapons/weapon/rifle.qc @@ -102,110 +102,121 @@ void W_Rifle_BulletHail(Weapon thiswep, entity actor, .entity weaponentity, floa METHOD(Rifle, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { - PHYS_INPUT_BUTTON_ATCK(actor) = false; - PHYS_INPUT_BUTTON_ATCK2(actor) = false; - if(vdist(actor.origin - actor.enemy.origin, >, 1000)) - actor.bot_secondary_riflemooth = 0; - if(actor.bot_secondary_riflemooth == 0) - { - if(bot_aim(actor, weaponentity, 1000000, 0, 0.001, false, true)) - { - PHYS_INPUT_BUTTON_ATCK(actor) = true; - if(random() < 0.01) actor.bot_secondary_riflemooth = 1; - } - } - else - { - if(bot_aim(actor, weaponentity, 1000000, 0, 0.001, false, true)) - { - PHYS_INPUT_BUTTON_ATCK2(actor) = true; - if(random() < 0.03) actor.bot_secondary_riflemooth = 0; - } - } + PHYS_INPUT_BUTTON_ATCK(actor) = false; + PHYS_INPUT_BUTTON_ATCK2(actor) = false; + if(vdist(actor.origin - actor.enemy.origin, >, 1000)) + actor.bot_secondary_riflemooth = 0; + if(actor.bot_secondary_riflemooth == 0) + { + if(bot_aim(actor, weaponentity, 1000000, 0, 0.001, false, true)) + { + PHYS_INPUT_BUTTON_ATCK(actor) = true; + if(random() < 0.01) actor.bot_secondary_riflemooth = 1; + } + } + else + { + if(bot_aim(actor, weaponentity, 1000000, 0, 0.001, false, true)) + { + PHYS_INPUT_BUTTON_ATCK2(actor) = true; + if(random() < 0.03) actor.bot_secondary_riflemooth = 0; + } + } } + METHOD(Rifle, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) { - if(autocvar_g_balance_rifle_reload_ammo && actor.(weaponentity).clip_load < min(WEP_CVAR_PRI(WEP_RIFLE, ammo), WEP_CVAR_SEC(WEP_RIFLE, ammo))) { // forced reload - thiswep.wr_reload(thiswep, actor, weaponentity); - } else - { - actor.(weaponentity).rifle_accumulator = bound(time - WEP_CVAR(WEP_RIFLE, bursttime), actor.(weaponentity).rifle_accumulator, time); - if(fire & 1) - if(weapon_prepareattack_check(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(WEP_RIFLE, refire))) - if(time >= actor.(weaponentity).rifle_accumulator + WEP_CVAR_PRI(WEP_RIFLE, burstcost)) - { - weapon_prepareattack_do(actor, weaponentity, false, WEP_CVAR_PRI(WEP_RIFLE, refire)); - W_Rifle_BulletHail(thiswep, actor, weaponentity, WEP_CVAR_PRI(WEP_RIFLE, bullethail), W_Rifle_Attack, WFRAME_FIRE1, WEP_CVAR_PRI(WEP_RIFLE, animtime), WEP_CVAR_PRI(WEP_RIFLE, refire)); - actor.(weaponentity).rifle_accumulator += WEP_CVAR_PRI(WEP_RIFLE, burstcost); - } - if(fire & 2) - { - if(WEP_CVAR(WEP_RIFLE, secondary)) - { - if(WEP_CVAR_SEC(WEP_RIFLE, reload)) { - thiswep.wr_reload(thiswep, actor, weaponentity); - } else - { - if(weapon_prepareattack_check(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(WEP_RIFLE, refire))) - if(time >= actor.(weaponentity).rifle_accumulator + WEP_CVAR_SEC(WEP_RIFLE, burstcost)) - { - weapon_prepareattack_do(actor, weaponentity, true, WEP_CVAR_SEC(WEP_RIFLE, refire)); - W_Rifle_BulletHail(thiswep, actor, weaponentity, WEP_CVAR_SEC(WEP_RIFLE, bullethail), W_Rifle_Attack2, WFRAME_FIRE2, WEP_CVAR_SEC(WEP_RIFLE, animtime), WEP_CVAR_PRI(WEP_RIFLE, refire)); - actor.(weaponentity).rifle_accumulator += WEP_CVAR_SEC(WEP_RIFLE, burstcost); - } - } - } - } - } + if(autocvar_g_balance_rifle_reload_ammo && actor.(weaponentity).clip_load < min(WEP_CVAR_PRI(WEP_RIFLE, ammo), WEP_CVAR_SEC(WEP_RIFLE, ammo))) + { // forced reload + thiswep.wr_reload(thiswep, actor, weaponentity); + } + else + { + actor.(weaponentity).rifle_accumulator = bound(time - WEP_CVAR(WEP_RIFLE, bursttime), actor.(weaponentity).rifle_accumulator, time); + if(fire & 1) + if(weapon_prepareattack_check(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(WEP_RIFLE, refire))) + if(time >= actor.(weaponentity).rifle_accumulator + WEP_CVAR_PRI(WEP_RIFLE, burstcost)) + { + weapon_prepareattack_do(actor, weaponentity, false, WEP_CVAR_PRI(WEP_RIFLE, refire)); + W_Rifle_BulletHail(thiswep, actor, weaponentity, WEP_CVAR_PRI(WEP_RIFLE, bullethail), W_Rifle_Attack, WFRAME_FIRE1, WEP_CVAR_PRI(WEP_RIFLE, animtime), WEP_CVAR_PRI(WEP_RIFLE, refire)); + actor.(weaponentity).rifle_accumulator += WEP_CVAR_PRI(WEP_RIFLE, burstcost); + } + if(fire & 2) + { + if(WEP_CVAR(WEP_RIFLE, secondary)) + { + if(WEP_CVAR_SEC(WEP_RIFLE, reload)) { + thiswep.wr_reload(thiswep, actor, weaponentity); + } + else + { + if(weapon_prepareattack_check(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(WEP_RIFLE, refire))) + if(time >= actor.(weaponentity).rifle_accumulator + WEP_CVAR_SEC(WEP_RIFLE, burstcost)) + { + weapon_prepareattack_do(actor, weaponentity, true, WEP_CVAR_SEC(WEP_RIFLE, refire)); + W_Rifle_BulletHail(thiswep, actor, weaponentity, WEP_CVAR_SEC(WEP_RIFLE, bullethail), W_Rifle_Attack2, WFRAME_FIRE2, WEP_CVAR_SEC(WEP_RIFLE, animtime), WEP_CVAR_PRI(WEP_RIFLE, refire)); + actor.(weaponentity).rifle_accumulator += WEP_CVAR_SEC(WEP_RIFLE, burstcost); + } + } + } + } + } } + METHOD(Rifle, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity)) { - float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_PRI(WEP_RIFLE, ammo); - ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_PRI(WEP_RIFLE, ammo); - return ammo_amount; + float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_PRI(WEP_RIFLE, ammo); + ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_PRI(WEP_RIFLE, ammo); + return ammo_amount; } + METHOD(Rifle, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity)) { - float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_SEC(WEP_RIFLE, ammo); - ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_SEC(WEP_RIFLE, ammo); - return ammo_amount; + float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_SEC(WEP_RIFLE, ammo); + ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_SEC(WEP_RIFLE, ammo); + return ammo_amount; } + METHOD(Rifle, wr_resetplayer, void(entity thiswep, entity actor)) { - for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) - { - .entity weaponentity = weaponentities[slot]; - actor.(weaponentity).rifle_accumulator = time - WEP_CVAR(WEP_RIFLE, bursttime); - } + for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + { + .entity weaponentity = weaponentities[slot]; + actor.(weaponentity).rifle_accumulator = time - WEP_CVAR(WEP_RIFLE, bursttime); + } } + METHOD(Rifle, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) { - W_Reload(actor, weaponentity, min(WEP_CVAR_PRI(WEP_RIFLE, ammo), WEP_CVAR_SEC(WEP_RIFLE, ammo)), SND_RELOAD); + W_Reload(actor, weaponentity, min(WEP_CVAR_PRI(WEP_RIFLE, ammo), WEP_CVAR_SEC(WEP_RIFLE, ammo)), SND_RELOAD); } + METHOD(Rifle, wr_suicidemessage, Notification(entity thiswep)) { - return WEAPON_THINKING_WITH_PORTALS; + return WEAPON_THINKING_WITH_PORTALS; } + METHOD(Rifle, wr_killmessage, Notification(entity thiswep)) { - if(w_deathtype & HITTYPE_SECONDARY) - { - if(w_deathtype & HITTYPE_BOUNCE) - return WEAPON_RIFLE_MURDER_HAIL_PIERCING; - else - return WEAPON_RIFLE_MURDER_HAIL; - } - else - { - if(w_deathtype & HITTYPE_BOUNCE) - return WEAPON_RIFLE_MURDER_PIERCING; - else - return WEAPON_RIFLE_MURDER; - } + if(w_deathtype & HITTYPE_SECONDARY) + { + if(w_deathtype & HITTYPE_BOUNCE) + return WEAPON_RIFLE_MURDER_HAIL_PIERCING; + else + return WEAPON_RIFLE_MURDER_HAIL; + } + else + { + if(w_deathtype & HITTYPE_BOUNCE) + return WEAPON_RIFLE_MURDER_PIERCING; + else + return WEAPON_RIFLE_MURDER; + } } + METHOD(Rifle, wr_zoom, bool(entity thiswep, entity actor)) { - return PHYS_INPUT_BUTTON_ATCK2(actor) && WEP_CVAR(WEP_RIFLE, secondary) == 0; + return PHYS_INPUT_BUTTON_ATCK2(actor) && WEP_CVAR(WEP_RIFLE, secondary) == 0; } #endif @@ -213,35 +224,38 @@ METHOD(Rifle, wr_zoom, bool(entity thiswep, entity actor)) METHOD(Rifle, wr_impacteffect, void(entity thiswep, entity actor)) { - vector org2 = w_org + w_backoff * 2; - pointparticles(EFFECT_RIFLE_IMPACT, org2, w_backoff * 1000, 1); - if(!w_issilent) - { - sound(actor, CH_SHOTS, SND_RIC_RANDOM(), VOL_BASE, ATTN_NORM); - } + vector org2 = w_org + w_backoff * 2; + pointparticles(EFFECT_RIFLE_IMPACT, org2, w_backoff * 1000, 1); + if(!w_issilent) + { + sound(actor, CH_SHOTS, SND_RIC_RANDOM(), VOL_BASE, ATTN_NORM); + } } + METHOD(Rifle, wr_init, void(entity thiswep)) { - if(autocvar_cl_reticle && autocvar_cl_reticle_weapon) - { - precache_pic("gfx/reticle_nex"); - } + if(autocvar_cl_reticle && autocvar_cl_reticle_weapon) + { + precache_pic("gfx/reticle_nex"); + } } + METHOD(Rifle, wr_zoom, bool(entity thiswep, entity actor)) { - if(button_zoom || zoomscript_caught) - { - return true; - } - else - { - // no weapon specific image for this weapon - return false; - } + if(button_zoom || zoomscript_caught) + { + return true; + } + else + { + // no weapon specific image for this weapon + return false; + } } + METHOD(Rifle, wr_zoomdir, bool(entity thiswep)) { - return button_attack2 && !WEP_CVAR(WEP_RIFLE, secondary); + return button_attack2 && !WEP_CVAR(WEP_RIFLE, secondary); } #endif diff --git a/qcsrc/common/weapons/weapon/seeker.qc b/qcsrc/common/weapons/weapon/seeker.qc index f1879efe4..0f439716b 100644 --- a/qcsrc/common/weapons/weapon/seeker.qc +++ b/qcsrc/common/weapons/weapon/seeker.qc @@ -52,12 +52,12 @@ void W_Seeker_Missile_Think(entity this) if(this.enemy != NULL) { - e = this.enemy; - eorg = 0.5 * (e.absmin + e.absmax); - turnrate = WEP_CVAR(WEP_SEEKER, missile_turnrate); // how fast to turn - desireddir = normalize(eorg - this.origin); - olddir = normalize(this.velocity); // get my current direction - dist = vlen(eorg - this.origin); + e = this.enemy; + eorg = 0.5 * (e.absmin + e.absmax); + turnrate = WEP_CVAR(WEP_SEEKER, missile_turnrate); // how fast to turn + desireddir = normalize(eorg - this.origin); + olddir = normalize(this.velocity); // get my current direction + dist = vlen(eorg - this.origin); // Do evasive maneuvers for world objects? ( this should be a cpu hog. :P ) if(WEP_CVAR(WEP_SEEKER, missile_smart) && (dist > WEP_CVAR(WEP_SEEKER, missile_smart_mindist))) @@ -115,7 +115,7 @@ void W_Seeker_Missile_Think(entity this) return; } - //this.angles = vectoangles(this.velocity); // turn model in the new flight direction + //this.angles = vectoangles(this.velocity); // turn model in the new flight direction this.nextthink = time;// + 0.05; // csqc projectiles UpdateCSQCProjectile(this); } @@ -151,13 +151,13 @@ void W_Seeker_Missile_Animate(entity this) if(this.frame == 5) { - this.think = W_Seeker_Missile_Think; - this.nextthink = time;// + cvar("g_balance_seeker_missile_activate_delay"); // cant dealy with csqc projectiles + this.think = W_Seeker_Missile_Think; + this.nextthink = time;// + cvar("g_balance_seeker_missile_activate_delay"); // cant dealy with csqc projectiles if(autocvar_g_balance_seeker_missile_proxy) - this.move_movetype = MOVETYPE_BOUNCEMISSILE; + this.move_movetype = MOVETYPE_BOUNCEMISSILE; else - this.move_movetype = MOVETYPE_FLYMISSILE; + this.move_movetype = MOVETYPE_FLYMISSILE; } UpdateCSQCProjectile(this); @@ -173,28 +173,28 @@ void W_Seeker_Fire_Missile(Weapon thiswep, entity actor, .entity weaponentity, v w_shotorg += f_diff; W_MuzzleFlash(thiswep, actor, weaponentity, w_shotorg, w_shotdir); - //actor.detornator = false; + //actor.detornator = false; - entity missile = new(seeker_missile); - missile.owner = missile.realowner = actor; - missile.bot_dodge = true; + entity missile = new(seeker_missile); + missile.owner = missile.realowner = actor; + missile.bot_dodge = true; missile.bot_dodgerating = WEP_CVAR(WEP_SEEKER, missile_damage); setthink(missile, W_Seeker_Missile_Think); settouch(missile, W_Seeker_Missile_Touch); - missile.event_damage = W_Seeker_Missile_Damage; - missile.nextthink = time;// + 0.2;// + cvar("g_balance_seeker_missile_activate_delay"); - missile.cnt = time + WEP_CVAR(WEP_SEEKER, missile_lifetime); - missile.enemy = m_target; - missile.solid = SOLID_BBOX; - missile.scale = 2; - missile.takedamage = DAMAGE_YES; + missile.event_damage = W_Seeker_Missile_Damage; + missile.nextthink = time; // + 0.2; // + cvar("g_balance_seeker_missile_activate_delay"); + missile.cnt = time + WEP_CVAR(WEP_SEEKER, missile_lifetime); + missile.enemy = m_target; + missile.solid = SOLID_BBOX; + missile.scale = 2; + missile.takedamage = DAMAGE_YES; missile.weaponentity_fld = weaponentity; SetResourceExplicit(missile, RES_HEALTH, WEP_CVAR(WEP_SEEKER, missile_health)); missile.damageforcescale = WEP_CVAR(WEP_SEEKER, missile_damageforcescale); missile.damagedbycontents = true; IL_PUSH(g_damagedbycontents, missile); - //missile.think = W_Seeker_Missile_Animate; // csqc projectiles. + //missile.think = W_Seeker_Missile_Animate; // csqc projectiles. if(missile.enemy != NULL) missile.projectiledeathtype = thiswep.m_id | HITTYPE_SECONDARY; @@ -272,25 +272,25 @@ void W_Seeker_Fire_Flac(Weapon thiswep, entity actor, .entity weaponentity) // uses hagar effects! W_MuzzleFlash(WEP_HAGAR, actor, weaponentity, w_shotorg, w_shotdir); - missile = new(missile); - missile.owner = missile.realowner = actor; - missile.bot_dodge = true; + missile = new(missile); + missile.owner = missile.realowner = actor; + missile.bot_dodge = true; missile.bot_dodgerating = WEP_CVAR(WEP_SEEKER, flac_damage); settouch(missile, W_Seeker_Flac_Touch); - missile.use = W_Seeker_Flac_Explode_use; + missile.use = W_Seeker_Flac_Explode_use; setthink(missile, adaptor_think2use_hittype_splash); - missile.nextthink = time + WEP_CVAR(WEP_SEEKER, flac_lifetime) + WEP_CVAR(WEP_SEEKER, flac_lifetime_rand); - missile.solid = SOLID_BBOX; + missile.nextthink = time + WEP_CVAR(WEP_SEEKER, flac_lifetime) + WEP_CVAR(WEP_SEEKER, flac_lifetime_rand); + missile.solid = SOLID_BBOX; set_movetype(missile, MOVETYPE_FLY); missile.projectiledeathtype = thiswep.m_id | HITTYPE_SECONDARY; missile.weaponentity_fld = weaponentity; missile.flags = FL_PROJECTILE; IL_PUSH(g_projectiles, missile); IL_PUSH(g_bot_dodge, missile); - missile.missile_flags = MIF_SPLASH; + missile.missile_flags = MIF_SPLASH; // csqc projectiles - //missile.angles = vectoangles(missile.velocity); + //missile.angles = vectoangles(missile.velocity); //missile.scale = 0.4; // BUG: the model is too big setorigin(missile, w_shotorg); @@ -405,7 +405,7 @@ void W_Seeker_Tracker_Think(entity this) void W_Seeker_Tag_Explode(entity this) { //if(other==this.realowner) - // return; + // return; Damage_DamageInfo(this.origin, 0, 0, 0, this.velocity, WEP_SEEKER.m_id | HITTYPE_BOUNCE, 0, this); delete(this); @@ -452,26 +452,26 @@ void W_Seeker_Tag_Touch(entity this, entity toucher) else { //sprint(this.realowner, strcat("You just tagged ^2", toucher.netname, "^7 with a tracking device!\n")); - e = new(tag_tracker); + e = new(tag_tracker); e.weaponentity_fld = this.weaponentity_fld; - e.cnt = WEP_CVAR(WEP_SEEKER, missile_count); - e.owner = this.owner; - e.realowner = this.realowner; + e.cnt = WEP_CVAR(WEP_SEEKER, missile_count); + e.owner = this.owner; + e.realowner = this.realowner; IL_PUSH(g_seeker_trackers, e); if(WEP_CVAR(WEP_SEEKER, type) == 1) { - e.tag_target = toucher; - e.tag_time = time; + e.tag_target = toucher; + e.tag_time = time; setthink(e, W_Seeker_Tracker_Think); } else { - e.enemy = toucher; + e.enemy = toucher; setthink(e, W_Seeker_Vollycontroller_Think); } - e.nextthink = time; + e.nextthink = time; } if(WEP_CVAR(WEP_SEEKER, type) == 1) @@ -491,19 +491,19 @@ void W_Seeker_Fire_Tag(Weapon thiswep, entity actor, .entity weaponentity) W_SetupShot_ProjectileSize(actor, weaponentity, '-2 -2 -2', '2 2 2', false, 2, SND_TAG_FIRE, CH_WEAPON_A, WEP_CVAR(WEP_SEEKER, missile_damage) * WEP_CVAR(WEP_SEEKER, missile_count), thiswep.m_id | HITTYPE_BOUNCE | HITTYPE_SECONDARY); - entity missile = new(seeker_tag); + entity missile = new(seeker_tag); missile.weaponentity_fld = weaponentity; - missile.owner = missile.realowner = actor; - missile.bot_dodge = true; + missile.owner = missile.realowner = actor; + missile.bot_dodge = true; missile.bot_dodgerating = 50; settouch(missile, W_Seeker_Tag_Touch); setthink(missile, SUB_Remove); - missile.nextthink = time + WEP_CVAR(WEP_SEEKER, tag_lifetime); + missile.nextthink = time + WEP_CVAR(WEP_SEEKER, tag_lifetime); set_movetype(missile, MOVETYPE_FLY); - missile.solid = SOLID_BBOX; + missile.solid = SOLID_BBOX; - missile.takedamage = DAMAGE_YES; - missile.event_damage = W_Seeker_Tag_Damage; + missile.takedamage = DAMAGE_YES; + missile.event_damage = W_Seeker_Tag_Damage; SetResourceExplicit(missile, RES_HEALTH, WEP_CVAR(WEP_SEEKER, tag_health)); missile.damageforcescale = WEP_CVAR(WEP_SEEKER, tag_damageforcescale); @@ -530,104 +530,110 @@ void W_Seeker_Fire_Tag(Weapon thiswep, entity actor, .entity weaponentity) METHOD(Seeker, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { - if(WEP_CVAR(WEP_SEEKER, type) == 1) - { - if(W_Seeker_Tagged_Info(actor, weaponentity, actor.enemy) != NULL) - PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, WEP_CVAR(WEP_SEEKER, missile_speed_max), 0, WEP_CVAR(WEP_SEEKER, missile_lifetime), false, false); - else - PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, weaponentity, WEP_CVAR(WEP_SEEKER, tag_speed), 0, WEP_CVAR(WEP_SEEKER, tag_lifetime), false, false); - } - else - PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, WEP_CVAR(WEP_SEEKER, tag_speed), 0, WEP_CVAR(WEP_SEEKER, tag_lifetime), false, true); + if(WEP_CVAR(WEP_SEEKER, type) == 1) + { + if(W_Seeker_Tagged_Info(actor, weaponentity, actor.enemy) != NULL) + PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, WEP_CVAR(WEP_SEEKER, missile_speed_max), 0, WEP_CVAR(WEP_SEEKER, missile_lifetime), false, false); + else + PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, weaponentity, WEP_CVAR(WEP_SEEKER, tag_speed), 0, WEP_CVAR(WEP_SEEKER, tag_lifetime), false, false); + } + else + PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, WEP_CVAR(WEP_SEEKER, tag_speed), 0, WEP_CVAR(WEP_SEEKER, tag_lifetime), false, true); } + METHOD(Seeker, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) { - if(autocvar_g_balance_seeker_reload_ammo && actor.(weaponentity).clip_load < min(WEP_CVAR(WEP_SEEKER, missile_ammo), WEP_CVAR(WEP_SEEKER, tag_ammo))) { // forced reload - thiswep.wr_reload(thiswep, actor, weaponentity); - } else if(fire & 1) - { - if(WEP_CVAR(WEP_SEEKER, type) == 1) - { - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(WEP_SEEKER, missile_refire))) - { - W_Seeker_Attack(thiswep, actor, weaponentity); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR(WEP_SEEKER, missile_animtime), w_ready); - } - } - else - { - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(WEP_SEEKER, tag_refire))) - { - W_Seeker_Fire_Tag(thiswep, actor, weaponentity); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR(WEP_SEEKER, tag_animtime), w_ready); - } - } - } - - else if(fire & 2) - { - if(WEP_CVAR(WEP_SEEKER, type) == 1) - { - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(WEP_SEEKER, tag_refire))) - { - W_Seeker_Fire_Tag(thiswep, actor, weaponentity); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR(WEP_SEEKER, tag_animtime), w_ready); - } - } - else - { - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(WEP_SEEKER, flac_refire))) - { - W_Seeker_Fire_Flac(thiswep, actor, weaponentity); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR(WEP_SEEKER, flac_animtime), w_ready); - } - } - } + if(autocvar_g_balance_seeker_reload_ammo && actor.(weaponentity).clip_load < min(WEP_CVAR(WEP_SEEKER, missile_ammo), WEP_CVAR(WEP_SEEKER, tag_ammo))) { // forced reload + thiswep.wr_reload(thiswep, actor, weaponentity); + } else if(fire & 1) + { + if(WEP_CVAR(WEP_SEEKER, type) == 1) + { + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(WEP_SEEKER, missile_refire))) + { + W_Seeker_Attack(thiswep, actor, weaponentity); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR(WEP_SEEKER, missile_animtime), w_ready); + } + } + else + { + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(WEP_SEEKER, tag_refire))) + { + W_Seeker_Fire_Tag(thiswep, actor, weaponentity); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR(WEP_SEEKER, tag_animtime), w_ready); + } + } + } + + else if(fire & 2) + { + if(WEP_CVAR(WEP_SEEKER, type) == 1) + { + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(WEP_SEEKER, tag_refire))) + { + W_Seeker_Fire_Tag(thiswep, actor, weaponentity); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR(WEP_SEEKER, tag_animtime), w_ready); + } + } + else + { + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(WEP_SEEKER, flac_refire))) + { + W_Seeker_Fire_Flac(thiswep, actor, weaponentity); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR(WEP_SEEKER, flac_animtime), w_ready); + } + } + } } + METHOD(Seeker, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity)) { - float ammo_amount; - if(WEP_CVAR(WEP_SEEKER, type) == 1) - { - ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR(WEP_SEEKER, missile_ammo); - ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR(WEP_SEEKER, missile_ammo); - } - else - { - ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR(WEP_SEEKER, tag_ammo); - ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR(WEP_SEEKER, tag_ammo); - } - return ammo_amount; + float ammo_amount; + if(WEP_CVAR(WEP_SEEKER, type) == 1) + { + ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR(WEP_SEEKER, missile_ammo); + ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR(WEP_SEEKER, missile_ammo); + } + else + { + ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR(WEP_SEEKER, tag_ammo); + ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR(WEP_SEEKER, tag_ammo); + } + return ammo_amount; } + METHOD(Seeker, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity)) { - float ammo_amount; - if(WEP_CVAR(WEP_SEEKER, type) == 1) - { - ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR(WEP_SEEKER, tag_ammo); - ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR(WEP_SEEKER, tag_ammo); - } - else - { - ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR(WEP_SEEKER, flac_ammo); - ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR(WEP_SEEKER, flac_ammo); - } - return ammo_amount; + float ammo_amount; + if(WEP_CVAR(WEP_SEEKER, type) == 1) + { + ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR(WEP_SEEKER, tag_ammo); + ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR(WEP_SEEKER, tag_ammo); + } + else + { + ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR(WEP_SEEKER, flac_ammo); + ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR(WEP_SEEKER, flac_ammo); + } + return ammo_amount; } + METHOD(Seeker, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) { - W_Reload(actor, weaponentity, min(WEP_CVAR(WEP_SEEKER, missile_ammo), WEP_CVAR(WEP_SEEKER, tag_ammo)), SND_RELOAD); + W_Reload(actor, weaponentity, min(WEP_CVAR(WEP_SEEKER, missile_ammo), WEP_CVAR(WEP_SEEKER, tag_ammo)), SND_RELOAD); } + METHOD(Seeker, wr_suicidemessage, Notification(entity thiswep)) { - return WEAPON_SEEKER_SUICIDE; + return WEAPON_SEEKER_SUICIDE; } + METHOD(Seeker, wr_killmessage, Notification(entity thiswep)) { - if(w_deathtype & HITTYPE_SECONDARY) - return WEAPON_SEEKER_MURDER_TAG; - else - return WEAPON_SEEKER_MURDER_SPRAY; + if(w_deathtype & HITTYPE_SECONDARY) + return WEAPON_SEEKER_MURDER_TAG; + else + return WEAPON_SEEKER_MURDER_SPRAY; } #endif @@ -635,41 +641,41 @@ METHOD(Seeker, wr_killmessage, Notification(entity thiswep)) METHOD(Seeker, wr_impacteffect, void(entity thiswep, entity actor)) { - vector org2 = w_org + w_backoff * 2; - if(w_deathtype & HITTYPE_BOUNCE) - { - if(w_deathtype & HITTYPE_SECONDARY) - { - if(!w_issilent) - sound(actor, CH_SHOTS, SND_TAG_IMPACT, 1, ATTEN_NORM); - } - else - { - pointparticles(EFFECT_HAGAR_EXPLODE, org2, '0 0 0', 1); - if(!w_issilent) - { - if(w_random<0.15) - sound(actor, CH_SHOTS, SND_TAGEXP1, 1, ATTEN_NORM); - else if(w_random<0.7) - sound(actor, CH_SHOTS, SND_TAGEXP2, 1, ATTEN_NORM); - else - sound(actor, CH_SHOTS, SND_TAGEXP3, 1, ATTEN_NORM); - } - } - } - else - { - pointparticles(EFFECT_HAGAR_EXPLODE, org2, '0 0 0', 1); - if(!w_issilent) - { - if(w_random<0.15) - sound(actor, CH_SHOTS, SND_SEEKEREXP1, 1, ATTEN_NORM); - else if(w_random<0.7) - sound(actor, CH_SHOTS, SND_SEEKEREXP2, 1, ATTEN_NORM); - else - sound(actor, CH_SHOTS, SND_SEEKEREXP3, 1, ATTEN_NORM); - } - } + vector org2 = w_org + w_backoff * 2; + if(w_deathtype & HITTYPE_BOUNCE) + { + if(w_deathtype & HITTYPE_SECONDARY) + { + if(!w_issilent) + sound(actor, CH_SHOTS, SND_TAG_IMPACT, 1, ATTEN_NORM); + } + else + { + pointparticles(EFFECT_HAGAR_EXPLODE, org2, '0 0 0', 1); + if(!w_issilent) + { + if(w_random<0.15) + sound(actor, CH_SHOTS, SND_TAGEXP1, 1, ATTEN_NORM); + else if(w_random<0.7) + sound(actor, CH_SHOTS, SND_TAGEXP2, 1, ATTEN_NORM); + else + sound(actor, CH_SHOTS, SND_TAGEXP3, 1, ATTEN_NORM); + } + } + } + else + { + pointparticles(EFFECT_HAGAR_EXPLODE, org2, '0 0 0', 1); + if(!w_issilent) + { + if(w_random<0.15) + sound(actor, CH_SHOTS, SND_SEEKEREXP1, 1, ATTEN_NORM); + else if(w_random<0.7) + sound(actor, CH_SHOTS, SND_SEEKEREXP2, 1, ATTEN_NORM); + else + sound(actor, CH_SHOTS, SND_SEEKEREXP3, 1, ATTEN_NORM); + } + } } #endif diff --git a/qcsrc/common/weapons/weapon/seeker.qh b/qcsrc/common/weapons/weapon/seeker.qh index e62145ac4..053ed1a06 100644 --- a/qcsrc/common/weapons/weapon/seeker.qh +++ b/qcsrc/common/weapons/weapon/seeker.qh @@ -21,59 +21,59 @@ CLASS(Seeker, Weapon) #define X(BEGIN, P, END, class, prefix) \ BEGIN(class) \ - P(class, prefix, flac_ammo, float, NONE) \ - P(class, prefix, flac_animtime, float, NONE) \ - P(class, prefix, flac_damage, float, NONE) \ - P(class, prefix, flac_edgedamage, float, NONE) \ - P(class, prefix, flac_force, float, NONE) \ - P(class, prefix, flac_lifetime, float, NONE) \ - P(class, prefix, flac_lifetime_rand, float, NONE) \ - P(class, prefix, flac_radius, float, NONE) \ - P(class, prefix, flac_refire, float, NONE) \ - P(class, prefix, flac_speed, float, NONE) \ - P(class, prefix, flac_speed_up, float, NONE) \ - P(class, prefix, flac_speed_z, float, NONE) \ - P(class, prefix, flac_spread, float, NONE) \ - P(class, prefix, missile_accel, float, NONE) \ - P(class, prefix, missile_ammo, float, NONE) \ - P(class, prefix, missile_animtime, float, NONE) \ - P(class, prefix, missile_count, float, NONE) \ - P(class, prefix, missile_damageforcescale, float, NONE) \ - P(class, prefix, missile_damage, float, NONE) \ - P(class, prefix, missile_decel, float, NONE) \ - P(class, prefix, missile_delay, float, NONE) \ - P(class, prefix, missile_edgedamage, float, NONE) \ - P(class, prefix, missile_force, float, NONE) \ - P(class, prefix, missile_health, float, NONE) \ - P(class, prefix, missile_lifetime, float, NONE) \ - P(class, prefix, missile_proxy, float, NONE) \ - P(class, prefix, missile_proxy_delay, float, NONE) \ - P(class, prefix, missile_proxy_maxrange, float, NONE) \ - P(class, prefix, missile_radius, float, NONE) \ - P(class, prefix, missile_refire, float, NONE) \ - P(class, prefix, missile_smart, float, NONE) \ - P(class, prefix, missile_smart_mindist, float, NONE) \ - P(class, prefix, missile_smart_trace_max, float, NONE) \ - P(class, prefix, missile_smart_trace_min, float, NONE) \ - P(class, prefix, missile_speed, float, NONE) \ - P(class, prefix, missile_speed_max, float, NONE) \ - P(class, prefix, missile_speed_up, float, NONE) \ - P(class, prefix, missile_speed_z, float, NONE) \ - P(class, prefix, missile_spread, float, NONE) \ - P(class, prefix, missile_turnrate, float, NONE) \ - P(class, prefix, reload_ammo, float, NONE) \ + P(class, prefix, flac_ammo, float, NONE) \ + P(class, prefix, flac_animtime, float, NONE) \ + P(class, prefix, flac_damage, float, NONE) \ + P(class, prefix, flac_edgedamage, float, NONE) \ + P(class, prefix, flac_force, float, NONE) \ + P(class, prefix, flac_lifetime, float, NONE) \ + P(class, prefix, flac_lifetime_rand, float, NONE) \ + P(class, prefix, flac_radius, float, NONE) \ + P(class, prefix, flac_refire, float, NONE) \ + P(class, prefix, flac_speed, float, NONE) \ + P(class, prefix, flac_speed_up, float, NONE) \ + P(class, prefix, flac_speed_z, float, NONE) \ + P(class, prefix, flac_spread, float, NONE) \ + P(class, prefix, missile_accel, float, NONE) \ + P(class, prefix, missile_ammo, float, NONE) \ + P(class, prefix, missile_animtime, float, NONE) \ + P(class, prefix, missile_count, float, NONE) \ + P(class, prefix, missile_damageforcescale, float, NONE) \ + P(class, prefix, missile_damage, float, NONE) \ + P(class, prefix, missile_decel, float, NONE) \ + P(class, prefix, missile_delay, float, NONE) \ + P(class, prefix, missile_edgedamage, float, NONE) \ + P(class, prefix, missile_force, float, NONE) \ + P(class, prefix, missile_health, float, NONE) \ + P(class, prefix, missile_lifetime, float, NONE) \ + P(class, prefix, missile_proxy, float, NONE) \ + P(class, prefix, missile_proxy_delay, float, NONE) \ + P(class, prefix, missile_proxy_maxrange, float, NONE) \ + P(class, prefix, missile_radius, float, NONE) \ + P(class, prefix, missile_refire, float, NONE) \ + P(class, prefix, missile_smart, float, NONE) \ + P(class, prefix, missile_smart_mindist, float, NONE) \ + P(class, prefix, missile_smart_trace_max, float, NONE) \ + P(class, prefix, missile_smart_trace_min, float, NONE) \ + P(class, prefix, missile_speed, float, NONE) \ + P(class, prefix, missile_speed_max, float, NONE) \ + P(class, prefix, missile_speed_up, float, NONE) \ + P(class, prefix, missile_speed_z, float, NONE) \ + P(class, prefix, missile_spread, float, NONE) \ + P(class, prefix, missile_turnrate, float, NONE) \ + P(class, prefix, reload_ammo, float, NONE) \ P(class, prefix, reload_time, float, NONE) \ P(class, prefix, switchdelay_drop, float, NONE) \ P(class, prefix, switchdelay_raise, float, NONE) \ - P(class, prefix, tag_ammo, float, NONE) \ - P(class, prefix, tag_animtime, float, NONE) \ - P(class, prefix, tag_damageforcescale, float, NONE) \ - P(class, prefix, tag_health, float, NONE) \ - P(class, prefix, tag_lifetime, float, NONE) \ - P(class, prefix, tag_refire, float, NONE) \ - P(class, prefix, tag_speed, float, NONE) \ - P(class, prefix, tag_spread, float, NONE) \ - P(class, prefix, tag_tracker_lifetime, float, NONE) \ + P(class, prefix, tag_ammo, float, NONE) \ + P(class, prefix, tag_animtime, float, NONE) \ + P(class, prefix, tag_damageforcescale, float, NONE) \ + P(class, prefix, tag_health, float, NONE) \ + P(class, prefix, tag_lifetime, float, NONE) \ + P(class, prefix, tag_refire, float, NONE) \ + P(class, prefix, tag_speed, float, NONE) \ + P(class, prefix, tag_spread, float, NONE) \ + P(class, prefix, tag_tracker_lifetime, float, NONE) \ P(class, prefix, type, float, NONE) \ P(class, prefix, weaponreplace, string, NONE) \ P(class, prefix, weaponstartoverride, float, NONE) \ diff --git a/qcsrc/common/weapons/weapon/shockwave.qc b/qcsrc/common/weapons/weapon/shockwave.qc index df75e0326..605dbd7da 100644 --- a/qcsrc/common/weapons/weapon/shockwave.qc +++ b/qcsrc/common/weapons/weapon/shockwave.qc @@ -74,9 +74,9 @@ void W_Shockwave_Melee_Think(entity this) is_player = (IS_PLAYER(trace_ent) || trace_ent.classname == "body" || IS_MONSTER(trace_ent)); if((trace_fraction < 1) // if trace is good, apply the damage and remove this if necessary - && (trace_ent.takedamage == DAMAGE_AIM) - && (trace_ent != this.swing_alreadyhit) - && (is_player || WEP_CVAR(WEP_SHOCKWAVE, melee_nonplayerdamage))) + && (trace_ent.takedamage == DAMAGE_AIM) + && (trace_ent != this.swing_alreadyhit) + && (is_player || WEP_CVAR(WEP_SHOCKWAVE, melee_nonplayerdamage))) { target_victim = trace_ent; // so it persists through other calls @@ -623,54 +623,59 @@ void W_Shockwave_Attack(Weapon thiswep, entity actor, .entity weaponentity) METHOD(Shockwave, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { - if(vdist(actor.origin - actor.enemy.origin, <=, WEP_CVAR(WEP_SHOCKWAVE, melee_range))) - { PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, weaponentity, 1000000, 0, 0.001, false, false); } - else - { PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, 1000000, 0, 0.001, false, false); } + if(vdist(actor.origin - actor.enemy.origin, <=, WEP_CVAR(WEP_SHOCKWAVE, melee_range))) + { PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, weaponentity, 1000000, 0, 0.001, false, false); } + else + { PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, 1000000, 0, 0.001, false, false); } } + METHOD(Shockwave, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) { - if(fire & 1) - { - if(time >= actor.(weaponentity).shockwave_blasttime) // handle refire separately so the secondary can be fired straight after a primary - { - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(WEP_SHOCKWAVE, blast_animtime))) - { - W_Shockwave_Attack(thiswep, actor, weaponentity); - actor.(weaponentity).shockwave_blasttime = time + WEP_CVAR(WEP_SHOCKWAVE, blast_refire) * W_WeaponRateFactor(actor); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(WEP_SHOCKWAVE, blast_animtime), w_ready); - } - } - } - else if(fire & 2) - { - //if(actor.clip_load >= 0) // we are not currently reloading - if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR(WEP_SHOCKWAVE, melee_refire))) - { - // attempt forcing playback of the anim by switching to another anim (that we never play) here... - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, 0, W_Shockwave_Melee); - } - } + if(fire & 1) + { + if(time >= actor.(weaponentity).shockwave_blasttime) // handle refire separately so the secondary can be fired straight after a primary + { + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(WEP_SHOCKWAVE, blast_animtime))) + { + W_Shockwave_Attack(thiswep, actor, weaponentity); + actor.(weaponentity).shockwave_blasttime = time + WEP_CVAR(WEP_SHOCKWAVE, blast_refire) * W_WeaponRateFactor(actor); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(WEP_SHOCKWAVE, blast_animtime), w_ready); + } + } + } + else if(fire & 2) + { + //if(actor.clip_load >= 0) // we are not currently reloading + if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR(WEP_SHOCKWAVE, melee_refire))) + { + // attempt forcing playback of the anim by switching to another anim (that we never play) here... + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, 0, W_Shockwave_Melee); + } + } } + METHOD(Shockwave, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity)) { - return true; // infinite ammo + return true; // infinite ammo } + METHOD(Shockwave, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity)) { - // shockwave has infinite ammo - return true; + // shockwave has infinite ammo + return true; } + METHOD(Shockwave, wr_suicidemessage, Notification(entity thiswep)) { - return WEAPON_THINKING_WITH_PORTALS; + return WEAPON_THINKING_WITH_PORTALS; } + METHOD(Shockwave, wr_killmessage, Notification(entity thiswep)) { - if(w_deathtype & HITTYPE_SECONDARY) - return WEAPON_SHOCKWAVE_MURDER_SLAP; - else - return WEAPON_SHOCKWAVE_MURDER; + if(w_deathtype & HITTYPE_SECONDARY) + return WEAPON_SHOCKWAVE_MURDER_SLAP; + else + return WEAPON_SHOCKWAVE_MURDER; } #endif @@ -802,9 +807,9 @@ void Net_ReadShockwaveParticle() METHOD(Shockwave, wr_impacteffect, void(entity thiswep, entity actor)) { - // handled by Net_ReadShockwaveParticle - //vector org2 = w_org + w_backoff * 2; - //pointparticles(EFFECT_BLASTER_IMPACT, org2, w_backoff * 1000, 1); + // handled by Net_ReadShockwaveParticle + //vector org2 = w_org + w_backoff * 2; + //pointparticles(EFFECT_BLASTER_IMPACT, org2, w_backoff * 1000, 1); } #endif diff --git a/qcsrc/common/weapons/weapon/shockwave.qh b/qcsrc/common/weapons/weapon/shockwave.qh index 76d3c3ef2..674fd8427 100644 --- a/qcsrc/common/weapons/weapon/shockwave.qh +++ b/qcsrc/common/weapons/weapon/shockwave.qh @@ -63,13 +63,13 @@ CLASS(Shockwave, Weapon) P(class, prefix, melee_time, float, NONE) \ P(class, prefix, melee_traces, float, NONE) \ P(class, prefix, switchdelay_raise, float, NONE) \ - P(class, prefix, switchdelay_drop, float, NONE) \ - P(class, prefix, weaponreplace, string, NONE) \ - P(class, prefix, weaponstart, float, NONE) \ - P(class, prefix, weaponstartoverride, float, NONE) \ - P(class, prefix, weaponthrowable, float, NONE) \ + P(class, prefix, switchdelay_drop, float, NONE) \ + P(class, prefix, weaponreplace, string, NONE) \ + P(class, prefix, weaponstart, float, NONE) \ + P(class, prefix, weaponstartoverride, float, NONE) \ + P(class, prefix, weaponthrowable, float, NONE) \ END() - W_PROPS(X, Shockwave, shockwave) + W_PROPS(X, Shockwave, shockwave) #undef X ENDCLASS(Shockwave) diff --git a/qcsrc/common/weapons/weapon/shotgun.qc b/qcsrc/common/weapons/weapon/shotgun.qc index 18259a3a8..49d36169c 100644 --- a/qcsrc/common/weapons/weapon/shotgun.qc +++ b/qcsrc/common/weapons/weapon/shotgun.qc @@ -242,33 +242,33 @@ void W_Shotgun_Attack3_Frame1(Weapon thiswep, entity actor, .entity weaponentity METHOD(Shotgun, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { - if(vdist(actor.origin - actor.enemy.origin, <=, WEP_CVAR_SEC(WEP_SHOTGUN, melee_range))) - PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, weaponentity, 1000000, 0, 0.001, false, false); - else - PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, 1000000, 0, 0.001, false, false); + if(vdist(actor.origin - actor.enemy.origin, <=, WEP_CVAR_SEC(WEP_SHOTGUN, melee_range))) + PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, weaponentity, 1000000, 0, 0.001, false, false); + else + PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, 1000000, 0, 0.001, false, false); } METHOD(Shotgun, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) { - // force reload weapon when clip is empty or insufficent - if(WEP_CVAR(WEP_SHOTGUN, reload_ammo) && actor.(weaponentity).clip_load < WEP_CVAR_PRI(WEP_SHOTGUN, ammo)) - { - if(actor.(weaponentity).clip_load >= 0 && GetResource(actor, thiswep.ammo_type) > 0) - { - thiswep.wr_reload(thiswep, actor, weaponentity); - return; - } - } - - if(actor.(weaponentity).clip_load >= 0) // we are not currently reloading - { - if(fire & 1) - { - if(time >= actor.(weaponentity).shotgun_primarytime) // handle refire separately so the secondary can be fired straight after a primary - { - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(WEP_SHOTGUN, animtime))) - { - W_Shotgun_Attack(thiswep, actor, weaponentity, true, + // force reload weapon when clip is empty or insufficent + if(WEP_CVAR(WEP_SHOTGUN, reload_ammo) && actor.(weaponentity).clip_load < WEP_CVAR_PRI(WEP_SHOTGUN, ammo)) + { + if(actor.(weaponentity).clip_load >= 0 && GetResource(actor, thiswep.ammo_type) > 0) + { + thiswep.wr_reload(thiswep, actor, weaponentity); + return; + } + } + + if(actor.(weaponentity).clip_load >= 0) // we are not currently reloading + { + if(fire & 1) + { + if(time >= actor.(weaponentity).shotgun_primarytime) // handle refire separately so the secondary can be fired straight after a primary + { + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(WEP_SHOTGUN, animtime))) + { + W_Shotgun_Attack(thiswep, actor, weaponentity, true, WEP_CVAR_PRI(WEP_SHOTGUN, ammo), WEP_CVAR_PRI(WEP_SHOTGUN, damage), WEP_CVAR_PRI(WEP_SHOTGUN, damagefalloff_halflife), @@ -282,19 +282,19 @@ METHOD(Shotgun, wr_think, void(entity thiswep, entity actor, .entity weaponentit WEP_CVAR_PRI(WEP_SHOTGUN, force), WEP_CVAR_PRI(WEP_SHOTGUN, damagefalloff_forcehalflife), EFFECT_BULLET_WEAK); - actor.(weaponentity).shotgun_primarytime = time + WEP_CVAR_PRI(WEP_SHOTGUN, refire) * W_WeaponRateFactor(actor); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(WEP_SHOTGUN, animtime), w_ready); - return; - } - } - } - else if((fire & 2) && WEP_CVAR(WEP_SHOTGUN, secondary) == 2) - { - if(time >= actor.(weaponentity).shotgun_primarytime) // handle refire separately so the secondary can be fired straight after a primary - { - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_SEC(WEP_SHOTGUN, alt_animtime))) - { - W_Shotgun_Attack(thiswep, actor, weaponentity, false, + actor.(weaponentity).shotgun_primarytime = time + WEP_CVAR_PRI(WEP_SHOTGUN, refire) * W_WeaponRateFactor(actor); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(WEP_SHOTGUN, animtime), w_ready); + return; + } + } + } + else if((fire & 2) && WEP_CVAR(WEP_SHOTGUN, secondary) == 2) + { + if(time >= actor.(weaponentity).shotgun_primarytime) // handle refire separately so the secondary can be fired straight after a primary + { + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_SEC(WEP_SHOTGUN, alt_animtime))) + { + W_Shotgun_Attack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(WEP_SHOTGUN, ammo), WEP_CVAR_PRI(WEP_SHOTGUN, damage), WEP_CVAR_PRI(WEP_SHOTGUN, damagefalloff_halflife), @@ -308,59 +308,64 @@ METHOD(Shotgun, wr_think, void(entity thiswep, entity actor, .entity weaponentit WEP_CVAR_PRI(WEP_SHOTGUN, force), WEP_CVAR_PRI(WEP_SHOTGUN, damagefalloff_forcehalflife), EFFECT_BULLET_WEAK); - actor.(weaponentity).shotgun_primarytime = time + WEP_CVAR_SEC(WEP_SHOTGUN, alt_refire) * W_WeaponRateFactor(actor); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_SEC(WEP_SHOTGUN, alt_animtime), W_Shotgun_Attack3_Frame1); - return; - } - } - } - } - - if(actor.(weaponentity).clip_load >= 0) // we are not currently reloading - if(WEP_CVAR(WEP_SHOTGUN, secondary) == 1) - if(((fire & 1) && !IS_BOT_CLIENT(actor) && GetResource(actor, thiswep.ammo_type) <= 0 && actor.(weaponentity).clip_load == 0 && !(actor.items & IT_UNLIMITED_AMMO)) || (fire & 2)) - if(!WEP_CVAR_SEC(WEP_SHOTGUN, melee_blockedbyfiring) || time >= actor.(weaponentity).shotgun_primarytime) - if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(WEP_SHOTGUN, refire))) - { - // melee attack - // attempt forcing playback of the anim by switching to another anim (that we never play) here... - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, 0, W_Shotgun_Attack2); - } + actor.(weaponentity).shotgun_primarytime = time + WEP_CVAR_SEC(WEP_SHOTGUN, alt_refire) * W_WeaponRateFactor(actor); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_SEC(WEP_SHOTGUN, alt_animtime), W_Shotgun_Attack3_Frame1); + return; + } + } + } + } + + if(actor.(weaponentity).clip_load >= 0) // we are not currently reloading + if(WEP_CVAR(WEP_SHOTGUN, secondary) == 1) + if(((fire & 1) && !IS_BOT_CLIENT(actor) && GetResource(actor, thiswep.ammo_type) <= 0 && actor.(weaponentity).clip_load == 0 && !(actor.items & IT_UNLIMITED_AMMO)) || (fire & 2)) + if(!WEP_CVAR_SEC(WEP_SHOTGUN, melee_blockedbyfiring) || time >= actor.(weaponentity).shotgun_primarytime) + if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(WEP_SHOTGUN, refire))) + { + // melee attack + // attempt forcing playback of the anim by switching to another anim (that we never play) here... + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, 0, W_Shotgun_Attack2); + } } + METHOD(Shotgun, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity)) { - float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_PRI(WEP_SHOTGUN, ammo); - ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_PRI(WEP_SHOTGUN, ammo); - return ammo_amount; + float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_PRI(WEP_SHOTGUN, ammo); + ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_PRI(WEP_SHOTGUN, ammo); + return ammo_amount; } + METHOD(Shotgun, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity)) { - switch(WEP_CVAR(WEP_SHOTGUN, secondary)) - { - case 1: return true; // melee does not use ammo - case 2: // secondary triple shot - { - float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_PRI(WEP_SHOTGUN, ammo); - ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_PRI(WEP_SHOTGUN, ammo); - return ammo_amount; - } - default: return false; // secondary unavailable - } + switch(WEP_CVAR(WEP_SHOTGUN, secondary)) + { + case 1: return true; // melee does not use ammo + case 2: // secondary triple shot + { + float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_PRI(WEP_SHOTGUN, ammo); + ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_PRI(WEP_SHOTGUN, ammo); + return ammo_amount; + } + default: return false; // secondary unavailable + } } + METHOD(Shotgun, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) { - W_Reload(actor, weaponentity, WEP_CVAR_PRI(WEP_SHOTGUN, ammo), SND_RELOAD); // WEAPONTODO + W_Reload(actor, weaponentity, WEP_CVAR_PRI(WEP_SHOTGUN, ammo), SND_RELOAD); // WEAPONTODO } + METHOD(Shotgun, wr_suicidemessage, Notification(entity thiswep)) { - return WEAPON_THINKING_WITH_PORTALS; + return WEAPON_THINKING_WITH_PORTALS; } + METHOD(Shotgun, wr_killmessage, Notification(entity thiswep)) { - if(w_deathtype & HITTYPE_SECONDARY) - return WEAPON_SHOTGUN_MURDER_SLAP; - else - return WEAPON_SHOTGUN_MURDER; + if(w_deathtype & HITTYPE_SECONDARY) + return WEAPON_SHOTGUN_MURDER_SLAP; + else + return WEAPON_SHOTGUN_MURDER; } #endif @@ -369,14 +374,14 @@ METHOD(Shotgun, wr_killmessage, Notification(entity thiswep)) METHOD(Shotgun, wr_impacteffect, void(entity thiswep, entity actor)) { - vector org2 = w_org + w_backoff * 2; - pointparticles(EFFECT_SHOTGUN_IMPACT, org2, w_backoff * 1000, 1); - if(!w_issilent && time - actor.prevric > 0.25) - { - if(w_random < 0.05) - sound(actor, CH_SHOTS, SND_RIC_RANDOM(), VOL_BASE, ATTEN_NORM); - actor.prevric = time; - } + vector org2 = w_org + w_backoff * 2; + pointparticles(EFFECT_SHOTGUN_IMPACT, org2, w_backoff * 1000, 1); + if(!w_issilent && time - actor.prevric > 0.25) + { + if(w_random < 0.05) + sound(actor, CH_SHOTS, SND_RIC_RANDOM(), VOL_BASE, ATTEN_NORM); + actor.prevric = time; + } } #endif diff --git a/qcsrc/common/weapons/weapon/tuba.qh b/qcsrc/common/weapons/weapon/tuba.qh index f2a1712c5..5de0b647b 100644 --- a/qcsrc/common/weapons/weapon/tuba.qh +++ b/qcsrc/common/weapons/weapon/tuba.qh @@ -36,7 +36,7 @@ CLASS(Tuba, Weapon) P(class, prefix, weaponstart, float, NONE) \ P(class, prefix, weaponthrowable, float, NONE) \ END() - W_PROPS(X, Tuba, tuba) + W_PROPS(X, Tuba, tuba) #undef X ENDCLASS(Tuba) REGISTER_WEAPON(TUBA, NEW(Tuba)); diff --git a/qcsrc/common/weapons/weapon/vaporizer.qc b/qcsrc/common/weapons/weapon/vaporizer.qc index afe3f57f2..4cd9415cf 100644 --- a/qcsrc/common/weapons/weapon/vaporizer.qc +++ b/qcsrc/common/weapons/weapon/vaporizer.qc @@ -24,6 +24,7 @@ string Draw_VaporizerBeam_trace_callback_tex; float Draw_VaporizerBeam_trace_callback_rnd; vector Draw_VaporizerBeam_trace_callback_rgb; float Draw_VaporizerBeam_trace_callback_a; + void Draw_VaporizerBeam_trace_callback(vector start, vector hit, vector end) { float i; @@ -246,115 +247,131 @@ void W_RocketMinsta_Attack(entity actor, .entity weaponentity, int mode) METHOD(Vaporizer, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { - if((actor.items & IT_UNLIMITED_AMMO) || GetResource(actor, thiswep.ammo_type) > 0) - PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, 1000000, 0, 1, false, true); - else - PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, weaponentity, WEP_CVAR_PRI(WEP_BLASTER, speed), 0, WEP_CVAR_PRI(WEP_BLASTER, lifetime), false, true); + if((actor.items & IT_UNLIMITED_AMMO) || GetResource(actor, thiswep.ammo_type) > 0) + PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, 1000000, 0, 1, false, true); + else + PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, weaponentity, WEP_CVAR_PRI(WEP_BLASTER, speed), 0, WEP_CVAR_PRI(WEP_BLASTER, lifetime), false, true); } + METHOD(Vaporizer, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) { - float vaporizer_ammo = ((autocvar_g_instagib) ? 1 : WEP_CVAR_PRI(WEP_VAPORIZER, ammo)); - // if the laser uses load, we also consider its ammo for reloading - if(WEP_CVAR(WEP_VAPORIZER, reload_ammo) && WEP_CVAR_PRI(WEP_BLASTER, ammo) && actor.(weaponentity).clip_load < min(vaporizer_ammo, WEP_CVAR_PRI(WEP_BLASTER, ammo))) { // forced reload - thiswep.wr_reload(thiswep, actor, weaponentity); - actor.(weaponentity).hagar_load = false; // rocket minsta exclusive var - return; - } else if(WEP_CVAR(WEP_VAPORIZER, reload_ammo) && actor.(weaponentity).clip_load < vaporizer_ammo) { // forced reload - thiswep.wr_reload(thiswep, actor, weaponentity); - actor.(weaponentity).hagar_load = false; // rocket minsta exclusive var - return; - } - if((fire & 1) && (GetResource(actor, RES_CELLS) || !autocvar_g_rm) && !weaponLocked(actor)) - { - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(WEP_VAPORIZER, refire))) - { - W_Vaporizer_Attack(thiswep, actor, weaponentity); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(WEP_VAPORIZER, animtime), w_ready); - } - } - if((fire & 2) || ((fire & 1) && !GetResource(actor, RES_CELLS) && autocvar_g_rm)) - { - if((autocvar_g_rm && autocvar_g_rm_laser) || autocvar_g_rm_laser == 2) - { - bool rapid = autocvar_g_rm_laser_rapid; - //hagar_load was previously named held_down - if(actor.(weaponentity).jump_interval <= time && !actor.(weaponentity).hagar_load) - { - if(rapid) - actor.(weaponentity).hagar_load = true; - actor.(weaponentity).jump_interval = time + autocvar_g_rm_laser_refire; - actor.(weaponentity).jump_interval2 = time + autocvar_g_rm_laser_rapid_delay; - impressive_hits = 0; - W_RocketMinsta_Attack(actor, weaponentity, 0); - } - else if(rapid && actor.(weaponentity).jump_interval2 <= time && actor.(weaponentity).hagar_load) - { - actor.(weaponentity).jump_interval2 = time + autocvar_g_rm_laser_rapid_refire; - impressive_hits = 0; - W_RocketMinsta_Attack(actor, weaponentity, 1); - //weapon_thinkf(actor, WFRAME_FIRE2, autocvar_g_rm_laser_rapid_animtime, w_ready); - } - } - else if (actor.(weaponentity).jump_interval <= time) - { - // handle refire manually, so that primary and secondary can be fired without conflictions (important for instagib) - actor.(weaponentity).jump_interval = time + WEP_CVAR_PRI(WEP_BLASTER, refire) * W_WeaponRateFactor(actor); - - // decrease ammo for the laser? - if(WEP_CVAR_PRI(WEP_BLASTER, ammo)) - W_DecreaseAmmo(thiswep, actor, WEP_CVAR_PRI(WEP_BLASTER, ammo), weaponentity); - - makevectors(actor.v_angle); - W_Blaster_Attack(actor, weaponentity); - - // now do normal refire - weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_PRI(WEP_BLASTER, animtime), w_ready); - } - } - else - actor.(weaponentity).hagar_load = false; + float vaporizer_ammo = ((autocvar_g_instagib) ? 1 : WEP_CVAR_PRI(WEP_VAPORIZER, ammo)); + // if the laser uses load, we also consider its ammo for reloading + if (WEP_CVAR(WEP_VAPORIZER, reload_ammo) + && WEP_CVAR_PRI(WEP_BLASTER, ammo) + && actor.(weaponentity).clip_load < min(vaporizer_ammo, WEP_CVAR_PRI(WEP_BLASTER, ammo))) + { // forced reload + thiswep.wr_reload(thiswep, actor, weaponentity); + actor.(weaponentity).hagar_load = false; // rocket minsta exclusive var + return; + } + if(WEP_CVAR(WEP_VAPORIZER, reload_ammo) + && actor.(weaponentity).clip_load < vaporizer_ammo) + { // forced reload + thiswep.wr_reload(thiswep, actor, weaponentity); + actor.(weaponentity).hagar_load = false; // rocket minsta exclusive var + return; + } + + if((fire & 1) && (GetResource(actor, RES_CELLS) || !autocvar_g_rm) && !weaponLocked(actor)) + { + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(WEP_VAPORIZER, refire))) + { + W_Vaporizer_Attack(thiswep, actor, weaponentity); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(WEP_VAPORIZER, animtime), w_ready); + } + } + + if((fire & 2) || ((fire & 1) && !GetResource(actor, RES_CELLS) && autocvar_g_rm)) + { + if((autocvar_g_rm && autocvar_g_rm_laser) || autocvar_g_rm_laser == 2) + { + bool rapid = autocvar_g_rm_laser_rapid; + //hagar_load was previously named held_down + if(actor.(weaponentity).jump_interval <= time && !actor.(weaponentity).hagar_load) + { + if(rapid) + actor.(weaponentity).hagar_load = true; + actor.(weaponentity).jump_interval = time + autocvar_g_rm_laser_refire; + actor.(weaponentity).jump_interval2 = time + autocvar_g_rm_laser_rapid_delay; + impressive_hits = 0; + W_RocketMinsta_Attack(actor, weaponentity, 0); + } + else if(rapid && actor.(weaponentity).jump_interval2 <= time && actor.(weaponentity).hagar_load) + { + actor.(weaponentity).jump_interval2 = time + autocvar_g_rm_laser_rapid_refire; + impressive_hits = 0; + W_RocketMinsta_Attack(actor, weaponentity, 1); + //weapon_thinkf(actor, WFRAME_FIRE2, autocvar_g_rm_laser_rapid_animtime, w_ready); + } + } + else if (actor.(weaponentity).jump_interval <= time) + { + // handle refire manually, so that primary and secondary can be fired without conflictions (important for instagib) + actor.(weaponentity).jump_interval = time + WEP_CVAR_PRI(WEP_BLASTER, refire) * W_WeaponRateFactor(actor); + + // decrease ammo for the laser? + if(WEP_CVAR_PRI(WEP_BLASTER, ammo)) + W_DecreaseAmmo(thiswep, actor, WEP_CVAR_PRI(WEP_BLASTER, ammo), weaponentity); + + makevectors(actor.v_angle); + W_Blaster_Attack(actor, weaponentity); + + // now do normal refire + weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_PRI(WEP_BLASTER, animtime), w_ready); + } + } + else + actor.(weaponentity).hagar_load = false; } + METHOD(Vaporizer, wr_setup, void(entity thiswep, entity actor, .entity weaponentity)) { - actor.vaporizer_lasthit = 0; + actor.vaporizer_lasthit = 0; } + METHOD(Vaporizer, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity)) { - float vaporizer_ammo = ((autocvar_g_instagib) ? 1 : WEP_CVAR_PRI(WEP_VAPORIZER, ammo)); - float ammo_amount = GetResource(actor, thiswep.ammo_type) >= vaporizer_ammo; - ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= vaporizer_ammo; - return ammo_amount; + float vaporizer_ammo = ((autocvar_g_instagib) ? 1 : WEP_CVAR_PRI(WEP_VAPORIZER, ammo)); + float ammo_amount = GetResource(actor, thiswep.ammo_type) >= vaporizer_ammo; + ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= vaporizer_ammo; + return ammo_amount; } + METHOD(Vaporizer, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity)) { - if(!WEP_CVAR_PRI(WEP_BLASTER, ammo)) - return true; - float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_PRI(WEP_BLASTER, ammo); - ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_PRI(WEP_BLASTER, ammo); - return ammo_amount; + if(!WEP_CVAR_PRI(WEP_BLASTER, ammo)) + return true; + float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_PRI(WEP_BLASTER, ammo); + ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_PRI(WEP_BLASTER, ammo); + return ammo_amount; } + METHOD(Vaporizer, wr_resetplayer, void(entity thiswep, entity actor)) { - actor.vaporizer_lasthit = 0; + actor.vaporizer_lasthit = 0; } + METHOD(Vaporizer, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) { - float vaporizer_ammo = ((autocvar_g_instagib) ? 1 : WEP_CVAR_PRI(WEP_VAPORIZER, ammo)); - float used_ammo; - if(WEP_CVAR_PRI(WEP_BLASTER, ammo)) - used_ammo = min(vaporizer_ammo, WEP_CVAR_PRI(WEP_BLASTER, ammo)); - else - used_ammo = vaporizer_ammo; - - W_Reload(actor, weaponentity, used_ammo, SND_RELOAD); + float vaporizer_ammo = ((autocvar_g_instagib) ? 1 : WEP_CVAR_PRI(WEP_VAPORIZER, ammo)); + float used_ammo; + if(WEP_CVAR_PRI(WEP_BLASTER, ammo)) + used_ammo = min(vaporizer_ammo, WEP_CVAR_PRI(WEP_BLASTER, ammo)); + else + used_ammo = vaporizer_ammo; + + W_Reload(actor, weaponentity, used_ammo, SND_RELOAD); } + METHOD(Vaporizer, wr_suicidemessage, Notification(entity thiswep)) { - return WEAPON_THINKING_WITH_PORTALS; + return WEAPON_THINKING_WITH_PORTALS; } + METHOD(Vaporizer, wr_killmessage, Notification(entity thiswep)) { - return WEAPON_VAPORIZER_MURDER; + return WEAPON_VAPORIZER_MURDER; } #endif @@ -367,24 +384,26 @@ METHOD(Vaporizer, wr_impacteffect, void(entity thiswep, entity actor)) if(!w_issilent) sound(actor, CH_SHOTS, SND_NEXIMPACT, VOL_BASE, ATTN_NORM); } + METHOD(Vaporizer, wr_init, void(entity thiswep)) { - if(autocvar_cl_reticle && autocvar_cl_reticle_weapon) - { - precache_pic("gfx/reticle_nex"); - } + if(autocvar_cl_reticle && autocvar_cl_reticle_weapon) + { + precache_pic("gfx/reticle_nex"); + } } + METHOD(Vaporizer, wr_zoom, bool(entity thiswep, entity actor)) { - if(button_zoom || zoomscript_caught) - { - return true; - } - else - { - // no weapon specific image for this weapon - return false; - } + if(button_zoom || zoomscript_caught) + { + return true; + } + else + { + // no weapon specific image for this weapon + return false; + } } #endif diff --git a/qcsrc/common/weapons/weapon/vortex.qh b/qcsrc/common/weapons/weapon/vortex.qh index b31836e69..9914e3a7a 100644 --- a/qcsrc/common/weapons/weapon/vortex.qh +++ b/qcsrc/common/weapons/weapon/vortex.qh @@ -51,15 +51,15 @@ CLASS(Vortex, Weapon) P(class, prefix, refire, float, BOTH) \ P(class, prefix, secondary, float, NONE) \ P(class, prefix, reload_ammo, float, NONE) \ - P(class, prefix, reload_time, float, NONE) \ - P(class, prefix, switchdelay_raise, float, NONE) \ - P(class, prefix, switchdelay_drop, float, NONE) \ - P(class, prefix, weaponreplace, string, NONE) \ - P(class, prefix, weaponstart, float, NONE) \ - P(class, prefix, weaponstartoverride, float, NONE) \ - P(class, prefix, weaponthrowable, float, NONE) \ + P(class, prefix, reload_time, float, NONE) \ + P(class, prefix, switchdelay_raise, float, NONE) \ + P(class, prefix, switchdelay_drop, float, NONE) \ + P(class, prefix, weaponreplace, string, NONE) \ + P(class, prefix, weaponstart, float, NONE) \ + P(class, prefix, weaponstartoverride, float, NONE) \ + P(class, prefix, weaponthrowable, float, NONE) \ END() - W_PROPS(X, Vortex, vortex) + W_PROPS(X, Vortex, vortex) #undef X ENDCLASS(Vortex)