]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Early Lightning Gun, still needs a ton of work. Next step: Remove lightning from...
authorSamual <samual@xonotic.org>
Mon, 28 Feb 2011 23:25:14 +0000 (18:25 -0500)
committerSamual <samual@xonotic.org>
Mon, 28 Feb 2011 23:25:14 +0000 (18:25 -0500)
12 files changed:
models/weapons/g_lightning.md3 [new file with mode: 0644]
models/weapons/h_lightning.iqm [new file with mode: 0644]
models/weapons/h_lightning.iqm.framegroups [new file with mode: 0644]
models/weapons/v_lightning.md3 [new file with mode: 0644]
models/weapons/w_lightning.zym [new file with mode: 0644]
qcsrc/client/Defs.qc
qcsrc/client/Main.qc
qcsrc/client/hook.qc
qcsrc/client/hud.qc
qcsrc/server/t_quake3.qc
qcsrc/server/w_all.qc
qcsrc/server/w_lightning.qc [new file with mode: 0644]

diff --git a/models/weapons/g_lightning.md3 b/models/weapons/g_lightning.md3
new file mode 100644 (file)
index 0000000..76c2e89
Binary files /dev/null and b/models/weapons/g_lightning.md3 differ
diff --git a/models/weapons/h_lightning.iqm b/models/weapons/h_lightning.iqm
new file mode 100644 (file)
index 0000000..8ae8898
Binary files /dev/null and b/models/weapons/h_lightning.iqm differ
diff --git a/models/weapons/h_lightning.iqm.framegroups b/models/weapons/h_lightning.iqm.framegroups
new file mode 100644 (file)
index 0000000..0a59625
--- /dev/null
@@ -0,0 +1,4 @@
+1 8 20 0 // fire
+9 5 20 0 // fire2
+15 200 20 1 // idle
+215 40 20 0 // reload
diff --git a/models/weapons/v_lightning.md3 b/models/weapons/v_lightning.md3
new file mode 100644 (file)
index 0000000..67105bc
Binary files /dev/null and b/models/weapons/v_lightning.md3 differ
diff --git a/models/weapons/w_lightning.zym b/models/weapons/w_lightning.zym
new file mode 100644 (file)
index 0000000..70cbd17
Binary files /dev/null and b/models/weapons/w_lightning.zym differ
index 3d15295942e21b6cefc40c52386f5f7ea3e8d6f0..62acc624968492cec56841ec85a64e70d0cd4084 100644 (file)
@@ -233,7 +233,7 @@ float announcer_5min;
 float tempdb;
 float ClientProgsDB;
 vector hook_shotorigin[4];
-vector electro_shotorigin[4];
+vector lightning_shotorigin[4];
 vector gauntlet_shotorigin[4];
 
 #ifdef BLURTEST
index 8614863318dcac9396237f4d6462dc30cdcf2826..1424a8c2794364fff7c211e5742284401fa52f39 100644 (file)
@@ -1067,10 +1067,10 @@ void Ent_Init()
        hook_shotorigin[1] = decompressShotOrigin(ReadInt24_t());
        hook_shotorigin[2] = decompressShotOrigin(ReadInt24_t());
        hook_shotorigin[3] = decompressShotOrigin(ReadInt24_t());
-       electro_shotorigin[0] = decompressShotOrigin(ReadInt24_t());
-       electro_shotorigin[1] = decompressShotOrigin(ReadInt24_t());
-       electro_shotorigin[2] = decompressShotOrigin(ReadInt24_t());
-       electro_shotorigin[3] = decompressShotOrigin(ReadInt24_t());
+       lightning_shotorigin[0] = decompressShotOrigin(ReadInt24_t());
+       lightning_shotorigin[1] = decompressShotOrigin(ReadInt24_t());
+       lightning_shotorigin[2] = decompressShotOrigin(ReadInt24_t());
+       lightning_shotorigin[3] = decompressShotOrigin(ReadInt24_t());
        gauntlet_shotorigin[0] = decompressShotOrigin(ReadInt24_t());
        gauntlet_shotorigin[1] = decompressShotOrigin(ReadInt24_t());
        gauntlet_shotorigin[2] = decompressShotOrigin(ReadInt24_t());
index 7ff5adeca46204beaf8e37d040341b84c3ee6854..91f62154ee4e2418f39f553249093d882ed48471 100644 (file)
@@ -76,7 +76,7 @@ void Draw_GrapplingHook()
                        vs = hook_shotorigin[s];
                        break;
                case ENT_CLIENT_LGBEAM:
-                       vs = electro_shotorigin[s];
+                       vs = lightning_shotorigin[s];
                        break;
                case ENT_CLIENT_GAUNTLET:
                        vs = gauntlet_shotorigin[s];
@@ -205,7 +205,7 @@ void Draw_GrapplingHook()
                case ENT_CLIENT_HOOK:
                        break;
                case ENT_CLIENT_LGBEAM:
-                       pointparticles(particleeffectnum("electro_lightning"), trace_endpos, normalize(atrans - trace_endpos), frametime * intensity);
+                       pointparticles(particleeffectnum("electro_lightning"), trace_endpos, normalize(atrans - trace_endpos), frametime * intensity); // todo: new effect
                        break;
                case ENT_CLIENT_GAUNTLET:
                        pointparticles(particleeffectnum("gauntlet_lightning"), b, normalize(a - b), frametime * intensity);
index d55cfd86612c76b69034738b7bf0a7d714fe398f..8e39cfcd22d9387c7f6ad20bf9e38545f537930a 100644 (file)
@@ -1506,6 +1506,7 @@ float GetAmmoTypeForWep(float i)
                case WEP_HLAC: return 3;
                case WEP_MINSTANEX: return 3;
                case WEP_NEX: return 3;
+               case WEP_LIGHTNING: return 3;
                case WEP_SNIPERRIFLE: return 1;
                case WEP_HAGAR: return 2;
                case WEP_ROCKET_LAUNCHER: return 2;
index 8cc7e479791b6a3fc8bec91c48383355953f2563..8ba0880f689145092c376ac3a084ed2400e5f0f1 100644 (file)
@@ -14,8 +14,8 @@ void spawnfunc_ammo_bullets()        { spawnfunc_item_bullets();        }
 // GL -> Mortar
 void spawnfunc_ammo_grenades()       { spawnfunc_item_rockets();        }
 
-// LG -> Electro
-void spawnfunc_weapon_lightning()    { spawnfunc_weapon_electro();      }
+// LG -> Lightning
+//void spawnfunc_weapon_lightning()    { spawnfunc_weapon_electro();      }
 void spawnfunc_ammo_lightning()      { spawnfunc_item_cells();          }
 
 // Plasma -> Hagar
index 930a413d58c487dbd4be050e2994c0ccd662f4dc..c31edb7f1096a2678058da95a39d9b16dd0d2edc 100644 (file)
@@ -7,6 +7,7 @@
 #include "w_grenadelauncher.qc"
 #include "w_minelayer.qc"
 #include "w_electro.qc"
+#include "w_lightning.qc"
 #include "w_crylink.qc"
 #include "w_nex.qc"
 #include "w_hagar.qc"
diff --git a/qcsrc/server/w_lightning.qc b/qcsrc/server/w_lightning.qc
new file mode 100644 (file)
index 0000000..2febfc2
--- /dev/null
@@ -0,0 +1,308 @@
+#ifdef REGISTER_WEAPON
+REGISTER_WEAPON(LIGHTNING, w_lightning, IT_CELLS, 5, WEP_FLAG_NORMAL | WEP_TYPE_SPLASH, BOT_PICKUP_RATING_MID, "lightning", "lightning", _("Lightning"));
+#else
+#ifdef SVQC
+
+// Declarations ========================= 
+.vector hook_start, hook_end; // used for beam
+.entity lightning_beam; // used for beam
+//.float bot_aim_whichfiretype; // ???
+.float BUTTON_ATCK_prev; // for better animation control
+.float lg_fire_prev; // for better animation control
+
+// Lightning functions ========================= 
+float W_Lightning_Beam_Send(entity to, float sf)
+{
+       WriteByte(MSG_ENTITY, ENT_CLIENT_LGBEAM);
+       sf = sf & 0x7F;
+       if(sound_allowed(MSG_BROADCAST, self.owner))
+               sf |= 0x80;
+       WriteByte(MSG_ENTITY, sf);
+       if(sf & 1)
+       {
+               WriteByte(MSG_ENTITY, num_for_edict(self.owner));
+               WriteCoord(MSG_ENTITY, autocvar_g_balance_electro_primary_range);
+       }
+       if(sf & 2)
+       {
+               WriteCoord(MSG_ENTITY, self.hook_start_x);
+               WriteCoord(MSG_ENTITY, self.hook_start_y);
+               WriteCoord(MSG_ENTITY, self.hook_start_z);
+       }
+       if(sf & 4)
+       {
+               WriteCoord(MSG_ENTITY, self.hook_end_x);
+               WriteCoord(MSG_ENTITY, self.hook_end_y);
+               WriteCoord(MSG_ENTITY, self.hook_end_z);
+       }
+       return TRUE;
+}
+
+void W_Lightning_Beam_Think()
+{
+       self.owner.lg_fire_prev = time;
+       if (self != self.owner.lightning_beam)
+       {
+               remove(self);
+               return;
+       }
+       if (self.owner.weaponentity.state != WS_INUSE || (self.owner.ammo_cells <= 0 && !(self.owner.items & IT_UNLIMITED_WEAPON_AMMO)) || self.owner.deadflag != DEAD_NO || !self.owner.BUTTON_ATCK || self.owner.freezetag_frozen)
+       {
+               if(self == self.owner.lightning_beam)
+                       self.owner.lightning_beam = world;
+               remove(self);
+               return;
+       }
+
+       self.nextthink = time;
+
+       makevectors(self.owner.v_angle);
+
+       float dt, f;
+       dt = frametime;
+       if not(self.owner.items & IT_UNLIMITED_WEAPON_AMMO)
+       {
+               if(autocvar_g_balance_electro_primary_ammo)
+               {
+                       dt = min(dt, self.owner.ammo_cells / autocvar_g_balance_electro_primary_ammo);
+                       self.owner.ammo_cells = max(0, self.owner.ammo_cells - autocvar_g_balance_electro_primary_ammo * frametime);
+               }
+       }
+
+       W_SetupShot_Range(self.owner, TRUE, 0, "", 0, autocvar_g_balance_electro_primary_damage * dt, autocvar_g_balance_electro_primary_range);
+       WarpZone_traceline_antilag(self.owner, w_shotorg, w_shotend, MOVE_NORMAL, self.owner, ANTILAG_LATENCY(self.owner));
+
+       // apply the damage
+       if(trace_ent)
+       {
+               vector force;
+               force = w_shotdir * autocvar_g_balance_electro_primary_force + '0 0 1' * autocvar_g_balance_electro_primary_force_up;
+
+               f = ExponentialFalloff(autocvar_g_balance_electro_primary_falloff_mindist, autocvar_g_balance_electro_primary_falloff_maxdist, autocvar_g_balance_electro_primary_falloff_halflifedist, vlen(WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos) - w_shotorg));
+
+               if(accuracy_isgooddamage(self.owner, trace_ent))
+                       accuracy_add(self.owner, WEP_LIGHTNING, 0, autocvar_g_balance_electro_primary_damage * dt * f);
+               Damage (trace_ent, self.owner, self.owner, autocvar_g_balance_electro_primary_damage * dt * f, WEP_LIGHTNING, trace_endpos, force * dt);
+       }
+
+       // draw effect
+       if(w_shotorg != self.hook_start)
+       {
+               self.SendFlags |= 2;
+               self.hook_start = w_shotorg;
+       }
+       if(w_shotend != self.hook_end)
+       {
+               self.SendFlags |= 4;
+               self.hook_end = w_shotend;
+       }
+}
+
+// Attack functions ========================= 
+void W_Lightning_Attack1 (void)
+{
+       // only play fire sound if 0.5 sec has passed since player let go the fire button
+       if(time - self.lg_fire_prev > 0.5)
+               sound (self, CHAN_WEAPON, "weapons/lgbeam_fire.wav", VOL_BASE, ATTN_NORM);
+
+       entity beam, oldself;
+
+       self.lightning_beam = beam = spawn();
+       beam.classname = "W_Lightning_Beam";
+       beam.solid = SOLID_NOT;
+       beam.think = W_Lightning_Beam_Think;
+       beam.owner = self;
+       beam.movetype = MOVETYPE_NONE;
+       beam.shot_spread = 0;
+       beam.bot_dodge = TRUE;
+       beam.bot_dodgerating = autocvar_g_balance_electro_primary_damage;
+       Net_LinkEntity(beam, FALSE, 0, W_Lightning_Beam_Send);
+
+       oldself = self;
+       self = beam;
+       self.think();
+       self = oldself;
+}
+
+void LightningInit()
+{
+       weapon_action(WEP_LIGHTNING, WR_PRECACHE);
+       lightning_shotorigin[0] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_LIGHTNING), FALSE, FALSE, 1);
+       lightning_shotorigin[1] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_LIGHTNING), FALSE, FALSE, 2);
+       lightning_shotorigin[2] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_LIGHTNING), FALSE, FALSE, 3);
+       lightning_shotorigin[3] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_LIGHTNING), FALSE, FALSE, 4);
+}
+
+void spawnfunc_weapon_lightning (void)
+{
+       weapon_defaultspawnfunc(WEP_LIGHTNING);
+}
+
+float w_lightning(float req)
+{
+       if (req == WR_AIM)
+       {
+               self.BUTTON_ATCK = bot_aim(1000000, 0, 0.001, FALSE);
+               /*
+               self.BUTTON_ATCK=FALSE;
+               self.BUTTON_ATCK2=FALSE;
+               if(vlen(self.origin-self.enemy.origin) > 1000)
+                       self.bot_aim_whichfiretype = 0;
+               if(self.bot_aim_whichfiretype == 0)
+               {
+                       float shoot;
+
+                       if(autocvar_g_balance_electro_primary_speed)
+                               shoot = bot_aim(autocvar_g_balance_electro_primary_speed, 0, autocvar_g_balance_electro_primary_lifetime, FALSE);
+                       else
+                               shoot = bot_aim(1000000, 0, 0.001, FALSE);
+
+                       if(shoot)
+                       {
+                               self.BUTTON_ATCK = TRUE;
+                               if(random() < 0.01) self.bot_aim_whichfiretype = 1;
+                       }
+               }
+               else // todo
+               {
+                       //if(bot_aim(autocvar_g_balance_electro_secondary_speed, autocvar_g_balance_grenadelauncher_secondary_speed_up, autocvar_g_balance_electro_secondary_lifetime, TRUE))
+                       //{
+                       //      self.BUTTON_ATCK2 = TRUE;
+                       //      if(random() < 0.03) self.bot_aim_whichfiretype = 0;
+                       //}
+               }
+               */
+       }
+       else if (req == WR_THINK)
+       {
+               if (self.BUTTON_ATCK)
+               {
+                       if(self.BUTTON_ATCK_prev)
+                               if(self.animstate_startframe == self.anim_shoot_x && self.animstate_numframes == self.anim_shoot_y)
+                                       weapon_thinkf(WFRAME_DONTCHANGE, autocvar_g_balance_electro_primary_animtime, w_ready);
+                               else
+                                       weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_electro_primary_animtime, w_ready);
+                       
+                       if (weapon_prepareattack(0, 0))
+                       {
+                               if ((!self.lightning_beam) || wasfreed(self.lightning_beam))
+                                       W_Lightning_Attack1();
+                               
+                               if(!self.BUTTON_ATCK_prev)
+                               {
+                                       weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_electro_primary_animtime, w_ready);
+                                       self.BUTTON_ATCK_prev = 1;
+                               }
+                       }
+               } 
+               else // todo
+               {
+                       if (self.BUTTON_ATCK_prev != 0)
+                       {
+                               weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_electro_primary_animtime, w_ready);
+                               ATTACK_FINISHED(self) = time + autocvar_g_balance_electro_primary_refire * W_WeaponRateFactor();
+                       }
+                       self.BUTTON_ATCK_prev = 0;
+               }
+
+               //if (self.BUTTON_ATCK2)
+                       //if (weapon_prepareattack(1, autocvar_g_balance_electro_secondary_refire))
+                       //{
+                       //      W_Lightning_Attack2();
+                       //      self.lightning_count = autocvar_g_balance_electro_secondary_count;
+                       //      weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_electro_secondary_animtime, w_lightning_checkattack);
+                       //      self.lightning_secondarytime = time + autocvar_g_balance_electro_secondary_refire2 * W_WeaponRateFactor();
+                       //}
+       }
+       else if (req == WR_PRECACHE)
+       {
+               precache_model ("models/weapons/g_lightning.md3");
+               precache_model ("models/weapons/v_lightning.md3");
+               precache_model ("models/weapons/h_lightning.iqm");
+               //precache_sound ("weapons/lightning_bounce.wav");
+               precache_sound ("weapons/lightning_fire.wav");
+               precache_sound ("weapons/lightning_fire2.wav");
+               precache_sound ("weapons/lightning_impact.wav");
+               //precache_sound ("weapons/lightning_impact_combo.wav");
+               //precache_sound ("weapons/W_Lightning_Beam_fire.wav");
+       }
+       else if (req == WR_SETUP)
+               weapon_setup(WEP_LIGHTNING);
+       else if (req == WR_CHECKAMMO1)
+       {
+               return !autocvar_g_balance_electro_primary_ammo || (self.ammo_cells > 0);
+       }
+       else if (req == WR_CHECKAMMO2)
+               return self.ammo_cells >= autocvar_g_balance_electro_secondary_ammo;
+       else if (req == WR_RESETPLAYER)
+       {
+               //self.lightning_secondarytime = time;
+       }
+       return TRUE;
+};
+#endif
+#ifdef CSQC
+float w_lightning(float req)
+{
+       if(req == WR_IMPACTEFFECT)
+       {
+               vector org2;
+               org2 = w_org + w_backoff * 6;
+               if(w_deathtype & HITTYPE_SECONDARY)
+               {
+                       pointparticles(particleeffectnum("lightning_ballexplode"), org2, '0 0 0', 1);
+                       if(!w_issilent)
+                               sound(self, CHAN_PROJECTILE, "weapons/lightning_impact.wav", VOL_BASE, ATTN_NORM);
+               }
+               else
+               {
+                       if(w_deathtype & HITTYPE_BOUNCE)
+                       {
+                               // this is sent as "primary (w_deathtype & HITTYPE_BOUNCE)" to distinguish it from (w_deathtype & HITTYPE_SECONDARY) bounced balls
+                               pointparticles(particleeffectnum("lightning_combo"), org2, '0 0 0', 1);
+                               if(!w_issilent)
+                                       sound(self, CHAN_PROJECTILE, "weapons/lightning_impact_combo.wav", VOL_BASE, ATTN_NORM);
+                       }
+                       else
+                       {
+                               pointparticles(particleeffectnum("lightning_impact"), org2, '0 0 0', 1);
+                               if(!w_issilent)
+                                       sound(self, CHAN_PROJECTILE, "weapons/lightning_impact.wav", VOL_BASE, ATTN_NORM);
+                       }
+               }
+       }
+       else if(req == WR_PRECACHE)
+       {
+               precache_sound("weapons/lightning_impact.wav");
+               precache_sound("weapons/lightning_impact_combo.wav");
+       }
+       else if (req == WR_SUICIDEMESSAGE)
+       {
+               if(w_deathtype & HITTYPE_SECONDARY)
+                       w_deathtypestring = _("%s could not remember where they put plasma");
+               else
+                       w_deathtypestring = _("%s played with plasma");
+       }
+       else if (req == WR_KILLMESSAGE)
+       {
+               if(w_deathtype & HITTYPE_SECONDARY)
+               {
+                       if(w_deathtype & HITTYPE_SPLASH) // unchecked: BOUNCE
+                               w_deathtypestring = _("%s just noticed %s's blue ball");
+                       else // unchecked: BOUNCE
+                               w_deathtypestring = _("%s got in touch with %s's blue ball");
+               }
+               else
+               {
+                       if(w_deathtype & HITTYPE_BOUNCE) // combo
+                               w_deathtypestring = _("%s felt the electrifying air of %s's combo");
+                       else if(w_deathtype & HITTYPE_SPLASH)
+                               w_deathtypestring = _("%s got too close to %s's blue beam");
+                       else
+                               w_deathtypestring = _("%s was blasted by %s's blue beam");
+               }
+       }
+       return TRUE;
+}
+#endif
+#endif