]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Putting LegendaryGuard things into LegendaryGuard/bai_mod
authorLegendaryGuard <rootuser999@gmail.com>
Sat, 13 Feb 2021 11:21:05 +0000 (12:21 +0100)
committerLegendaryGuard <rootuser999@gmail.com>
Sat, 13 Feb 2021 11:21:05 +0000 (12:21 +0100)
13 files changed:
gfx/hud/default/nade_armorize.tga [new file with mode: 0644]
gfx/hud/default/nade_dark.tga [new file with mode: 0644]
gfx/hud/luma/nade_armorize.tga [new file with mode: 0644]
gfx/hud/luma/nade_dark.tga [new file with mode: 0644]
qcsrc/common/items/inventory.qh
qcsrc/common/mutators/mutator/nades/effects.inc
qcsrc/common/mutators/mutator/nades/nades.inc
qcsrc/common/mutators/mutator/nades/nades.qc
qcsrc/common/mutators/mutator/nades/nades.qh
qcsrc/common/stats.qh
qcsrc/common/weapons/weapon/devastator.qc
qcsrc/common/weapons/weapon/devastator.qh
sound/misc/blind.ogg [new file with mode: 0644]

diff --git a/gfx/hud/default/nade_armorize.tga b/gfx/hud/default/nade_armorize.tga
new file mode 100644 (file)
index 0000000..2d16014
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 (file)
index 0000000..8803e29
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 (file)
index 0000000..7588761
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 (file)
index 0000000..fb33b34
Binary files /dev/null and b/gfx/hud/luma/nade_dark.tga differ
index ebcddf2b21cd75fac61fa814969e02be6bb2ee9e..f7f87d9da66f8b65c87eb22b2de02ba3b8aa1fa2 100644 (file)
@@ -37,23 +37,6 @@ STATIC_INIT(Inventory)
 #endif
 
 #ifdef CSQC
-<<<<<<< HEAD
-#include <client/hud/hud.qh>
-
-//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
index 83cf74247fcdf2275c5a2bcc4df83025925700fb..aa7b729b1f0a95032ed271c7abe470d3af7e9ef5 100644 (file)
@@ -1,10 +1,15 @@
 #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) {
@@ -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) {
index 3270e719fe2902858fd1c4e516de7af2f05014fa..4c3f0df64268f5f5ae4763929531755c3fe0756c 100644 (file)
@@ -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
index a8d9f7936f6548b36f0cd36f63c4e0afbb35fe45..c9f25b9cb0d30c35b72174c36efd7f7a6d0c0e9d 100644 (file)
@@ -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)
index c07882270163a4434ad1ca4e1db3a6b5a2b40cbb..14272834485acf68a0802fbb436067196f04e642 100644 (file)
@@ -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
index d0f7f2bae34e2f6b7ccbcc72eecc1b6776e348ac..f539f97a9d66e9af3df19215b68b02859526ed58 100644 (file)
@@ -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;
index b3645b1df829b0793fcac7253bce6378a61906eb..f6a73844409ef43c51ce030c50a04f0b62c3907f 100644 (file)
@@ -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
index 11481c6f95167acf56acb927595a5056b52c04a0..b713646ed2ee36a43b73dc375cc84b8d963be573 100644 (file)
@@ -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 (file)
index 0000000..e40ab12
Binary files /dev/null and b/sound/misc/blind.ogg differ