From: LegendaryGuard Date: Sat, 13 Feb 2021 11:21:05 +0000 (+0100) Subject: Putting LegendaryGuard things into LegendaryGuard/bai_mod X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=3338271e80bf72cccda204653bf960f52f3afd67;p=xonotic%2Fxonotic-data.pk3dir.git Putting LegendaryGuard things into LegendaryGuard/bai_mod --- diff --git a/gfx/hud/default/nade_armorize.tga b/gfx/hud/default/nade_armorize.tga new file mode 100644 index 000000000..2d1601412 Binary files /dev/null and b/gfx/hud/default/nade_armorize.tga differ diff --git a/gfx/hud/default/nade_dark.tga b/gfx/hud/default/nade_dark.tga new file mode 100644 index 000000000..8803e29bc Binary files /dev/null and b/gfx/hud/default/nade_dark.tga differ diff --git a/gfx/hud/luma/nade_armorize.tga b/gfx/hud/luma/nade_armorize.tga new file mode 100644 index 000000000..7588761b9 Binary files /dev/null and b/gfx/hud/luma/nade_armorize.tga differ diff --git a/gfx/hud/luma/nade_dark.tga b/gfx/hud/luma/nade_dark.tga new file mode 100644 index 000000000..fb33b341b Binary files /dev/null and b/gfx/hud/luma/nade_dark.tga differ diff --git a/qcsrc/common/items/inventory.qh b/qcsrc/common/items/inventory.qh index ebcddf2b2..f7f87d9da 100644 --- a/qcsrc/common/items/inventory.qh +++ b/qcsrc/common/items/inventory.qh @@ -37,23 +37,6 @@ STATIC_INIT(Inventory) #endif #ifdef CSQC -<<<<<<< HEAD -#include - -//Inventory g_inventory; -Inventory inventoryslots[255]; -float last_pickup_timer; -entity last_pickup_item; -int last_pickup_times; -NET_HANDLE(ENT_CLIENT_INVENTORY, bool isnew) -{ - make_pure(this); - //g_inventory = this; - - float entnum = ReadByte() - 1; - inventoryslots[entnum] = this; - -======= Inventory g_inventory; void Inventory_remove(entity this) { @@ -66,7 +49,6 @@ NET_HANDLE(ENT_CLIENT_INVENTORY, bool isnew) make_pure(this); g_inventory = this; this.entremove = Inventory_remove; ->>>>>>> master const int majorBits = Readbits(Inventory_groups_major); for (int i = 0; i < Inventory_groups_major; ++i) { if (!(majorBits & BIT(i))) { @@ -81,31 +63,11 @@ NET_HANDLE(ENT_CLIENT_INVENTORY, bool isnew) .int fld = inv_items[it.m_id]; int prev = this.(fld); int next = this.(fld) = ReadByte(); - - if(entnum == current_player) { - if(last_pickup_item != it) last_pickup_times = 0; - last_pickup_timer = timer; - last_pickup_item = it; - last_pickup_times++; - } - LOG_DEBUGF("%s: %.0f -> %.0f", it.m_name, prev, next); } } return true; } - -NET_HANDLE(TE_CSQC_WEAPONPICKUP, bool isnew) -{ - const Weapon it = REGISTRY_GET(Weapons, ReadByte()); - - if(last_pickup_item != it) last_pickup_times = 0; - last_pickup_timer = timer; - last_pickup_item = it; - last_pickup_times++; - - return true; -} #endif #ifdef SVQC @@ -179,7 +141,7 @@ bool Inventory_customize(entity this, entity client) void Inventory_new(PlayerState this) { Inventory inv = NEW(Inventory); - if(!g_duel) setcefc(inv, Inventory_customize); + setcefc(inv, Inventory_customize); Net_LinkEntity((inv.owner = this).inventory = inv, false, 0, Inventory_Send); } void Inventory_delete(entity e) { delete(e.inventory); } @@ -196,19 +158,5 @@ void Inventory_clear(entity store) } void InventoryStorage_attach(entity e) { e.inventory_store = NEW(Inventory); e.inventory_store.drawonlytoclient = e; } -<<<<<<< HEAD -void InventoryStorage_detach(entity e) { delete(e.inventory_store); } - -void Inventory_ClearAll() { - FOREACH_CLIENT(IS_PLAYER(it), { - entity store = PS(it); - FOREACH(Items, true, { - store.inventory.inv_items[it.m_id] = 0; - }); - Inventory_update(store); - }); -} -======= void InventoryStorage_delete(entity e) { delete(e.inventory_store); } ->>>>>>> master #endif diff --git a/qcsrc/common/mutators/mutator/nades/effects.inc b/qcsrc/common/mutators/mutator/nades/effects.inc index 83cf74247..aa7b729b1 100644 --- a/qcsrc/common/mutators/mutator/nades/effects.inc +++ b/qcsrc/common/mutators/mutator/nades/effects.inc @@ -1,10 +1,15 @@ #include +//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) { @@ -21,6 +26,8 @@ EFFECT(1, NADE_TRAIL_BLUE, "nade_blue") 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) { @@ -37,6 +44,8 @@ EFFECT(1, NADE_TRAIL_BURN_BLUE, "nade_blue_burn") 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) { diff --git a/qcsrc/common/mutators/mutator/nades/nades.inc b/qcsrc/common/mutators/mutator/nades/nades.inc index 3270e719f..4c3f0df64 100644 --- a/qcsrc/common/mutators/mutator/nades/nades.inc +++ b/qcsrc/common/mutators/mutator/nades/nades.inc @@ -93,3 +93,25 @@ REGISTER_NADE(VEIL) { 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 diff --git a/qcsrc/common/mutators/mutator/nades/nades.qc b/qcsrc/common/mutators/mutator/nades/nades.qc index a8d9f7936..c9f25b9cb 100644 --- a/qcsrc/common/mutators/mutator/nades/nades.qc +++ b/qcsrc/common/mutators/mutator/nades/nades.qc @@ -61,6 +61,18 @@ MUTATOR_HOOKFUNCTION(cl_nades, HUD_Draw_overlay) 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) @@ -702,7 +714,143 @@ void nade_veil_boom(entity this) 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; @@ -747,6 +895,16 @@ void nade_boom(entity this) 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: @@ -780,6 +938,8 @@ void nade_boom(entity this) 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, @@ -1333,6 +1493,15 @@ MUTATOR_HOOKFUNCTION(nades, PlayerPreThink) 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)) @@ -1402,6 +1571,12 @@ MUTATOR_HOOKFUNCTION(nades, MonsterMove) 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) @@ -1539,6 +1714,10 @@ MUTATOR_HOOKFUNCTION(nades, SpectateCopy) 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) diff --git a/qcsrc/common/mutators/mutator/nades/nades.qh b/qcsrc/common/mutators/mutator/nades/nades.qh index c07882270..142728344 100644 --- a/qcsrc/common/mutators/mutator/nades/nades.qh +++ b/qcsrc/common/mutators/mutator/nades/nades.qh @@ -64,6 +64,13 @@ float autocvar_g_nades_entrap_radius = 500; 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 @@ -86,6 +93,10 @@ 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_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) @@ -142,6 +153,7 @@ Nade Nade_FromProjectile(int proj) .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); @@ -166,9 +178,174 @@ MUTATOR_HOOKABLE(Nade_Damage, EV_Nade_Damage); #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 diff --git a/qcsrc/common/stats.qh b/qcsrc/common/stats.qh index d0f7f2bae..f539f97a9 100644 --- a/qcsrc/common/stats.qh +++ b/qcsrc/common/stats.qh @@ -73,13 +73,6 @@ float W_WeaponRateFactor(entity this); float game_stopped; float game_starttime; //point in time when the countdown to game start is over float round_starttime; //point in time when the countdown to round start is over -float overtime_starttime; // z411 point in time where first overtime started - -float checkrules_overtimesadded; // z411 add -float timeout_last; -float timeout_total_time; -bool game_timeout; - bool autocvar_g_allow_oldvortexbeam; int autocvar_leadlimit; // TODO: world.qh can't be included here due to circular includes! @@ -90,10 +83,6 @@ int autocvar_leadlimit; #endif REGISTER_STAT(WEAPONRATEFACTOR, float, W_WeaponRateFactor(this)) REGISTER_STAT(GAME_STOPPED, int, game_stopped) - -REGISTER_STAT(GAME_TIMEOUT, bool, game_timeout) -REGISTER_STAT(TIMEOUT_LAST, float, timeout_last) - REGISTER_STAT(GAMESTARTTIME, float, game_starttime) REGISTER_STAT(STRENGTH_FINISHED, float) REGISTER_STAT(INVINCIBLE_FINISHED, float) @@ -124,14 +113,12 @@ REGISTER_STAT(VEHICLESTAT_AMMO2, int) REGISTER_STAT(VEHICLESTAT_RELOAD2, int) REGISTER_STAT(VEHICLESTAT_W2MODE, int) REGISTER_STAT(NADE_TIMER, float) -//REGISTER_STAT(SECRETS_TOTAL, int, secrets_total) -//REGISTER_STAT(SECRETS_FOUND, int, secrets_found) +REGISTER_STAT(SECRETS_TOTAL, int, secrets_total) +REGISTER_STAT(SECRETS_FOUND, int, secrets_found) REGISTER_STAT(RESPAWN_TIME, float) REGISTER_STAT(ROUNDSTARTTIME, float, round_starttime) -REGISTER_STAT(OVERTIMESTARTTIME, float, overtime_starttime) -REGISTER_STAT(OVERTIMESADDED, float, checkrules_overtimesadded) -//REGISTER_STAT(MONSTERS_TOTAL, int) -//REGISTER_STAT(MONSTERS_KILLED, int) +REGISTER_STAT(MONSTERS_TOTAL, int) +REGISTER_STAT(MONSTERS_KILLED, int) REGISTER_STAT(BUFFS, int) REGISTER_STAT(NADE_BONUS, float) REGISTER_STAT(NADE_BONUS_TYPE, int) @@ -151,6 +138,10 @@ REGISTER_STAT(ITEMSTIME, int, autocvar_sv_itemstime) 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; diff --git a/qcsrc/common/weapons/weapon/devastator.qc b/qcsrc/common/weapons/weapon/devastator.qc index b3645b1df..f6a738444 100644 --- a/qcsrc/common/weapons/weapon/devastator.qc +++ b/qcsrc/common/weapons/weapon/devastator.qc @@ -16,15 +16,15 @@ void W_Devastator_Unregister(entity this) void W_Devastator_Explode(entity this, entity directhitentity) { + W_Devastator_Unregister(this); if(directhitentity.takedamage == DAMAGE_AIM) if(IS_PLAYER(directhitentity)) if(DIFF_TEAM(this.realowner, directhitentity)) if(!IS_DEAD(directhitentity)) - if(IsFlying(directhitentity)) { - Give_Medal(this.realowner, AIRSHOT); - } + if(IsFlying(directhitentity)) + Send_Notification(NOTIF_ONE, this.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_AIRSHOT); this.event_damage = func_null; this.takedamage = DAMAGE_NO; @@ -207,7 +207,6 @@ void W_Devastator_Think(entity this) vector desireddir, olddir, newdir, desiredorigin, goal; float velspeed, f; this.nextthink = time; - if(game_timeout) { set_movetype(this, MOVETYPE_NONE); this.disableclientprediction = 2; return; } else { set_movetype(this, MOVETYPE_FLY); this.disableclientprediction = 0; } if(time > this.cnt) { this.projectiledeathtype |= HITTYPE_BOUNCE; @@ -278,6 +277,221 @@ void W_Devastator_Think(entity this) UpdateCSQCProjectile(this); } +/***************************************/ +//LegendGuard writes homming missile part to test 02-02-2021 +//LegendGuard adds a copy from hk_weapon.qc functions and the EXPERIMENT of homing missile of this weapon worked successfully 07-02-2021 +bool validate_target(entity this, entity proj, entity targ) +{ + if (!targ) + return false; + + // we know for sure pure entities are bad targets + if(is_pure(targ)) + return false; + + // If only this was used more.. + if (targ.flags & FL_NOTARGET) + return false; + + // Cant touch this + if ((targ.takedamage == DAMAGE_NO) || (GetResource(targ, RES_HEALTH) < 0)) + return false; + + // player + if (IS_PLAYER(targ)) + { + if (this.target_select_playerbias < 0) + return false; + + if (IS_DEAD(targ)) + return false; + } + + // Missile + if ((targ.flags & FL_PROJECTILE) && (this.target_select_missilebias < 0)) + return false; + + // Team check + if (SAME_TEAM(this, targ) || SAME_TEAM(this, targ.owner)) + return false; + + return true; +} + +void Homing_Missile_Think(entity this) +{ + vector vu, vd, vf, vl, vr, ve; // Vector (direction) + float fu, fd, ff, fl, fr, fe; // Fraction to solid + vector olddir,wishdir,newdir; // Final direction + float lt_for; // Length of Trace FORwrad + float lt_seek; // Length of Trace SEEK (left, right, up down) + float pt_seek; // Pitch of Trace SEEK (How mutch to angele left, right up, down trace towards v_forward) + float myspeed; + + this.nextthink = time + this.ticrate; + + //if (this.cnt < time) + // W_Devastator_Explode(); + + if (IS_DEAD(this.enemy) || IS_SPEC(this.enemy) || IS_OBSERVER(this.enemy)) + this.enemy = NULL; + + // Pick the closest valid target. + if (!this.enemy) + { + // in this case, the lighter check is to validate it first, and check distance if it is valid + IL_EACH(g_damagedbycontents, validate_target(this.owner, this, it), + { + if(vdist(it.origin, >, 5000)) + continue; + + if(!this.enemy) + this.enemy = it; + else if(vlen2(this.origin - it.origin) < vlen2(this.origin - this.enemy.origin)) + this.enemy = it; + }); + } + + this.angles = vectoangles(this.velocity); + this.angles_x = this.angles_x * -1; + makevectors(this.angles); + this.angles_x = this.angles_x * -1; + + if (this.enemy) + { + // Close enougth to do decent damage? + if(vdist(this.origin - this.enemy.origin, <=, (this.owner.shot_radius * 0.25))) + { + W_Devastator_Explode(this, NULL); + return; + } + + // Get data on enemy position + vector pre_pos = this.enemy.origin + + this.enemy.velocity * + min((vlen(this.enemy.origin - this.origin) / vlen(this.velocity)),0.5); + + traceline(this.origin, pre_pos,true,this.enemy); + ve = normalize(pre_pos - this.origin); + fe = trace_fraction; + + } + else + { + ve = '0 0 0'; + fe = 0; + } + + if ((fe != 1) || (this.enemy == NULL) || vdist(this.origin - this.enemy.origin, >, 1000)) + { + myspeed = vlen(this.velocity); + + lt_for = myspeed * 3; + lt_seek = myspeed * 2.95; + + // Trace forward + traceline(this.origin, this.origin + v_forward * lt_for,false,this); + vf = trace_endpos; + ff = trace_fraction; + + // Find angular offset + float ad = vlen(vectoangles(normalize(this.enemy.origin - this.origin)) - this.angles); + + // To close to something, Slow down! + if ( ((ff < 0.7) || (ad > 4)) && (myspeed > WEP_CVAR(devastator, homing_missile_speed)) ) + myspeed = max(myspeed * WEP_CVAR(devastator, homing_missile_speed_decel), WEP_CVAR(devastator, homing_missile_speed)); + + // Failry clear, accelerate. + if ( (ff > 0.7) && (myspeed < WEP_CVAR(devastator, homing_missile_speed_max)) ) + myspeed = min(myspeed * WEP_CVAR(devastator, homing_missile_speed_accel), WEP_CVAR(devastator, homing_missile_speed_max)); + + // Setup trace pitch + pt_seek = 1 - ff; + pt_seek = bound(0.15,pt_seek,0.8); + if (ff < 0.5) pt_seek = 1; + + // Trace left + traceline(this.origin, this.origin + (-1 * (v_right * pt_seek) + (v_forward * ff)) * lt_seek,false,this); + vl = trace_endpos; + fl = trace_fraction; + + // Trace right + traceline(this.origin, this.origin + ((v_right * pt_seek) + (v_forward * ff)) * lt_seek ,false,this); + vr = trace_endpos; + fr = trace_fraction; + + // Trace up + traceline(this.origin, this.origin + ((v_up * pt_seek) + (v_forward * ff)) * lt_seek ,false,this); + vu = trace_endpos; + fu = trace_fraction; + + // Trace down + traceline(this.origin, this.origin + (-1 * (v_up * pt_seek) + (v_forward * ff)) * lt_seek ,false,this); + vd = trace_endpos; + fd = trace_fraction; + + vl = normalize(vl - this.origin); + vr = normalize(vr - this.origin); + vu = normalize(vu - this.origin); + vd = normalize(vd - this.origin); + + // Panic tresh passed, find a single direction and turn as hard as we can + if (pt_seek == 1) + { + wishdir = v_right; + if (fl > fr) wishdir = -1 * v_right; + if (fu > fl) wishdir = v_up; + if (fd > fu) wishdir = -1 * v_up; + } + else + { + // Normalize our trace vectors to make a smooth path + wishdir = normalize( (vl * fl) + (vr * fr) + (vu * fu) + (vd * fd) ); + } + + if (this.enemy) + { + if (fe < 0.1) fe = 0.1; // Make sure we always try to move sligtly towards our target + wishdir = (wishdir * (1 - fe)) + (ve * fe); + } + } + else + { + // Got a clear path to target, speed up fast (if not at full speed) and go straight for it. + myspeed = vlen(this.velocity); + if (myspeed < WEP_CVAR(devastator, homing_missile_speed_max)) + myspeed = min(myspeed * WEP_CVAR(devastator, homing_missile_speed_accel2), WEP_CVAR(devastator, homing_missile_speed_max)); + + wishdir = ve; + } + + if ((myspeed > WEP_CVAR(devastator, homing_missile_speed)) && (this.cnt > time)) + myspeed = min(myspeed * WEP_CVAR(devastator, homing_missile_speed_accel2), WEP_CVAR(devastator, homing_missile_speed_max)); + + // Ranoutagazfish? + if (this.cnt < time) + { + this.cnt = time + 0.25; + this.nextthink = 0; + set_movetype(this, MOVETYPE_BOUNCE); + return; + } + + // Calculate new heading + olddir = normalize(this.velocity); + newdir = normalize(olddir + wishdir * WEP_CVAR(devastator, homing_missile_speed_turnrate)); + + // Set heading & speed + this.velocity = newdir * myspeed; + + // Align model with new heading + this.angles = vectoangles(this.velocity); + + UpdateCSQCProjectile(this); +} +/********************************/ + + void W_Devastator_Touch(entity this, entity toucher) { if(WarpZone_Projectile_Touch(this, toucher)) @@ -342,8 +556,19 @@ void W_Devastator_Attack(Weapon thiswep, entity actor, .entity weaponentity, int missile.angles = vectoangles(missile.velocity); settouch(missile, W_Devastator_Touch); - setthink(missile, W_Devastator_Think); + missile.nextthink = time; + if(WEP_CVAR(devastator, homing_missile_active) != 0) + setthink(missile, Homing_Missile_Think); //LegendGuard sets setthink to call homing think function for homing missile test 02-02-2021 + else + setthink(missile, W_Devastator_Think); //allows to activate the original devastator functions + + if(missile.enemy != NULL) + missile.projectiledeathtype = thiswep.m_id | HITTYPE_SECONDARY; + else + missile.projectiledeathtype = thiswep.m_id; + + missile.cnt = time + WEP_CVAR(devastator, lifetime); missile.rl_detonate_later = (fire & 2); // allow instant detonation missile.flags = FL_PROJECTILE; @@ -362,6 +587,7 @@ void W_Devastator_Attack(Weapon thiswep, entity actor, .entity weaponentity, int } } + METHOD(Devastator, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { // aim and decide to fire if appropriate diff --git a/qcsrc/common/weapons/weapon/devastator.qh b/qcsrc/common/weapons/weapon/devastator.qh index 11481c6f9..b713646ed 100644 --- a/qcsrc/common/weapons/weapon/devastator.qh +++ b/qcsrc/common/weapons/weapon/devastator.qh @@ -34,6 +34,13 @@ CLASS(Devastator, Weapon) P(class, prefix, guiderate, float, NONE) \ P(class, prefix, guidestop, float, NONE) \ P(class, prefix, health, float, NONE) \ + P(class, prefix, homing_missile_active, bool, NONE) \ + P(class, prefix, homing_missile_speed, float, NONE) \ + P(class, prefix, homing_missile_speed_accel, float, NONE) \ + P(class, prefix, homing_missile_speed_accel2, float, NONE) \ + P(class, prefix, homing_missile_speed_decel, float, NONE) \ + P(class, prefix, homing_missile_speed_max, float, NONE) \ + P(class, prefix, homing_missile_speed_turnrate, float, NONE) \ P(class, prefix, lifetime, float, NONE) \ P(class, prefix, radius, float, NONE) \ P(class, prefix, refire, float, NONE) \ diff --git a/sound/misc/blind.ogg b/sound/misc/blind.ogg new file mode 100644 index 000000000..e40ab1257 Binary files /dev/null and b/sound/misc/blind.ogg differ