From: LegendaryGuard Date: Mon, 10 Jul 2023 14:36:40 +0000 (+0200) Subject: Merge branch 'master' into LegendaryGuard/tandem_nade X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=a180d6627edb2b0060f2c44d842421d711cc278a;p=xonotic%2Fxonotic-data.pk3dir.git Merge branch 'master' into LegendaryGuard/tandem_nade --- a180d6627edb2b0060f2c44d842421d711cc278a diff --cc mutators.cfg index ce0f79821,d0337c22d..30ca61014 --- a/mutators.cfg +++ b/mutators.cfg @@@ -202,12 -204,11 +204,12 @@@ set g_nades_nade_edgedamage 9 set g_nades_nade_radius 300 set g_nades_nade_force 650 set g_nades_nade_newton_style 0 "nade velocity: 0 is absolute, 1 is relative (takes into account player velocity), 2 is something in between" - set g_nades_nade_type 1 "Type of the off-hand grenade. 1:normal 2:napalm 3:ice 4:translocate 5:spawn 6:heal 7:pokenade 8:entrap 9:veil, 10:ammo, 11:dark" + set g_nades_nade_type 1 "Type of the off-hand grenade. 1:normal 2:napalm 3:ice 4:translocate 5:spawn 6:heal 7:pokenade 8:entrap 9:veil, 10:ammo, 11:darkness" seta cl_nade_timer 1 "show a visual timer for nades, 1 = only circle, 2 = circle with text" - seta cl_nade_type 3 - seta cl_pokenade_type "zombie" "monster, item, vehicle and turret to spawn" + seta cl_nade_type 3 "selected type of the off-hand grenade. 1:normal 2:napalm 3:ice 4:translocate 5:spawn 6:heal 7:pokenade 8:entrap 9:veil 10:ammo 11:dark" + seta cl_pokenade_type "zombie" "monster to spawn" +seta cl_tandemnade_type 0 "tandem nade selection; 0: monster, 1: item, 2: vehicle, 3: turret" // ------------ // Nade bonus @@@ -260,14 -261,17 +262,20 @@@ set g_nades_ice 1 "Ice nade: freezes an set g_nades_ice_freeze_time 3 "How long the ice field will last" set g_nades_ice_health 0 "How much health the player will have after being unfrozen" set g_nades_ice_explode 0 "Whether the ice nade should explode again once the ice field dissipated" - set g_nades_ice_teamcheck 0 "Don't freeze teammates" + set g_nades_ice_teamcheck 2 "0: friendly fire, 1: nade owner isn't affected, 2: don't freeze teammates" + + // Translocate (4) + set g_nades_translocate 1 "Translocate nade: teleports into explosion nade location" + set g_nades_translocate_destroy_damage 25 "Damage caused when translocate nade is destroyed by some attacker" +// Translocate (4) +set g_nades_translocate 1 "Translocate nade: teleports into explosion nade location" + // Spawn (5) - set g_nades_spawntype 1 "Spawn nade: respawns into nade explosion location after being fragged" + set g_nades_spawn 1 "Spawn nade: respawns into nade explosion location after being fragged" set g_nades_spawn_count 3 "Number of times player will spawn at their spawn nade explosion location" + set g_nades_spawn_health_respawn 0 "How much health the player will have when being respawned, if 0, normal health respawn" + set g_nades_spawn_destroy_damage 25 "Damage caused when spawn nade is destroyed by some attacker" // Heal (6) set g_nades_heal 1 "Heal nade: spawns a orb to recover health inside, enemies take the reverse effect when being inside orb" diff --cc notifications.cfg index 4ede8914f,22a4e70a3..08f4a7622 --- a/notifications.cfg +++ b/notifications.cfg @@@ -539,8 -554,9 +554,10 @@@ seta notification_CENTER_VEHICLE_ENTER seta notification_CENTER_VEHICLE_ENTER_GUNNER "1" "0 = off, 1 = centerprint" seta notification_CENTER_VEHICLE_ENTER_STEAL "1" "0 = off, 1 = centerprint" seta notification_CENTER_VEHICLE_STEAL "1" "0 = off, 1 = centerprint" +seta notification_CENTER_VEHICLE_STEAL_OWNER "1" "0 = off, 1 = centerprint" seta notification_CENTER_VEHICLE_STEAL_SELF "1" "0 = off, 1 = centerprint" + seta notification_CENTER_VOTEBAN "1" "0 = off, 1 = centerprint" + seta notification_CENTER_VOTEBANYN "1" "0 = off, 1 = centerprint" seta notification_CENTER_WEAPON_MINELAYER_LIMIT "1" "0 = off, 1 = centerprint" // MSG_MULTI notifications: diff --cc qcsrc/common/mutators/mutator/nades/nades.qc index 4a949a1b0,272da5677..88431410c --- a/qcsrc/common/mutators/mutator/nades/nades.qc +++ b/qcsrc/common/mutators/mutator/nades/nades.qc @@@ -152,8 -188,7 +189,9 @@@ void DrawAmmoNades(vector myPos, vecto #include #include #include +#include +#include + #include .float nade_time_primed; .float nade_lifetime; @@@ -639,377 -692,20 +694,377 @@@ void nade_heal_boom(entity this settouch(orb, nade_heal_touch); orb.colormod = '1 0 0'; } +void nade_tandem_randomweapon(entity e, vector org) +{ + RandomSelection_Init(); + FOREACH(Weapons, + it != WEP_Null + && (!((it.spawnflags & WEP_FLAG_HIDDEN) + || (it.spawnflags & WEP_FLAG_MUTATORBLOCKED) + || (it.spawnflags & WEP_FLAG_SPECIALATTACK) + || (it.spawnflags & WEP_FLAG_SUPERWEAPON)) + || autocvar_g_nades_tandem_randomweapon_includespecial), + { + if((it.spawnflags & WEP_FLAG_HIDDEN) + && (it.spawnflags & WEP_FLAG_MUTATORBLOCKED)) + continue; + if(it.spawnflags & WEP_FLAG_MUTATORBLOCKED) continue; + if(it.spawnflags & WEP_FLAG_SPECIALATTACK) continue; + if(it.spawnflags & WEP_TYPE_OTHER) continue; + if (W_IsWeaponThrowable(e, it.m_id)) + RandomSelection_AddEnt(it, 1, 1); + }); + - Item_SetLoot(e, true); ++ ITEM_SET_LOOT(e, true); + e.pickup_anyway = true; + e.angles = '0 0 0'; + e.gravity = 1; + setorigin(e, org); + e.velocity = randomvec() * 150 + '0 0 325'; + e.spawnfunc_checked = true; + e.glowmod = weaponentity_glowmod(RandomSelection_chosen_ent, 0, e); + weapon_defaultspawnfunc(e, RandomSelection_chosen_ent); +} + +entity nade_tandem_randomitem() +{ + RandomSelection_Init(); + FOREACH(Items, + it != NULL + && (!(it.spawnflags & ITEM_FLAG_MUTATORBLOCKED) + && !(it.m_itemid & IT_JETPACK) + && !(it.m_itemid & IT_FUEL_REGEN) + && !(it.m_itemid & IT_STRENGTH) + && !(it.m_itemid & IT_INVINCIBLE) + && !(it.m_itemid & IT_INVISIBILITY) + && !(it.m_itemid & IT_SPEED) + || autocvar_g_nades_tandem_item_includespecial), + { + if(it.m_canonical_spawnfunc == "item_armor_mega" + || it.m_canonical_spawnfunc == "item_health_mega" + || it.m_canonical_spawnfunc == "item_armor_big" + || it.m_canonical_spawnfunc == "item_health_big" + || it.m_canonical_spawnfunc == "item_armor_medium" + || it.m_canonical_spawnfunc == "item_health_medium" + || it.m_canonical_spawnfunc == "item_extralife" + || (it.spawnflags & ITEM_FLAG_MUTATORBLOCKED)) + continue; + RandomSelection_AddEnt(it, 1, 1); + }); + + return RandomSelection_chosen_ent; +} + +void nade_tandem_spawnitem(entity e, vector org) +{ + entity itm; + + switch (e.pokenade_type) + { + case "health": { itm = ITEM_HealthSmall; break; } + case "armor" : { itm = ITEM_ArmorSmall; break; } + case "ammo" : + { + itm = (random() > 0.5) ? + ITEM_Shells : (random() > 0.5) ? + ITEM_Bullets : (random() > 0.5) ? + ITEM_Rockets : ITEM_Plasma; + break; + } + case "jetpack": + { + itm = (!autocvar_g_nades_tandem_item_includespecial) ? + ITEM_JetpackFuel : (random() < 0.5) ? + ITEM_JetpackFuel : ITEM_Jetpack; + break; + } + default: { itm = nade_tandem_randomitem(); break; } + } + + if((IS_GAMETYPE(FREEZETAG) || IS_GAMETYPE(LMS)) + && (itm != ITEM_ArmorSmall || itm != ITEM_HealthSmall)) + { + // Non-regular items can't be spawned on survival-type gamemodes + itm = (random() > 0.5) ? ITEM_ArmorSmall : ITEM_HealthSmall; + } + + // item setup - Item_SetLoot(e, true); ++ ITEM_SET_LOOT(e, true); + e.reset = SUB_Remove; + e.noalign = true; + StartItem(e, itm); + e.gravity = 1; + setorigin(e, org); + e.velocity = randomvec() * 175 + '0 0 325'; + e.item_spawnshieldtime = time + 0.7; + SUB_SetFade(e, time + autocvar_g_nades_tandem_item_lifetime, 1); +} + +void nade_tandem_dropping(entity this, vector org) +{ + entity e = spawn(); + e.spawnfunc_checked = true; + e.pokenade_type = this.pokenade_type; + + // Items can't be spawned on CA and Instagib + if(!IS_GAMETYPE(CA) && !autocvar_g_instagib) + { + switch (this.pokenade_type) + { + case "weapon" : + { + if (autocvar_g_nades_tandem_includespecial) + { + nade_tandem_randomweapon(e, org); + return; + } + } + case "health" : + case "armor" : + case "ammo" : + case "jetpack" : + default : { nade_tandem_spawnitem(e, org); return; } + } + } +} + +void tandem_ball_think(entity this) +{ + if(round_handler_IsActive()) + if(!round_handler_IsRoundStarted()) + { + delete(this); + return; + } + + if(time > this.pushltime) + { + delete(this); + return; + } + + vector midpoint = ((this.absmin + this.absmax) * 0.5); + if(pointcontents(midpoint) == CONTENT_WATER) + { + this.velocity = this.velocity * 0.5; + + if(pointcontents(midpoint + '0 0 16') == CONTENT_WATER) + this.velocity_z = 200; + } + + this.angles = vectoangles(this.velocity); + + if (this.nade_item_spawncount < autocvar_g_nades_tandem_ball_item_spawncount) + { + this.nade_item_spawncount++; + nade_tandem_dropping(this, this.origin); + } + + this.nextthink = time + 0.1; +} + +void nade_tandem_ball(entity this) +{ + entity proj; + vector kick; + + spamsound(this, CH_SHOTS, SND_FIREBALL_FIRE, VOL_BASE, ATTEN_NORM); + + proj = new(grenade); + proj.bot_dodge = true; + proj.pokenade_type = this.pokenade_type; + set_movetype(proj, MOVETYPE_BOUNCE); + setmodel(proj, MDL_Null); + proj.scale = 1; //0.5; + setsize(proj, '-4 -4 -4', '4 4 4'); + setorigin(proj, this.origin); + setthink(proj, tandem_ball_think); + proj.nextthink = time; + proj.effects = EF_LOWPRECISION; + + kick.x =(random() - 0.5) * 2 * autocvar_g_nades_tandem_ball_spread; + kick.y = (random() - 0.5) * 2 * autocvar_g_nades_tandem_ball_spread; + kick.z = (random() / 2 + 0.5) * autocvar_g_nades_tandem_ball_spread; + proj.velocity = kick; + + proj.pushltime = time + autocvar_g_nades_tandem_ball_lifetime; + + proj.angles = vectoangles(proj.velocity); + proj.flags = FL_PROJECTILE; + IL_PUSH(g_projectiles, proj); + IL_PUSH(g_bot_dodge, proj); + proj.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_ARC; +} -void nade_monster_boom(entity this) +void tandem_fountain_think(entity this) { - if(!autocvar_g_monsters) + if(round_handler_IsActive()) + if(!round_handler_IsRoundStarted()) + { + delete(this); + return; + } + + if(time >= this.ltime) + { + Send_Effect(EFFECT_SMOKE_SMALL, this.origin + '0 0 1', '0 0 0', 1); + sound(this, CH_SHOTS, SND_ROCKET_IMPACT, VOL_BASE, ATTEN_NORM); + + delete(this); return; + } + + vector midpoint = ((this.absmin + this.absmax) * 0.5); + if(pointcontents(midpoint) == CONTENT_WATER) + { + this.velocity = this.velocity * 0.5; + + if(pointcontents(midpoint + '0 0 16') == CONTENT_WATER) + this.velocity_z = 200; + + UpdateCSQCProjectile(this); + } + + this.nextthink = time + 0.1; + if(time >= this.nade_special_time) + { + this.nade_special_time = time + autocvar_g_nades_tandem_fountain_delay; + nade_tandem_ball(this); + Send_Effect(EFFECT_SMOKE_LARGE, this.origin, '0 0 0', 1); + } +} + +void tandem_item_fountain_explode(entity this) +{ + entity fountain = new(nade_tandem_fountain); + fountain.owner = this.owner; + fountain.realowner = this.realowner; + fountain.origin = this.origin; + fountain.pokenade_type = this.pokenade_type; + fountain.flags = FL_PROJECTILE; + IL_PUSH(g_projectiles, fountain); + IL_PUSH(g_bot_dodge, fountain); + setorigin(fountain, fountain.origin); + setthink(fountain, tandem_fountain_think); + fountain.nextthink = time; + fountain.ltime = time + autocvar_g_nades_tandem_fountain_lifetime; + fountain.pushltime = fountain.ltime; + fountain.team = this.team; + + //nade model maintaining + setmodel(fountain, MDL_PROJECTILE_GRENADE); + entity timer = new(nade_timer); + setmodel(timer, MDL_NADE_TIMER); + setattachment(timer, fountain, ""); + timer.colormap = this.colormap; + timer.glowmod = this.glowmod; + setthink(timer, nade_timer_think); + timer.nextthink = time; + timer.wait = fountain.ltime; + timer.owner = fountain; + timer.skin = 10; + + set_movetype(fountain, MOVETYPE_TOSS); + fountain.bot_dodge = true; + fountain.nade_special_time = time; + setsize(fountain, '-16 -16 -16', '16 16 16'); + CSQCProjectile(fountain, true, PROJECTILE_NADE_TANDEM_BURN, true); +} + +void nade_tandem_boom(entity this) +{ entity e = spawn(); e.noalign = true; // don't drop to floor - e = spawnmonster(e, this.pokenade_type, MON_Null, this.realowner, this.realowner, this.origin, false, false, 1); - if(!e) - return; // monster failed to be spawned + e.gravity = 1; + + this.nade_item_spawncount = 0; + + int tandemnade_type_select = (autocvar_g_nades_tandem_includespecial) ? + this.tandemnade_type : 1; - if(autocvar_g_nades_pokenade_monster_lifetime > 0) - e.monster_lifetime = time + autocvar_g_nades_pokenade_monster_lifetime; - e.monster_skill = MONSTER_SKILL_INSANE; + switch (tandemnade_type_select) + { + case 1: + { + tandem_item_fountain_explode(this); + return; + } + case 2: + { + if(!autocvar_g_vehicles) + return; + + e = spawnvehicle( + e, + this.pokenade_type, + VEH_Null, + this.realowner, + this.realowner, + this.origin, + true, + false, + true, + false + ); + + if(!e) + return; // vehicle failed to be spawned + + if(autocvar_g_nades_pokenade_vehicle_lifetime > 0) + e.vehicle_lifetime = time + autocvar_g_nades_pokenade_vehicle_lifetime; + return; + } + case 3: + { + if(!autocvar_g_turrets) + return; + + e = spawnturret( + e, + this.pokenade_type, + TUR_Null, + this.realowner, + this.realowner, + this.origin, + false, + false, + false, + 1, + true + ); + + if(!e) + return; // turret failed to be spawned + + if(autocvar_g_nades_pokenade_turret_lifetime > 0) + e.turret_lifetime = time + autocvar_g_nades_pokenade_turret_lifetime; + return; + } + default: + { + if(!autocvar_g_monsters) + return; + + e = spawnmonster( + e, + this.pokenade_type, + MON_Null, + this.realowner, + this.realowner, + this.origin, + false, + false, + 1 + ); + + if(!e) + return; // monster failed to be spawned + + if(autocvar_g_nades_pokenade_monster_lifetime > 0) + e.monster_lifetime = time + autocvar_g_nades_pokenade_monster_lifetime; + e.monster_skill = MONSTER_SKILL_INSANE; + } + } } void nade_veil_touch(entity this, entity toucher) @@@ -1245,81 -927,36 +1286,36 @@@ void nade_boom(entity this entity expef = NULL; bool nade_blast = true; - switch ( REGISTRY_GET(Nades, STAT(NADE_BONUS_TYPE, this)) ) - { - case NADE_TYPE_NAPALM: - nade_blast = autocvar_g_nades_napalm_blast; - expef = EFFECT_EXPLOSION_MEDIUM; - break; - - case NADE_TYPE_ICE: - nade_blast = false; - expef = EFFECT_ELECTRO_COMBO; // hookbomb_explode electro_combo bigplasma_impact - break; - - case NADE_TYPE_TRANSLOCATE: - nade_blast = false; - break; - - case NADE_TYPE_TANDEM: - if(!autocvar_g_monsters) - { - expef = EFFECT_NADE_EXPLODE(this.realowner.team); - break; // fall back to a standard nade explosion - } - if(!autocvar_g_vehicles) - { - expef = EFFECT_NADE_EXPLODE(this.realowner.team); - break; // fall back to a standard nade explosion - } - if(!autocvar_g_turrets) - { - expef = EFFECT_NADE_EXPLODE(this.realowner.team); - break; // fall back to a standard nade explosion - } - - case NADE_TYPE_SPAWN: - nade_blast = false; - switch(this.realowner.team) - { - case NUM_TEAM_1: expef = EFFECT_SPAWN_RED; break; - case NUM_TEAM_2: expef = EFFECT_SPAWN_BLUE; break; - case NUM_TEAM_3: expef = EFFECT_SPAWN_YELLOW; break; - case NUM_TEAM_4: expef = EFFECT_SPAWN_PINK; break; - default: expef = EFFECT_SPAWN_NEUTRAL; break; - } - break; - - case NADE_TYPE_HEAL: - nade_blast = false; - expef = EFFECT_SPAWN_RED; - break; - - case NADE_TYPE_ENTRAP: - nade_blast = false; - expef = EFFECT_SPAWN_YELLOW; - break; - - case NADE_TYPE_VEIL: - nade_blast = false; - expef = EFFECT_SPAWN_NEUTRAL; - break; - - case NADE_TYPE_AMMO: - nade_blast = false; - expef = EFFECT_SPAWN_BROWN; - break; + #define GET_NADE_TYPE_SPAWN_EFFECT(team_owner) \ + ((team_owner) == NUM_TEAM_1 ? EFFECT_SPAWN_RED : \ + ((team_owner) == NUM_TEAM_2 ? EFFECT_SPAWN_BLUE : \ + ((team_owner) == NUM_TEAM_3 ? EFFECT_SPAWN_YELLOW : \ + ((team_owner) == NUM_TEAM_4 ? EFFECT_SPAWN_PINK : \ + EFFECT_SPAWN_NEUTRAL)))) - case NADE_TYPE_DARK: - nade_blast = false; - expef = EFFECT_EXPLOSION_MEDIUM; - break; + #define SET_NADE_EFFECT(nade_type, blast, exp_effect) \ + case nade_type: \ + nade_blast = blast; \ + expef = exp_effect; \ - break; ++ break - default: - case NADE_TYPE_NORMAL: - expef = EFFECT_NADE_EXPLODE(this.realowner.team); - break; - } + switch ( REGISTRY_GET(Nades, STAT(NADE_BONUS_TYPE, this)) ) + { + SET_NADE_EFFECT(NADE_TYPE_NAPALM, autocvar_g_nades_napalm_blast, EFFECT_EXPLOSION_MEDIUM); + SET_NADE_EFFECT(NADE_TYPE_ICE, false, EFFECT_ELECTRO_COMBO /* hookbomb_explode electro_combo bigplasma_impact */); + SET_NADE_EFFECT(NADE_TYPE_TRANSLOCATE, false, NULL); - SET_NADE_EFFECT(NADE_TYPE_MONSTER, true, (!autocvar_g_monsters) ? EFFECT_NADE_EXPLODE(this.realowner.team) : NULL); ++ SET_NADE_EFFECT(NADE_TYPE_TANDEM, true, (!autocvar_g_monsters && !autocvar_g_turrets && !autocvar_g_vehicles) ? EFFECT_NADE_EXPLODE(this.realowner.team) : NULL); + SET_NADE_EFFECT(NADE_TYPE_SPAWN, false, GET_NADE_TYPE_SPAWN_EFFECT(this.realowner.team)); + SET_NADE_EFFECT(NADE_TYPE_HEAL, false, EFFECT_SPAWN_RED); + SET_NADE_EFFECT(NADE_TYPE_ENTRAP, false, EFFECT_SPAWN_YELLOW); + SET_NADE_EFFECT(NADE_TYPE_VEIL, false, EFFECT_SPAWN_NEUTRAL); + SET_NADE_EFFECT(NADE_TYPE_AMMO, false, EFFECT_SPAWN_BROWN); + SET_NADE_EFFECT(NADE_TYPE_DARK, false, EFFECT_EXPLOSION_MEDIUM); + SET_NADE_EFFECT(NADE_TYPE_NORMAL, true, EFFECT_NADE_EXPLODE(this.realowner.team)); + default: expef = EFFECT_NADE_EXPLODE(this.realowner.team); break; + } + #undef GET_NADE_TYPE_SPAWN_EFFECT + #undef SET_NADE_EFFECT if(expef) Send_Effect(expef, findbetterlocation(this.origin, 8), '0 0 0', 1); @@@ -1335,16 -972,16 +1331,16 @@@ if(this.takedamage) switch ( REGISTRY_GET(Nades, STAT(NADE_BONUS_TYPE, this)) ) { - case NADE_TYPE_NAPALM: nade_napalm_boom(this); break; - case NADE_TYPE_ICE: nade_ice_boom(this); break; - case NADE_TYPE_TRANSLOCATE: nade_translocate_boom(this); break; - case NADE_TYPE_SPAWN: nade_spawn_boom(this); break; - case NADE_TYPE_HEAL: nade_heal_boom(this); break; - case NADE_TYPE_TANDEM: nade_tandem_boom(this); break; - case NADE_TYPE_ENTRAP: nade_entrap_boom(this); break; - case NADE_TYPE_VEIL: nade_veil_boom(this); break; - case NADE_TYPE_AMMO: nade_ammo_boom(this); break; - case NADE_TYPE_DARK: nade_dark_boom(this); break; + case NADE_TYPE_NAPALM: nade_napalm_boom(this); break; + case NADE_TYPE_ICE: nade_ice_boom(this); break; + case NADE_TYPE_TRANSLOCATE: nade_translocate_boom(this); break; + case NADE_TYPE_SPAWN: nade_spawn_boom(this); break; + case NADE_TYPE_HEAL: nade_heal_boom(this); break; - case NADE_TYPE_MONSTER: nade_monster_boom(this); break; ++ case NADE_TYPE_TANDEM: nade_tandem_boom(this); break; + case NADE_TYPE_ENTRAP: nade_entrap_boom(this); break; + case NADE_TYPE_VEIL: nade_veil_boom(this); break; + case NADE_TYPE_AMMO: nade_ammo_boom(this); break; - case NADE_TYPE_DARK: nade_darkness_boom(this); break; ++ case NADE_TYPE_DARK: nade_darkness_boom(this); break; } IL_EACH(g_projectiles, it.classname == "grapplinghook" && it.aiment == this, @@@ -1721,11 -1368,10 +1730,11 @@@ void nade_prime(entity this else { ntype = ((autocvar_g_nades_client_select) ? CS_CVAR(this).cvar_cl_nade_type : autocvar_g_nades_nade_type); - pntype = ((autocvar_g_nades_client_select) ? CS_CVAR(this).cvar_cl_pokenade_type : autocvar_g_nades_pokenade_type); + pntype = ((autocvar_g_nades_client_select) ? CS_CVAR(this).cvar_cl_pokenade_type : autocvar_g_nades_pokenade_monster_type); + tntype = ((autocvar_g_nades_client_select) ? CS_CVAR(this).cvar_cl_tandemnade_type : autocvar_g_nades_tandemnade_type); } - spawn_held_nade(this, this, autocvar_g_nades_nade_lifetime, ntype, pntype); + spawn_held_nade(this, this, autocvar_g_nades_nade_lifetime, ntype, pntype, tntype); } bool CanThrowNade(entity this) @@@ -1776,23 -1422,28 +1785,28 @@@ void nades_Clear(entity player STAT(NADE_TIMER, player) = 0; } - void nades_CheckTypes(entity player) + int nades_CheckTypes(entity player, int cl_ntype) { - int cl_ntype = CS_CVAR(player).cvar_cl_nade_type; + #define CL_NADE_TYPE_CHECK(cl_ntype, cvar) \ + case cl_ntype.m_id: \ + if (!cvar) return NADE_TYPE_NORMAL.m_id; \ + break + switch (cl_ntype) { - case NADE_TYPE_NAPALM.m_id: if (!autocvar_g_nades_napalm) cl_ntype = NADE_TYPE_NORMAL.m_id; break; - case NADE_TYPE_ICE.m_id: if (!autocvar_g_nades_ice) cl_ntype = NADE_TYPE_NORMAL.m_id; break; - case NADE_TYPE_TRANSLOCATE.m_id: if (!autocvar_g_nades_translocate) cl_ntype = NADE_TYPE_NORMAL.m_id; break; - case NADE_TYPE_SPAWN.m_id: if (!autocvar_g_nades_spawntype) cl_ntype = NADE_TYPE_NORMAL.m_id; break; - case NADE_TYPE_HEAL.m_id: if (!autocvar_g_nades_heal) cl_ntype = NADE_TYPE_NORMAL.m_id; break; - case NADE_TYPE_TANDEM.m_id: if (!autocvar_g_nades_tandem) cl_ntype = NADE_TYPE_NORMAL.m_id; break; - case NADE_TYPE_ENTRAP.m_id: if (!autocvar_g_nades_entrap) cl_ntype = NADE_TYPE_NORMAL.m_id; break; - case NADE_TYPE_VEIL.m_id: if (!autocvar_g_nades_veil) cl_ntype = NADE_TYPE_NORMAL.m_id; break; - case NADE_TYPE_AMMO.m_id: if (!autocvar_g_nades_ammo) cl_ntype = NADE_TYPE_NORMAL.m_id; break; - case NADE_TYPE_DARK.m_id: if (!autocvar_g_nades_dark) cl_ntype = NADE_TYPE_NORMAL.m_id; break; + CL_NADE_TYPE_CHECK(NADE_TYPE_NAPALM, autocvar_g_nades_napalm); + CL_NADE_TYPE_CHECK(NADE_TYPE_ICE, autocvar_g_nades_ice); + CL_NADE_TYPE_CHECK(NADE_TYPE_TRANSLOCATE, autocvar_g_nades_translocate); + CL_NADE_TYPE_CHECK(NADE_TYPE_SPAWN, autocvar_g_nades_spawn); + CL_NADE_TYPE_CHECK(NADE_TYPE_HEAL, autocvar_g_nades_heal); - CL_NADE_TYPE_CHECK(NADE_TYPE_MONSTER, autocvar_g_nades_pokenade); ++ CL_NADE_TYPE_CHECK(NADE_TYPE_TANDEM, autocvar_g_nades_tandem); + CL_NADE_TYPE_CHECK(NADE_TYPE_ENTRAP, autocvar_g_nades_entrap); + CL_NADE_TYPE_CHECK(NADE_TYPE_VEIL, autocvar_g_nades_veil); + CL_NADE_TYPE_CHECK(NADE_TYPE_AMMO, autocvar_g_nades_ammo); + CL_NADE_TYPE_CHECK(NADE_TYPE_DARK, autocvar_g_nades_darkness); } - STAT(NADE_BONUS_TYPE, player) = cl_ntype; + return cl_ntype; + #undef CL_NADE_TYPE_CHECK } MUTATOR_HOOKFUNCTION(nades, VehicleEnter) @@@ -1902,15 -1553,13 +1916,15 @@@ MUTATOR_HOOKFUNCTION(nades, PlayerPreTh if(autocvar_g_nades_bonus_client_select) { - nades_CheckTypes(player); + STAT(NADE_BONUS_TYPE, player) = nades_CheckTypes(player, CS_CVAR(player).cvar_cl_nade_type); player.pokenade_type = CS_CVAR(player).cvar_cl_pokenade_type; + player.tandemnade_type = CS_CVAR(player).cvar_cl_tandemnade_type; } else { STAT(NADE_BONUS_TYPE, player) = autocvar_g_nades_bonus_type; - player.pokenade_type = autocvar_g_nades_pokenade_type; + player.pokenade_type = autocvar_g_nades_pokenade_monster_type; + player.tandemnade_type = autocvar_g_nades_tandemnade_type; } STAT(NADE_BONUS_TYPE, player) = bound(1, STAT(NADE_BONUS_TYPE, player), Nades_COUNT); diff --cc qcsrc/common/mutators/mutator/nades/nades.qh index d5edba807,7888da7d1..e2abf7e1e --- a/qcsrc/common/mutators/mutator/nades/nades.qh +++ b/qcsrc/common/mutators/mutator/nades/nades.qh @@@ -86,15 -79,13 +89,15 @@@ float autocvar_g_nades_ammo_time float autocvar_g_nades_ammo_rate; float autocvar_g_nades_ammo_friend; float autocvar_g_nades_ammo_foe; - bool autocvar_g_nades_dark; - float autocvar_g_nades_dark_damage; - float autocvar_g_nades_dark_time; - float autocvar_g_nades_dark_radius; - string autocvar_g_nades_pokenade_type; + bool autocvar_g_nades_darkness; + bool autocvar_g_nades_darkness_explode; + bool autocvar_g_nades_darkness_teamcheck; + float autocvar_g_nades_darkness_time; -bool autocvar_g_nades_pokenade; + string autocvar_g_nades_pokenade_monster_type; +int autocvar_g_nades_tandemnade_type; float autocvar_g_nades_pokenade_monster_lifetime; +float autocvar_g_nades_pokenade_turret_lifetime; +float autocvar_g_nades_pokenade_vehicle_lifetime; #endif // use slots 70-100 @@@ -115,12 -106,10 +118,12 @@@ const int PROJECTILE_NADE_ENTRAP = 84 const int PROJECTILE_NADE_ENTRAP_BURN = 85; const int PROJECTILE_NADE_VEIL = 86; const int PROJECTILE_NADE_VEIL_BURN = 87; -const int PROJECTILE_NADE_AMMO = 88; -const int PROJECTILE_NADE_AMMO_BURN = 89; -const int PROJECTILE_NADE_DARKNESS = 90; -const int PROJECTILE_NADE_DARKNESS_BURN = 91; +const int PROJECTILE_NADE_EMERALD = 88; +const int PROJECTILE_NADE_EMERALD_BURN = 89; +const int PROJECTILE_NADE_AMMO = 90; +const int PROJECTILE_NADE_AMMO_BURN = 91; - const int PROJECTILE_NADE_DARK = 92; - const int PROJECTILE_NADE_DARK_BURN = 93; ++const int PROJECTILE_NADE_DARKNESS = 92; ++const int PROJECTILE_NADE_DARKNESS_BURN = 93; REGISTRY(Nades, BITS(4)) REGISTER_REGISTRY(Nades) diff --cc qcsrc/common/notifications/all.inc index d957d7bfd,aa6b4eb56..21e8a91f8 --- a/qcsrc/common/notifications/all.inc +++ b/qcsrc/common/notifications/all.inc @@@ -778,9 -804,11 +804,12 @@@ string multiteam_info_sprintf(string in MSG_CENTER_NOTIF(VEHICLE_ENTER_GUNNER, N_ENABLE, 0, 0, "pass_key", CPID_VEHICLES, "0 0", _("^BGPress ^F2%s^BG to enter the vehicle gunner"), "") MSG_CENTER_NOTIF(VEHICLE_ENTER_STEAL, N_ENABLE, 0, 0, "pass_key", CPID_VEHICLES, "0 0", _("^BGPress ^F2%s^BG to steal this vehicle"), "") MSG_CENTER_NOTIF(VEHICLE_STEAL, N_ENABLE, 0, 0, "", CPID_VEHICLES_OTHER, "0 0", _("^F2The enemy is stealing one of your vehicles!\n^F4Stop them!"), "") + MSG_CENTER_NOTIF(VEHICLE_STEAL_OWNER, N_ENABLE, 1, 0, "s1", CPID_VEHICLES_OTHER, "4 0", _("^F2Intruder detected, %s vehicle is being stolen,\n disabling shields!"), "") MSG_CENTER_NOTIF(VEHICLE_STEAL_SELF, N_ENABLE, 0, 0, "", CPID_VEHICLES_OTHER, "4 0", _("^F2Intruder detected, disabling shields!"), "") + MSG_CENTER_NOTIF(VOTEBAN, N_ENABLE, 0, 0, "", CPID_Null, "0 0", BOLD(_("^K1You aren't allowed to call a vote because you are banned in this server")), "") + MSG_CENTER_NOTIF(VOTEBANYN, N_ENABLE, 0, 0, "", CPID_Null, "0 0", BOLD(_("^K1You aren't allowed to vote because you are banned in this server")), "") + MSG_CENTER_NOTIF(WEAPON_MINELAYER_LIMIT, N_ENABLE, 0, 1, "f1", CPID_Null, "0 0", _("^BGYou cannot place more than ^F2%s^BG mines at a time"), "") #undef N_DISABL