#include <common/effects/all.qh>
+//LegendGuard adds purple nade parts 08-02-2021
+//LegendGuard adds green nade parts 11-02-2021
EFFECT(0, NADE_EXPLODE_RED, "nade_red_explode")
EFFECT(0, NADE_EXPLODE_BLUE, "nade_blue_explode")
EFFECT(0, NADE_EXPLODE_YELLOW, "nade_yellow_explode")
EFFECT(0, NADE_EXPLODE_PINK, "nade_pink_explode")
EFFECT(0, NADE_EXPLODE_NEUTRAL, "nade_neutral_explode")
+EFFECT(0, NADE_EXPLODE_GREEN, "nade_green_explode")
+EFFECT(0, NADE_EXPLODE_PURPLE, "nade_purple_explode")
+
entity EFFECT_NADE_EXPLODE(int teamid)
{
switch (teamid) {
EFFECT(1, NADE_TRAIL_YELLOW, "nade_yellow")
EFFECT(1, NADE_TRAIL_PINK, "nade_pink")
EFFECT(1, NADE_TRAIL_NEUTRAL, "nade_neutral")
+EFFECT(1, NADE_TRAIL_GREEN, "nade_green")
+EFFECT(1, NADE_TRAIL_PURPLE, "nade_purple")
entity EFFECT_NADE_TRAIL(int teamid)
{
switch (teamid) {
EFFECT(1, NADE_TRAIL_BURN_YELLOW, "nade_yellow_burn")
EFFECT(1, NADE_TRAIL_BURN_PINK, "nade_pink_burn")
EFFECT(1, NADE_TRAIL_BURN_NEUTRAL, "nade_neutral_burn")
+EFFECT(1, NADE_TRAIL_BURN_GREEN, "nade_green_burn")
+EFFECT(1, NADE_TRAIL_BURN_PURPLE, "nade_purple_burn")
entity EFFECT_NADE_TRAIL_BURN(int teamid)
{
switch (teamid) {
NADE_PROJECTILE(1, PROJECTILE_NADE_VEIL_BURN, EFFECT_NADE_TRAIL_BURN_NEUTRAL);
#endif
}
+
+//LegendGuard writes Armorize nade code 11-02-2021
+REGISTER_NADE(ARMORIZE) {
+ this.m_color = '0.33 1 0.66';
+ this.m_name = _("Armorize grenade");
+ this.m_icon = "nade_armorize";
+#ifdef GAMEQC
+ NADE_PROJECTILE(0, PROJECTILE_NADE_ARMORIZE, EFFECT_NADE_TRAIL_GREEN);
+ NADE_PROJECTILE(1, PROJECTILE_NADE_ARMORIZE_BURN, EFFECT_NADE_TRAIL_BURN_GREEN);
+#endif
+}
+
+//LegendGuard writes Dark nade code 08-02-2021
+REGISTER_NADE(DARK) {
+ this.m_color = '0.23 0 0.23';
+ this.m_name = _("Dark grenade");
+ this.m_icon = "nade_dark";
+#ifdef GAMEQC
+ NADE_PROJECTILE(0, PROJECTILE_NADE_DARK, EFFECT_NADE_TRAIL_PURPLE);
+ NADE_PROJECTILE(1, PROJECTILE_NADE_DARK_BURN, EFFECT_NADE_TRAIL_BURN_PURPLE);
+#endif
+}
\ No newline at end of file
M_ARGV(1, float) = STAT(VEIL_ORB_ALPHA);
return true;
}
+ if (STAT(ARMORIZING_ORB) > time) //LegendGuard adds new nade STAT ORB (keep in mind: qcsrc/common/stats.qh) 11-02-2021
+ {
+ M_ARGV(0, vector) = NADE_TYPE_ARMORIZE.m_color;
+ M_ARGV(1, float) = STAT(ARMORIZING_ORB_ALPHA);
+ return true;
+ }
+ if (STAT(DARK_ORB) > time) //LegendGuard adds new nade STAT ORB (keep in mind: qcsrc/common/stats.qh) 08-02-2021
+ {
+ M_ARGV(0, vector) = NADE_TYPE_DARK.m_color;
+ M_ARGV(1, float) = STAT(DARK_ORB_ALPHA);
+ return true;
+ }
return false;
}
MUTATOR_HOOKFUNCTION(cl_nades, Ent_Projectile)
settouch(orb, nade_veil_touch);
orb.colormod = NADE_TYPE_VEIL.m_color;
}
+/**************LEGENDGUARD NEW NADES: ARMORIZE AND DARK NADES functions "cl_nade_type 10" and "cl_nade_type 11" *** //more ideas: BLOCKING NADE ***********************/
+void nade_armorize_touch(entity this, entity toucher)
+{
+ float maxarmor;
+ float maxhealth;
+ float armor_factor;
+ float health_foemantain;
+ float health_maintaining = 1;
+ if(IS_PLAYER(toucher) || IS_MONSTER(toucher))
+ if(!IS_DEAD(toucher))
+ if(!STAT(FROZEN, toucher))
+ {
+ armor_factor = autocvar_g_nades_armorize_rate*frametime/2;
+ health_foemantain = autocvar_g_nades_armorize_rate*frametime/2;
+ if ( toucher != this.realowner )
+ {
+ if ( SAME_TEAM(toucher,this) )
+ {
+ armor_factor *= autocvar_g_nades_armorize_friend;
+ }
+ else
+ {
+ //maintain foe health and reduce armor
+ armor_factor *= autocvar_g_nades_armorize_foe;
+ if (autocvar_g_nades_armorize_friend > 1 || autocvar_g_nades_armorize_friend < 1)
+ health_foemantain *= health_maintaining;
+ else
+ health_foemantain *= autocvar_g_nades_armorize_friend;
+ }
+ }
+ if ( armor_factor > 0 )
+ {
+ maxarmor = 200;
+ float ar = GetResource(toucher, RES_ARMOR);
+ if (ar < maxarmor)
+ {
+ if (this.nade_show_particles)
+ {
+ Send_Effect(EFFECT_HEALING, toucher.origin, '0 0 0', 1);
+ }
+ GiveResourceWithLimit(toucher, RES_ARMOR, armor_factor, maxarmor);
+ }
+ }
+ else if ( armor_factor < 0 )
+ {
+ //Foe should drop only armor points
+ maxhealth = (IS_MONSTER(toucher)) ? toucher.max_health : g_pickup_healthmega_max;
+ float hp = GetResource(toucher, RES_HEALTH);
+ if (hp < maxhealth)
+ {
+ if ((GetResource(toucher, RES_ARMOR) <= 0) && (GetResource(toucher, RES_HEALTH) <= 9999))
+ return;
+ else
+ GiveResourceWithLimit(toucher, RES_HEALTH, health_foemantain/1.3, maxhealth);
+ Damage(toucher,this,this.realowner,-armor_factor,DEATH_NADE_HEAL.m_id,DMG_NOWEP,toucher.origin,'0 0 0');
+ }
+ }
+ }
+
+ if ( IS_REAL_CLIENT(toucher) || IS_VEHICLE(toucher) )
+ {
+ entity show_green = (IS_VEHICLE(toucher)) ? toucher.owner : toucher;
+ STAT(ARMORIZING_ORB, show_green) = time+0.1;
+ STAT(ARMORIZING_ORB_ALPHA, show_green) = 0.75 * (this.ltime - time) / this.orb_lifetime;
+ }
+}
+
+void nade_armorize_boom(entity this)
+{
+ entity orb = nades_spawn_orb(this.owner, this.realowner, this.origin, autocvar_g_nades_armorize_time, autocvar_g_nades_nade_radius);
+
+ settouch(orb, nade_armorize_touch);
+ orb.colormod = '0.33 1 0.66';
+}
+/***********************************************************************************/
+//remember to put an image in gfx/hud/luma and gfx/hud/default per each nade_blabla.tga
+//dark nade does damage like a normal nade but the damage is minor
+void dark_damage(entity this, float radius, float damage)
+{
+ entity e;
+
+ if ( damage < 0 )
+ return;
+
+ for(e = WarpZone_FindRadius(this.origin, radius, true); e; e = e.chain)
+ if(!IS_DEAD(e))
+ if(e.takedamage == DAMAGE_AIM)
+ if(!IS_PLAYER(e) || !this.realowner || DIFF_TEAM(e, this) || !IS_MONSTER(e))
+ if(!STAT(FROZEN, e))
+ {
+ RadiusDamage(this, this.realowner, damage, 0,
+ radius, this, NULL, 0, this.projectiledeathtype, DMG_NOWEP, this.enemy);
+ Damage_DamageInfo(this.origin, damage, 0,
+ radius, '1 1 1' * 0, this.projectiledeathtype, 0, this);
+ }
+}
+void DarkBlinking(entity e);
+//copy of the special.qc function contents for DarkBlinking
+void nade_dark_touch(entity this, entity toucher)
+{
+ if ( IS_REAL_CLIENT(toucher) || IS_VEHICLE(toucher) || IS_MONSTER(toucher) )
+ {
+ entity show_tint = (IS_VEHICLE(toucher)) ? toucher.owner : toucher;
+
+ float tint_alpha = 0.55;
+ if(SAME_TEAM(toucher, this.realowner) || SAME_TEAM(toucher, this))
+ {
+ tint_alpha = 0.25;
+ if(!STAT(DARK_ORB, show_tint))
+ {
+ toucher.nade_veil_prevalpha = toucher.alpha;
+ toucher.alpha = 1;
+ }
+ }
+ else
+ {
+ tint_alpha = 0.25;
+ if(!STAT(DARK_ORB, show_tint))
+ {
+ DarkBlinking(toucher);
+ dark_damage(this, autocvar_g_nades_dark_radius, autocvar_g_nades_dark_damage);
+ }
+ }
+ STAT(DARK_ORB, show_tint) = time + 0.1;
+ STAT(DARK_ORB_ALPHA, show_tint) = tint_alpha * (this.ltime - time) / this.orb_lifetime;
+ }
+}
+
+void nade_dark_boom(entity this)
+{
+ entity orb = nades_spawn_orb(this.owner, this.realowner, this.origin, autocvar_g_nades_dark_time, autocvar_g_nades_dark_radius);
+
+ settouch(orb, nade_dark_touch);
+ orb.colormod = NADE_TYPE_DARK.m_color;
+}
+/***********************************************************************************/
void nade_boom(entity this)
{
entity expef = NULL;
nade_blast = false;
expef = EFFECT_SPAWN_NEUTRAL;
break;
+
+ case NADE_TYPE_ARMORIZE: //LegendGuard adds nade case 11-02-2021
+ nade_blast = false;
+ expef = EFFECT_SPAWN_NEUTRAL;
+ break;
+
+ case NADE_TYPE_DARK: //LegendGuard adds nade case 08-02-2021
+ nade_blast = false;
+ expef = EFFECT_EXPLOSION_MEDIUM;
+ break;
default:
case NADE_TYPE_NORMAL:
case NADE_TYPE_MONSTER: nade_monster_boom(this); break;
case NADE_TYPE_ENTRAP: nade_entrap_boom(this); break;
case NADE_TYPE_VEIL: nade_veil_boom(this); break;
+ case NADE_TYPE_ARMORIZE: nade_armorize_boom(this); break; //LegendGuard adds the register of new nade 11-02-2021
+ case NADE_TYPE_DARK: nade_dark_boom(this); break; //LegendGuard adds the register of new nade 08-02-2021
}
IL_EACH(g_projectiles, it.classname == "grapplinghook" && it.aiment == this,
else
player.alpha = player.nade_veil_prevalpha;
}
+ //LegendGuard adds nade if STAT DARK_ORB 08-02-2021
+ if(STAT(DARK_ORB, player) && STAT(DARK_ORB, player) <= time)
+ {
+ STAT(DARK_ORB, player) = 0;
+ if(player.vehicle)
+ player.vehicle.alpha = player.vehicle.nade_dark_prevalpha;
+ else
+ player.alpha = player.nade_dark_prevalpha;
+ }
}
if (frametime && IS_PLAYER(player))
mon.alpha = mon.nade_veil_prevalpha;
STAT(VEIL_ORB, mon) = 0;
}
+ //LegendGuard adds nade if STAT ORB 08-02-2021
+ if (STAT(DARK_ORB, mon) && STAT(DARK_ORB, mon) <= time)
+ {
+ mon.alpha = mon.nade_dark_prevalpha;
+ STAT(DARK_ORB, mon) = 0;
+ }
}
MUTATOR_HOOKFUNCTION(nades, PlayerSpawn)
STAT(ENTRAP_ORB_ALPHA, client) = STAT(ENTRAP_ORB_ALPHA, spectatee);
STAT(VEIL_ORB, client) = STAT(VEIL_ORB, spectatee);
STAT(VEIL_ORB_ALPHA, client) = STAT(VEIL_ORB_ALPHA, spectatee);
+ STAT(ARMORIZING_ORB, client) = STAT(ARMORIZING_ORB, spectatee); //LegendGuard adds nade STAT client 11-02-2021
+ STAT(ARMORIZING_ORB_ALPHA, client) = STAT(ARMORIZING_ORB_ALPHA, spectatee);
+ STAT(DARK_ORB, client) = STAT(DARK_ORB, spectatee); //LegendGuard adds nade STAT client 08-02-2021
+ STAT(DARK_ORB_ALPHA, client) = STAT(DARK_ORB_ALPHA, spectatee);
}
MUTATOR_HOOKFUNCTION(nades, BuildMutatorsString)
float autocvar_g_nades_entrap_time = 10;
float autocvar_g_nades_veil_time = 8;
float autocvar_g_nades_veil_radius = 300;
+float autocvar_g_nades_armorize_time = 5; //LegendGuard adds new nade cvars 11-02-2021
+float autocvar_g_nades_armorize_rate = 30;
+float autocvar_g_nades_armorize_friend = 1;
+float autocvar_g_nades_armorize_foe = -2;
+float autocvar_g_nades_dark_damage = 25; //LegendGuard adds new nade cvars 08-02-2021
+float autocvar_g_nades_dark_time = 13;
+float autocvar_g_nades_dark_radius = 700;
string autocvar_g_nades_pokenade_monster_type;
float autocvar_g_nades_pokenade_monster_lifetime;
#endif
const int PROJECTILE_NADE_ENTRAP_BURN = 85;
const int PROJECTILE_NADE_VEIL = 86;
const int PROJECTILE_NADE_VEIL_BURN = 87;
+const int PROJECTILE_NADE_ARMORIZE = 88; //LegendGuard adds new nade MACROS 11-02-2021
+const int PROJECTILE_NADE_ARMORIZE_BURN = 89;
+const int PROJECTILE_NADE_DARK = 90; //LegendGuard adds new nade MACROS 08-02-2021
+const int PROJECTILE_NADE_DARK_BURN = 91;
REGISTRY(Nades, BITS(4))
REGISTER_REGISTRY(Nades)
.float toss_time;
.float nade_show_particles;
.float nade_veil_prevalpha;
+.float nade_dark_prevalpha; //LegendGuard adds new nade .variable 08-02-2021
bool orb_send(entity this, entity to, int sf);
#endif
+REGISTER_NET_TEMP(TE_CSQC_DARKBLINKING); //LegendGuard registers dark blinking nade feature 09-02-2021
+
#ifdef CSQC
float cvar_cl_nade_type;
string cvar_cl_pokenade_type;
+//LegendGuard sets variables for dark nade 09-02-2021
+float autocvar_hud_panel_darkradar_maximised_zoom_scale = 1;
+float dark_appeartime;
+float dark_fadetime;
+/***************************************************************/
+void HUD_DarkBlinking()
+{
+ // vectors for top right, bottom right, bottom and bottom left corners
+ //vector topright = vec2(vid_conwidth, 0);
+ //vector bottom = vec2(vid_conwidth / 2, vid_conheight);
+ vector bottomright = vec2(vid_conwidth, vid_conheight);
+ //vector bottomleft = vec2(0, vid_conheight);
+
+ /*
+ drawfill function parameters (qcsrc/dpdefs/menudefs.qc):
+ float drawfill(vector position, vector size, vector rgb, float alpha, float flag)
+ */
+ drawfill('0 0 0', bottomright, '0.23 0 0.23', 0.98, DRAWFLAG_NORMAL);
+}
+
+#elif defined(SVQC)
+void DarkBlinking(entity e)
+{
+ if(e == NULL)
+ return;
+
+ int accepted = VerifyClientEntity(e, true, false);
+
+ if(accepted > 0)
+ {
+ msg_entity = e;
+ WriteHeader(MSG_ONE, TE_CSQC_DARKBLINKING);
+ }
+}
+#endif
+
+#ifdef CSQC
+const int MAX_QUADRATIC2 = 25;
+vector quadratic2_slots[MAX_QUADRATIC2];
+vector quadratic2_dirs[MAX_QUADRATIC2];
+const float QUADRATIC2_SPEED = 150;
+const float QUADRATIC2_TURNSPEED = 0.35;
+const float QUADRATIC2_SIZE = 24;
+const float QUADRATIC2_CHANCE = 0.35;
+float quadratic2_spawntime, quadratic2_fadetime;
+bool quadratic2;
+void HUD_Quadratic2()
+{
+ for(int j = MAX_QUADRATIC2 - 1; j >= 0; --j)
+ {
+ vector slot = quadratic2_slots[j];
+ vector dirs = quadratic2_dirs[j];
+ float oldz = slot.z;
+ if(slot)
+ slot += quadratic2_dirs[j] * QUADRATIC2_SPEED * frametime;
+ slot.z = oldz;
+ //if(slot.z)
+ //slot.z = sin(QUADRATIC2_TURNSPEED * M_PI * time);
+ if(slot.y > vid_conheight || slot.x > vid_conwidth)
+ slot = '0 0 0';
+
+ if(slot == '0 0 0')
+ {
+ if(time > quadratic2_spawntime && random() <= QUADRATIC2_CHANCE) // low chance to spawn!
+ {
+ slot.x = bound(0, (random() * vid_conwidth + 1), vid_conwidth);
+ slot.y = bound(0, (random() * vid_conheight + 1), vid_conheight);
+ slot.z = 0;
+ dirs = vec2(randomvec());
+ quadratic2_spawntime = time + bound(0.05, random() * 0.5, 0.4); // prevent spawning another one for this amount of time!
+ }
+ }
+ else
+ {
+ vector splash_size = vec2(QUADRATIC2_SIZE, QUADRATIC2_SIZE);
+ if(time > dirs.z)
+ {
+ if(random() <= 0.05)
+ slot.z = -1;
+ else
+ slot.z = floor(random() * 9) + 1;
+ dirs.z = time + QUADRATIC2_TURNSPEED;
+ }
+ string chosen_number = ((slot.z == -1) ? "NOOB" : ftos(rint(slot.z)));
+ draw_beginBoldFont();
+ drawcolorcodedstring(vec2(slot), chosen_number, splash_size, 0.95, DRAWFLAG_NORMAL);
+ draw_endBoldFont();
+ }
+
+ quadratic2_slots[j] = slot;
+ quadratic2_dirs[j] = dirs;
+ }
+}
+
+bool darkblink;
+
+STATIC_INIT_LATE(cl_darkblink_override)
+{
+ localcmd("\nalias solve_quadratic2 \"cl_cmd solve_quadratic2 ${* ?}\"\n");
+}
+
+REGISTER_MUTATOR(cl_darkblink, true);
+
+MUTATOR_HOOKFUNCTION(cl_darkblink, DrawScoreboard)
+{
+ return darkblink;
+}
+
+MUTATOR_HOOKFUNCTION(cl_darkblink, HUD_Draw_overlay)
+{
+ if(!darkblink && !quadratic2)
+ return false;
+
+ if(time <= dark_fadetime && autocvar_hud_panel_darkradar_maximised_zoom_scale == 1)
+ {
+ HUD_DarkBlinking();
+ return false;
+ }
+ else
+ darkblink = false;
+
+ if(time <= quadratic2_fadetime)
+ {
+ HUD_Quadratic2();
+ // don't return true, we want regular HUD effects!
+ }
+ else
+ quadratic2 = false;
+
+ return false;
+}
+
+MUTATOR_HOOKFUNCTION(cl_darkblink, CSQC_ConsoleCommand)
+{
+ if(MUTATOR_RETURNVALUE) // command was already handled?
+ return;
+
+ string cmd_name = M_ARGV(0, string);
+ //int cmd_argc = M_ARGV(2, int);
+
+ if(cmd_name == "solve_quadratic2")
+ {
+ quadratic2 = true;
+ quadratic2_fadetime = time + 5;
+ return true;
+ }
+}
+
+NET_HANDLE(TE_CSQC_DARKBLINKING, bool isNew)
+{
+ return = true;
+
+ if(darkblink)
+ return;
+
+ localcmd("play2 sound/misc/blind\n");
+ darkblink = true;
+ dark_appeartime = time;
+ dark_fadetime = time + 9;
+}
+#endif
+/***************************************************************/
+#ifdef CSQC
bool Projectile_isnade(int proj); // TODO: remove
void DrawAmmoNades(vector myPos, vector mySize, bool draw_expanding, float expand_time); // TODO: mutator
REGISTER_STAT(KILL_TIME, float)
REGISTER_STAT(VEIL_ORB, float)
REGISTER_STAT(VEIL_ORB_ALPHA, float)
+REGISTER_STAT(ARMORIZING_ORB, float) //LegendGuard registers new STAT 11-02-2021
+REGISTER_STAT(ARMORIZING_ORB_ALPHA, float)
+REGISTER_STAT(DARK_ORB, float) //LegendGuard registers new STAT 08-02-2021
+REGISTER_STAT(DARK_ORB_ALPHA, float)
#ifdef SVQC
float autocvar_sv_showfps = 5;