]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/generator.qc
Merge branch 'master' into Mario/monsters
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / generator.qc
index 891b82039063b0485a658237701088acd2698cd9..62fd76e9a6f9e4bf6f8bb5b5e80d4b21146a1b29 100644 (file)
@@ -1,5 +1,16 @@
 #ifdef CSQC
 float generator_precached;
+.float count;
+
+vector randompos(vector m1, vector m2)
+{
+    vector v;
+    m2 = m2 - m1;
+    v_x = m2_x * random() + m1_x;
+    v_y = m2_y * random() + m1_y;
+    v_z = m2_z * random() + m1_z;
+    return  v;
+}
 
 void generator_precache()
 {
@@ -19,10 +30,182 @@ void generator_precache()
        precache_model("models/onslaught/generator_dmg9.md3");
        precache_model("models/onslaught/generator_dead.md3");
        
+       precache_model("models/onslaught/ons_ray.md3");
+       precache_sound("onslaught/shockwave.wav");
+       precache_sound("weapons/grenade_impact.wav");
+       precache_sound("weapons/rocket_impact.wav");
+       
+       precache_model("models/onslaught/gen_gib1.md3");
+       precache_model("models/onslaught/gen_gib2.md3");
+       precache_model("models/onslaught/gen_gib3.md3");
+       
        generator_precached = TRUE;
 }
 
-void generator_draw() { } // TODO
+void ons_gib_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce)
+{
+       self.velocity = self.velocity + vforce;
+}
+
+.float giblifetime;
+
+void gib_draw_noburn()
+{
+       if(time >= self.giblifetime)
+               remove(self);
+}
+
+void gib_draw()
+{
+       if(time >= self.move_time)
+               return;
+
+       self.move_time = time + 0.05;
+
+       if(time > self.giblifetime)
+       {
+               remove(self);
+               return;
+       }
+       
+       self.alpha -= 0.05;
+       
+       if(self.alpha < 0.1)
+       {
+               remove(self);
+               return;
+       }
+
+       if(random()<0.6)
+               pointparticles(particleeffectnum("onslaught_generator_gib_flame"), self.origin, '0 0 0', 1);
+}
+
+void ons_throwgib(vector v_from, vector v_to, string smodel, float f_lifetime, float b_burn)
+{
+       entity gib;
+
+       gib = spawn();
+
+       setmodel(gib, smodel);
+       setorigin(gib, v_from);
+       gib.solid = SOLID_CORPSE;
+       gib.move_movetype = MOVETYPE_BOUNCE;
+       gib.movetype = MOVETYPE_BOUNCE;
+       gib.health = 255;
+       gib.move_velocity = v_to;
+       gib.move_origin = v_from;
+       gib.velocity = v_to;
+       gib.alpha = 1;
+       gib.move_time = time;
+       gib.drawmask = MASK_NORMAL;
+       gib.giblifetime = time + f_lifetime;
+       
+       if(b_burn)
+               gib.draw = gib_draw;
+       else
+               gib.draw = gib_draw_noburn;     
+}
+
+void onslaught_generator_ray_think()
+{
+       self.nextthink = time + 0.05;
+       if(self.count > 10)
+       {
+               self.think = SUB_Remove;
+               return;
+       }
+
+       if(self.count > 5)
+               self.alpha -= 0.1;
+       else
+               self.alpha += 0.1;
+
+       self.scale += 0.2;
+       self.count +=1;
+}
+
+void onslaught_generator_ray_spawn(vector org)
+{
+       entity e;
+       e = spawn();
+       setmodel(e, "models/onslaught/ons_ray.md3");
+       setorigin(e, org);
+       e.angles = randomvec() * 360;
+       e.alpha = 0;
+       e.scale = random() * 5 + 8;
+       e.think = onslaught_generator_ray_think;
+       e.nextthink = time + 0.05;
+}
+
+void generator_draw()
+{
+       if(self.health > 0)
+               return;
+         
+       if(time < self.move_time)
+               return;
+       if(self.count <= 0)
+               return;
+    
+    vector org;
+       float i;
+
+       // White shockwave
+       if(self.count==40||self.count==20)
+       {
+               sound(self, CH_TRIGGER, "onslaught/shockwave.wav", VOL_BASE, ATTN_NORM);
+               pointparticles(particleeffectnum("electro_combo"), self.origin, '0 0 0', 6);
+       }
+
+       // Throw some gibs
+       if(random() < 0.3)
+       {
+               i = random();
+               if(i < 0.3)
+                       ons_throwgib(self.origin + '0 0 40', (100 * randomvec() - '1 1 1') * 11 + '0 0 20', "models/onslaught/gen_gib1.md3", 6, TRUE);
+               else if(i > 0.7)
+                       ons_throwgib(self.origin + '0 0 40', (100 * randomvec() - '1 1 1') * 12 + '0 0 20', "models/onslaught/gen_gib2.md3", 6, TRUE);
+               else
+                       ons_throwgib(self.origin + '0 0 40', (100 * randomvec() - '1 1 1') * 13 + '0 0 20', "models/onslaught/gen_gib3.md3", 6, TRUE);
+       }
+
+       // Spawn fire balls
+       for(i=0;i < 10;++i)
+       {
+               org = self.origin + randompos('-30 -30 -30' * i + '0 0 -20', '30 30 30' * i + '0 0 20');
+               pointparticles(particleeffectnum("onslaught_generator_gib_explode"), org, '0 0 0', 1);
+       }
+
+       // Short explosion sound + small explosion
+       if(random() < 0.25)
+       {
+               te_explosion(self.origin);
+               sound(self, CH_TRIGGER, "weapons/grenade_impact.wav", VOL_BASE, ATTN_NORM);
+       }
+
+       // Particles
+       org = self.origin + randompos(self.mins + '8 8 8', self.maxs + '-8 -8 -8');
+       pointparticles(particleeffectnum("onslaught_generator_smallexplosion"), org, '0 0 0', 1);
+
+       // rays
+       if(random() > 0.25 )
+       {
+               onslaught_generator_ray_spawn(self.origin);
+       }
+
+       // Final explosion
+       if(self.count==1)
+       {
+               org = self.origin;
+               te_explosion(org);
+               pointparticles(particleeffectnum("onslaught_generator_finalexplosion"), org, '0 0 0', 1);
+               sound(self, CH_TRIGGER, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
+       }
+       
+       self.move_time = time + 0.05;
+
+       self.count -= 1;
+}
 
 .float max_health;
 void generator_damage(float hp)
@@ -54,7 +237,7 @@ void generator_damage(float hp)
 }
 
 void generator_construct()
-{      
+{
        self.netname = "Generator";
 
        setorigin(self, self.origin);
@@ -74,11 +257,18 @@ void generator_construct()
 .vector glowmod;
 void generator_changeteam()
 {
-       self.glowmod = Team_ColorRGB(self.team - 1);
-       self.teamradar_color = Team_ColorRGB(self.team - 1);
-       
        if(self.team)
+       {
+               self.glowmod = Team_ColorRGB(self.team - 1);
+               self.teamradar_color = Team_ColorRGB(self.team - 1);
                self.colormap = 1024 + (self.team - 1) * 17;
+       }
+       else
+       {
+               self.colormap = 1024;
+               self.glowmod = '1 1 0';
+               self.teamradar_color = '1 1 0';
+       }
 }
 
 void ent_generator()
@@ -95,11 +285,15 @@ void ent_generator()
                
                self.health = ReadByte();
                self.max_health = ReadByte();
+               self.count = ReadByte();
+               self.team = ReadByte();
                
+               if not(self.count)
+                       self.count = 40;
+               
+               generator_changeteam();
                generator_precache();
                generator_construct();
-               self.colormap = 1024;
-               self.glowmod = '1 1 0'; 
        }
 
        if(sf & GSF_STATUS)
@@ -116,9 +310,6 @@ void ent_generator()
                
                if(_tmp != self.health)
                        generator_damage(_tmp);
-               
-               //if(_tmp == 0 && self.health != 0)
-                       //generator_die();
 
                self.health = _tmp;
        }
@@ -138,6 +329,8 @@ float generator_send(entity to, float sf)
                
                WriteByte(MSG_ENTITY, self.health);
                WriteByte(MSG_ENTITY, self.max_health);
+               WriteByte(MSG_ENTITY, self.count);
+               WriteByte(MSG_ENTITY, self.team);
     }
     
     if(sf & GSF_STATUS)