1 void onslaught_generator_updatesprite(entity e);
\r
2 void onslaught_controlpoint_updatesprite(entity e);
\r
3 void onslaught_link_checkupdate();
\r
9 .float isgenneighbor_red;
\r
10 .float isgenneighbor_blue;
\r
11 .float iscpneighbor_red;
\r
12 .float iscpneighbor_blue;
\r
16 .float lastshielded;
\r
17 .float lastcaptured;
\r
19 .string model1, model2, model3;
\r
21 void ons_gib_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce)
\r
23 self.velocity = self.velocity + vforce;
\r
27 void ons_throwgib_think()
\r
31 self.nextthink = time + 0.05;
\r
33 d = self.giblifetime - time;
\r
37 self.think = SUB_Remove;
\r
45 pointparticles(particleeffectnum("onslaught_generator_gib_flame"), self.origin, '0 0 0', 1);
\r
48 void ons_throwgib(vector v_from, vector v_to, string smodel, float f_lifetime, float b_burn)
\r
54 setmodel(gib, smodel);
\r
55 setorigin(gib, v_from);
\r
56 gib.solid = SOLID_BBOX;
\r
57 gib.movetype = MOVETYPE_BOUNCE;
\r
58 gib.takedamage = DAMAGE_YES;
\r
59 gib.event_damage = ons_gib_damage;
\r
61 gib.effects = EF_LOWPRECISION;
\r
62 gib.flags = FL_NOTARGET;
\r
63 gib.velocity = v_to;
\r
64 gib.giblifetime = time + f_lifetime;
\r
68 gib.think = ons_throwgib_think;
\r
69 gib.nextthink = time + 0.05;
\r
72 SUB_SetFade(gib, gib.giblifetime, 2);
\r
75 void onslaught_updatelinks()
\r
77 local entity l, links;
\r
78 local float stop, t1, t2, t3, t4;
\r
79 // first check if the game has ended
\r
80 dprint("--- updatelinks ---\n");
\r
81 links = findchain(classname, "onslaught_link");
\r
82 // mark generators as being shielded and networked
\r
83 l = findchain(classname, "onslaught_generator");
\r
87 dprint(etos(l), " (generator) belongs to team ", ftos(l.team), "\n");
\r
89 dprint(etos(l), " (generator) is destroyed\n");
\r
90 l.islinked = l.iscaptured;
\r
91 l.isshielded = l.iscaptured;
\r
94 // mark points as shielded and not networked
\r
95 l = findchain(classname, "onslaught_controlpoint");
\r
99 l.isshielded = TRUE;
\r
100 l.isgenneighbor_red = FALSE;
\r
101 l.isgenneighbor_blue = FALSE;
\r
102 l.iscpneighbor_red = FALSE;
\r
103 l.iscpneighbor_blue = FALSE;
\r
104 dprint(etos(l), " (point) belongs to team ", ftos(l.team), "\n");
\r
107 // flow power outward from the generators through the network
\r
111 dprint(etos(l), " (link) connects ", etos(l.goalentity), " with ", etos(l.enemy), "\n");
\r
121 // if both points are captured by the same team, and only one of
\r
122 // them is powered, mark the other one as powered as well
\r
123 if (l.enemy.iscaptured && l.goalentity.iscaptured)
\r
124 if (l.enemy.islinked != l.goalentity.islinked)
\r
125 if (l.enemy.team == l.goalentity.team)
\r
127 if (!l.goalentity.islinked)
\r
130 l.goalentity.islinked = TRUE;
\r
131 dprint(etos(l), " (link) is marking ", etos(l.goalentity), " (point) because its team matches ", etos(l.enemy), " (point)\n");
\r
133 else if (!l.enemy.islinked)
\r
136 l.enemy.islinked = TRUE;
\r
137 dprint(etos(l), " (link) is marking ", etos(l.enemy), " (point) because its team matches ", etos(l.goalentity), " (point)\n");
\r
143 // now that we know which points are powered we can mark their neighbors
\r
144 // as unshielded if team differs
\r
148 if (l.goalentity.islinked)
\r
150 if (l.goalentity.team != l.enemy.team)
\r
152 dprint(etos(l), " (link) is unshielding ", etos(l.enemy), " (point) because its team does not match ", etos(l.goalentity), " (point)\n");
\r
153 l.enemy.isshielded = FALSE;
\r
155 if(l.goalentity.classname == "onslaught_generator")
\r
157 if(l.goalentity.team == COLOR_TEAM1)
\r
158 l.enemy.isgenneighbor_red = TRUE;
\r
159 else if(l.goalentity.team == COLOR_TEAM2)
\r
160 l.enemy.isgenneighbor_blue = TRUE;
\r
164 if(l.goalentity.team == COLOR_TEAM1)
\r
165 l.enemy.iscpneighbor_red = TRUE;
\r
166 else if(l.goalentity.team == COLOR_TEAM2)
\r
167 l.enemy.iscpneighbor_blue = TRUE;
\r
170 if (l.enemy.islinked)
\r
172 if (l.goalentity.team != l.enemy.team)
\r
174 dprint(etos(l), " (link) is unshielding ", etos(l.goalentity), " (point) because its team does not match ", etos(l.enemy), " (point)\n");
\r
175 l.goalentity.isshielded = FALSE;
\r
177 if(l.enemy.classname == "onslaught_generator")
\r
179 if(l.enemy.team == COLOR_TEAM1)
\r
180 l.goalentity.isgenneighbor_red = TRUE;
\r
181 else if(l.enemy.team == COLOR_TEAM2)
\r
182 l.goalentity.isgenneighbor_blue = TRUE;
\r
186 if(l.enemy.team == COLOR_TEAM1)
\r
187 l.goalentity.iscpneighbor_red = TRUE;
\r
188 else if(l.enemy.team == COLOR_TEAM2)
\r
189 l.goalentity.iscpneighbor_blue = TRUE;
\r
194 // now update the takedamage and alpha variables on generator shields
\r
195 l = findchain(classname, "onslaught_generator");
\r
200 dprint(etos(l), " (generator) is shielded\n");
\r
202 l.takedamage = DAMAGE_NO;
\r
203 l.bot_attack = FALSE;
\r
207 dprint(etos(l), " (generator) is not shielded\n");
\r
208 l.enemy.alpha = -1;
\r
209 l.takedamage = DAMAGE_AIM;
\r
210 l.bot_attack = TRUE;
\r
214 // now update the takedamage and alpha variables on control point icons
\r
215 l = findchain(classname, "onslaught_controlpoint");
\r
220 dprint(etos(l), " (point) is shielded\n");
\r
224 l.goalentity.takedamage = DAMAGE_NO;
\r
225 l.goalentity.bot_attack = FALSE;
\r
230 dprint(etos(l), " (point) is not shielded\n");
\r
231 l.enemy.alpha = -1;
\r
234 l.goalentity.takedamage = DAMAGE_AIM;
\r
235 l.goalentity.bot_attack = TRUE;
\r
238 onslaught_controlpoint_updatesprite(l);
\r
241 // count generators owned by each team
\r
242 t1 = t2 = t3 = t4 = 0;
\r
243 l = findchain(classname, "onslaught_generator");
\r
248 if (l.team == COLOR_TEAM1) t1 = 1;
\r
249 if (l.team == COLOR_TEAM2) t2 = 1;
\r
250 if (l.team == COLOR_TEAM3) t3 = 1;
\r
251 if (l.team == COLOR_TEAM4) t4 = 1;
\r
253 onslaught_generator_updatesprite(l);
\r
256 // see if multiple teams remain (if not, it's game over)
\r
257 if (t1 + t2 + t3 + t4 < 2)
\r
258 dprint("--- game over ---\n");
\r
260 dprint("--- done updating links ---\n");
\r
263 float onslaught_controlpoint_can_be_linked(entity cp, float t)
\r
265 if(t == COLOR_TEAM1)
\r
267 if(cp.isgenneighbor_red)
\r
269 if(cp.iscpneighbor_red)
\r
272 else if(t == COLOR_TEAM2)
\r
274 if(cp.isgenneighbor_blue)
\r
276 if(cp.iscpneighbor_blue)
\r
282 // check to see if this player has a legitimate claim to capture this
\r
283 // control point - more specifically that there is a captured path of
\r
284 // points leading back to the team generator
\r
285 e = findchain(classname, "onslaught_link");
\r
288 if (e.goalentity == cp)
\r
290 dprint(etos(e), " (link) connects to ", etos(e.enemy), " (point)");
\r
291 if (e.enemy.islinked)
\r
293 dprint(" which is linked");
\r
294 if (e.enemy.team == t)
\r
296 dprint(" and has the correct team!\n");
\r
300 dprint(" but has the wrong team\n");
\r
305 else if (e.enemy == cp)
\r
307 dprint(etos(e), " (link) connects to ", etos(e.goalentity), " (point)");
\r
308 if (e.goalentity.islinked)
\r
310 dprint(" which is linked");
\r
311 if (e.goalentity.team == t)
\r
313 dprint(" and has a team!\n");
\r
317 dprint(" but has the wrong team\n");
\r
328 float onslaught_controlpoint_attackable(entity cp, float t)
\r
329 // -2: SAME TEAM, attackable by enemy!
\r
334 // 3: attack it (HIGH PRIO)
\r
335 // 4: touch it (HIGH PRIO)
\r
343 else if(cp.goalentity)
\r
345 // if there's already an icon built, nothing happens
\r
348 a = onslaught_controlpoint_can_be_linked(cp, COLOR_TEAM1 + COLOR_TEAM2 - t);
\r
349 if(a) // attackable by enemy?
\r
350 return -2; // EMERGENCY!
\r
353 // we know it can be linked, so no need to check
\r
355 a = onslaught_controlpoint_can_be_linked(cp, t);
\r
356 if(a == 2) // near our generator?
\r
357 return 3; // EMERGENCY!
\r
363 if(onslaught_controlpoint_can_be_linked(cp, t))
\r
365 a = onslaught_controlpoint_can_be_linked(cp, COLOR_TEAM1 + COLOR_TEAM2 - t);
\r
367 return 4; // GET THIS ONE NOW!
\r
369 return 2; // TOUCH ME
\r
375 void onslaught_generator_think()
\r
379 self.nextthink = ceil(time + 1);
\r
382 if (cvar("timelimit"))
\r
383 if (time > game_starttime + cvar("timelimit") * 60)
\r
385 // self.max_health / 300 gives 5 minutes of overtime.
\r
386 // control points reduce the overtime duration.
\r
387 sound(self, CHAN_TRIGGER, "onslaught/generator_decay.wav", VOL_BASE, ATTN_NORM);
\r
389 e = findchain(classname, "onslaught_controlpoint");
\r
392 if (e.team != self.team)
\r
397 d = d * self.max_health / 300;
\r
398 Damage(self, self, self, d, DEATH_HURTTRIGGER, self.origin, '0 0 0');
\r
403 void onslaught_generator_ring_spawn(vector org)
\r
405 modeleffect_spawn("models/onslaught/shockwavetransring.md3", 0, 0, org, '0 0 0', '0 0 0', '0 0 0', 0, -16, 0.1, 1.25, 0.25);
\r
408 void onslaught_generator_ray_think()
\r
410 self.nextthink = time + 0.05;
\r
411 if(self.count > 10)
\r
413 self.think = SUB_Remove;
\r
426 void onslaught_generator_ray_spawn(vector org)
\r
430 setmodel(e, "models/onslaught/ons_ray.md3");
\r
432 e.angles = randomvec() * 360;
\r
434 e.scale = random() * 5 + 8;
\r
435 e.think = onslaught_generator_ray_think;
\r
436 e.nextthink = time + 0.05;
\r
439 void onslaught_generator_shockwave_spawn(vector org)
\r
441 shockwave_spawn("models/onslaught/shockwave.md3", org, -64, 0.75, 0.5);
\r
444 void onslaught_generator_damage_think()
\r
446 if(self.owner.health < 0)
\r
448 self.think = SUB_Remove;
\r
451 self.nextthink = time+0.1;
\r
453 // damaged fx (less probable the more damaged is the generator)
\r
454 if(random() < 0.9 - self.owner.health / self.owner.max_health)
\r
455 if(random() < 0.01)
\r
457 pointparticles(particleeffectnum("electric_ballexplode"), self.origin + randompos('-50 -50 -20', '50 50 50'), '0 0 0', 1);
\r
458 sound(self, CHAN_TRIGGER, "onslaught/electricity_explode.wav", VOL_BASE, ATTN_NORM);
\r
461 pointparticles(particleeffectnum("torch_small"), self.origin + randompos('-60 -60 -20', '60 60 60'), '0 0 0', 1);
\r
464 void onslaught_generator_damage_spawn(entity gd_owner)
\r
468 e.owner = gd_owner;
\r
469 e.health = self.owner.health;
\r
470 setorigin(e, gd_owner.origin);
\r
471 e.think = onslaught_generator_damage_think;
\r
472 e.nextthink = time+1;
\r
475 void onslaught_generator_deaththink()
\r
480 if not (self.count)
\r
484 if(self.count==40||self.count==20)
\r
486 onslaught_generator_ring_spawn(self.origin);
\r
487 sound(self, CHAN_TRIGGER, "onslaught/shockwave.wav", VOL_BASE, ATTN_NORM);
\r
495 ons_throwgib(self.origin + '0 0 40', (100 * randomvec() - '1 1 1') * 11 + '0 0 20', "models/onslaught/gen_gib1.md3", 6, TRUE);
\r
497 ons_throwgib(self.origin + '0 0 40', (100 * randomvec() - '1 1 1') * 12 + '0 0 20', "models/onslaught/gen_gib2.md3", 6, TRUE);
\r
499 ons_throwgib(self.origin + '0 0 40', (100 * randomvec() - '1 1 1') * 13 + '0 0 20', "models/onslaught/gen_gib3.md3", 6, TRUE);
\r
502 // Spawn fire balls
\r
503 for(i=0;i < 10;++i)
\r
505 org = self.origin + randompos('-30 -30 -30' * i + '0 0 -20', '30 30 30' * i + '0 0 20');
\r
506 pointparticles(particleeffectnum("onslaught_generator_gib_explode"), org, '0 0 0', 1);
\r
509 // Short explosion sound + small explosion
\r
510 if(random() < 0.25)
\r
512 te_explosion(self.origin);
\r
513 sound(self, CHAN_TRIGGER, "weapons/grenade_impact.wav", VOL_BASE, ATTN_NORM);
\r
517 org = self.origin + randompos(self.mins + '8 8 8', self.maxs + '-8 -8 -8');
\r
518 pointparticles(particleeffectnum("onslaught_generator_smallexplosion"), org, '0 0 0', 1);
\r
521 if(random() > 0.25 )
\r
523 onslaught_generator_ray_spawn(self.origin);
\r
531 onslaught_generator_shockwave_spawn(org);
\r
532 pointparticles(particleeffectnum("onslaught_generator_finalexplosion"), org, '0 0 0', 1);
\r
533 sound(self, CHAN_TRIGGER, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
\r
536 self.nextthink = time + 0.05;
\r
538 self.count = self.count - 1;
\r
541 void onslaught_generator_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
\r
548 if (attacker != self)
\r
550 if (self.isshielded)
\r
552 // this is protected by a shield, so ignore the damage
\r
553 if (time > self.pain_finished)
\r
554 if (attacker.classname == "player")
\r
556 play2(attacker, "onslaught/damageblockedbyshield.wav");
\r
557 self.pain_finished = time + 1;
\r
561 if (time > self.pain_finished)
\r
563 self.pain_finished = time + 10;
\r
564 bprint(ColoredTeamName(self.team), " generator under attack!\n");
\r
565 play2team(self.team, "onslaught/generator_underattack.wav");
\r
568 self.health = self.health - damage;
\r
569 WaypointSprite_UpdateHealth(self.sprite, self.health);
\r
570 // choose an animation frame based on health
\r
571 self.frame = 10 * bound(0, (1 - self.health / self.max_health), 1);
\r
572 // see if the generator is still functional, or dying
\r
573 if (self.health > 0)
\r
575 #ifdef ONSLAUGHT_SPAM
\r
577 lh = ceil(self.lasthealth / 100) * 100;
\r
578 h = ceil(self.health / 100) * 100;
\r
580 bprint(ColoredTeamName(self.team), " generator has less than ", ftos(h), " health remaining\n");
\r
582 self.lasthealth = self.health;
\r
584 else if not(inWarmupStage)
\r
586 if (attacker == self)
\r
587 bprint(ColoredTeamName(self.team), " generator spontaneously exploded due to overtime!\n");
\r
591 t = ColoredTeamName(attacker.team);
\r
592 bprint(ColoredTeamName(self.team), " generator destroyed by ", t, "!\n");
\r
594 self.iscaptured = FALSE;
\r
595 self.islinked = FALSE;
\r
596 self.isshielded = FALSE;
\r
597 self.takedamage = DAMAGE_NO; // can't be hurt anymore
\r
598 self.event_damage = SUB_Null; // won't do anything if hurt
\r
599 self.count = 0; // reset counter
\r
600 self.think = onslaught_generator_deaththink; // explosion sequence
\r
601 self.nextthink = time; // start exploding immediately
\r
602 self.think(); // do the first explosion now
\r
604 WaypointSprite_UpdateMaxHealth(self.sprite, 0);
\r
606 onslaught_updatelinks();
\r
609 if(self.health <= 0)
\r
610 setmodel(self, "models/onslaught/generator_dead.md3");
\r
611 else if(self.health < self.max_health * 0.10)
\r
612 setmodel(self, "models/onslaught/generator_dmg9.md3");
\r
613 else if(self.health < self.max_health * 0.20)
\r
614 setmodel(self, "models/onslaught/generator_dmg8.md3");
\r
615 else if(self.health < self.max_health * 0.30)
\r
616 setmodel(self, "models/onslaught/generator_dmg7.md3");
\r
617 else if(self.health < self.max_health * 0.40)
\r
618 setmodel(self, "models/onslaught/generator_dmg6.md3");
\r
619 else if(self.health < self.max_health * 0.50)
\r
620 setmodel(self, "models/onslaught/generator_dmg5.md3");
\r
621 else if(self.health < self.max_health * 0.60)
\r
622 setmodel(self, "models/onslaught/generator_dmg4.md3");
\r
623 else if(self.health < self.max_health * 0.70)
\r
624 setmodel(self, "models/onslaught/generator_dmg3.md3");
\r
625 else if(self.health < self.max_health * 0.80)
\r
626 setmodel(self, "models/onslaught/generator_dmg2.md3");
\r
627 else if(self.health < self.max_health * 0.90)
\r
628 setmodel(self, "models/onslaught/generator_dmg1.md3");
\r
629 setsize(self, '-52 -52 -14', '52 52 75');
\r
631 // Throw some flaming gibs on damage, more damage = more chance for gib
\r
632 if(random() < damage/220)
\r
634 sound(self, CHAN_TRIGGER, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
\r
637 ons_throwgib(hitloc + '0 0 20', force * -1, "models/onslaught/gen_gib1.md3", 5, TRUE);
\r
639 ons_throwgib(hitloc + '0 0 20', force * -1, "models/onslaught/gen_gib2.md3", 5, TRUE);
\r
641 ons_throwgib(hitloc + '0 0 20', force * -1, "models/onslaught/gen_gib3.md3", 5, TRUE);
\r
645 // particles on every hit
\r
646 pointparticles(particleeffectnum("sparks"), hitloc, force * -1, 1);
\r
648 //sound on every hit
\r
649 if (random() < 0.5)
\r
650 sound(self, CHAN_TRIGGER, "onslaught/ons_hit1.wav", VOL_BASE, ATTN_NORM);
\r
652 sound(self, CHAN_TRIGGER, "onslaught/ons_hit2.wav", VOL_BASE, ATTN_NORM);
\r
655 //throw some gibs on damage
\r
656 if(random() < damage/200+0.2)
\r
658 ons_throwgib(hitloc + '0 0 20', randomvec()*360, "models/onslaught/gen_gib1.md3", 5, FALSE);
\r
661 // update links after a delay
\r
662 void onslaught_generator_delayed()
\r
664 onslaught_updatelinks();
\r
665 // now begin normal thinking
\r
666 self.think = onslaught_generator_think;
\r
667 self.nextthink = time;
\r
670 string onslaught_generator_waypointsprite_for_team(entity e, float t)
\r
674 if(e.team == COLOR_TEAM1)
\r
675 return "ons-gen-red";
\r
676 else if(e.team == COLOR_TEAM2)
\r
677 return "ons-gen-blue";
\r
680 return "ons-gen-shielded";
\r
681 if(e.team == COLOR_TEAM1)
\r
682 return "ons-gen-red";
\r
683 else if(e.team == COLOR_TEAM2)
\r
684 return "ons-gen-blue";
\r
688 void onslaught_generator_updatesprite(entity e)
\r
691 s1 = onslaught_generator_waypointsprite_for_team(e, COLOR_TEAM1);
\r
692 s2 = onslaught_generator_waypointsprite_for_team(e, COLOR_TEAM2);
\r
693 s3 = onslaught_generator_waypointsprite_for_team(e, -1);
\r
694 WaypointSprite_UpdateSprites(e.sprite, s1, s2, s3);
\r
696 if(e.lastteam != e.team + 2 || e.lastshielded != e.isshielded)
\r
698 e.lastteam = e.team + 2;
\r
699 e.lastshielded = e.isshielded;
\r
702 if(e.team == COLOR_TEAM1 || e.team == COLOR_TEAM2)
\r
703 WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_GENERATOR, 0.5 * colormapPaletteColor(e.team - 1, FALSE));
\r
705 WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_GENERATOR, '0.5 0.5 0.5');
\r
709 if(e.team == COLOR_TEAM1 || e.team == COLOR_TEAM2)
\r
710 WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_GENERATOR, colormapPaletteColor(e.team - 1, FALSE));
\r
712 WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_GENERATOR, '0.75 0.75 0.75');
\r
714 WaypointSprite_Ping(e.sprite);
\r
718 string onslaught_controlpoint_waypointsprite_for_team(entity e, float t)
\r
723 a = onslaught_controlpoint_attackable(e, t);
\r
724 if(a == 3 || a == 4) // ATTACK/TOUCH THIS ONE NOW
\r
726 if(e.team == COLOR_TEAM1)
\r
727 return "ons-cp-atck-red";
\r
728 else if(e.team == COLOR_TEAM2)
\r
729 return "ons-cp-atck-blue";
\r
731 return "ons-cp-atck-neut";
\r
733 else if(a == -2) // DEFEND THIS ONE NOW
\r
735 if(e.team == COLOR_TEAM1)
\r
736 return "ons-cp-dfnd-red";
\r
737 else if(e.team == COLOR_TEAM2)
\r
738 return "ons-cp-dfnd-blue";
\r
740 else if(e.team == t || a == -1 || a == 1) // own point, or fire at it
\r
742 if(e.team == COLOR_TEAM1)
\r
743 return "ons-cp-red";
\r
744 else if(e.team == COLOR_TEAM2)
\r
745 return "ons-cp-blue";
\r
747 else if(a == 2) // touch it
\r
748 return "ons-cp-neut";
\r
752 if(e.team == COLOR_TEAM1)
\r
753 return "ons-cp-red";
\r
754 else if(e.team == COLOR_TEAM2)
\r
755 return "ons-cp-blue";
\r
757 return "ons-cp-neut";
\r
762 void onslaught_controlpoint_updatesprite(entity e)
\r
765 s1 = onslaught_controlpoint_waypointsprite_for_team(e, COLOR_TEAM1);
\r
766 s2 = onslaught_controlpoint_waypointsprite_for_team(e, COLOR_TEAM2);
\r
767 s3 = onslaught_controlpoint_waypointsprite_for_team(e, -1);
\r
768 WaypointSprite_UpdateSprites(e.sprite, s1, s2, s3);
\r
771 sh = !(onslaught_controlpoint_can_be_linked(e, COLOR_TEAM1) || onslaught_controlpoint_can_be_linked(e, COLOR_TEAM2));
\r
773 if(e.lastteam != e.team + 2 || e.lastshielded != sh || e.iscaptured != e.lastcaptured)
\r
775 if(e.iscaptured) // don't mess up build bars!
\r
779 WaypointSprite_UpdateMaxHealth(e.sprite, 0);
\r
783 WaypointSprite_UpdateMaxHealth(e.sprite, e.goalentity.max_health);
\r
784 WaypointSprite_UpdateHealth(e.sprite, e.goalentity.health);
\r
789 if(e.team == COLOR_TEAM1 || e.team == COLOR_TEAM2)
\r
790 WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_CONTROLPOINT, 0.5 * colormapPaletteColor(e.team - 1, FALSE));
\r
792 WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_CONTROLPOINT, '0.5 0.5 0.5');
\r
796 if(e.team == COLOR_TEAM1 || e.team == COLOR_TEAM2)
\r
797 WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_CONTROLPOINT, colormapPaletteColor(e.team - 1, FALSE));
\r
799 WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_CONTROLPOINT, '0.75 0.75 0.75');
\r
801 WaypointSprite_Ping(e.sprite);
\r
803 e.lastteam = e.team + 2;
\r
804 e.lastshielded = sh;
\r
805 e.lastcaptured = e.iscaptured;
\r
809 void onslaught_generator_reset()
\r
811 self.team = self.team_saved;
\r
812 self.lasthealth = self.max_health = self.health = cvar("g_onslaught_gen_health");
\r
813 self.takedamage = DAMAGE_AIM;
\r
814 self.bot_attack = TRUE;
\r
815 self.iscaptured = TRUE;
\r
816 self.islinked = TRUE;
\r
817 self.isshielded = TRUE;
\r
818 self.enemy.solid = SOLID_NOT;
\r
819 self.think = onslaught_generator_delayed;
\r
820 self.nextthink = time + 0.2;
\r
821 setmodel(self, "models/onslaught/generator.md3");
\r
823 WaypointSprite_UpdateMaxHealth(self.sprite, self.max_health);
\r
824 WaypointSprite_UpdateHealth(self.sprite, self.health);
\r
827 /*QUAKED spawnfunc_onslaught_generator (0 .5 .8) (-32 -32 -24) (32 32 64)
\r
830 spawnfunc_onslaught_link entities can target this.
\r
833 "team" - team that owns this generator (5 = red, 14 = blue, etc), MUST BE SET.
\r
834 "targetname" - name that spawnfunc_onslaught_link entities will use to target this.
\r
836 void spawnfunc_onslaught_generator()
\r
845 precache_model("models/onslaught/generator.md3");
\r
846 precache_model("models/onslaught/generator_shield.md3");
\r
847 precache_model("models/onslaught/generator_dmg1.md3");
\r
848 precache_model("models/onslaught/generator_dmg2.md3");
\r
849 precache_model("models/onslaught/generator_dmg3.md3");
\r
850 precache_model("models/onslaught/generator_dmg4.md3");
\r
851 precache_model("models/onslaught/generator_dmg5.md3");
\r
852 precache_model("models/onslaught/generator_dmg6.md3");
\r
853 precache_model("models/onslaught/generator_dmg7.md3");
\r
854 precache_model("models/onslaught/generator_dmg8.md3");
\r
855 precache_model("models/onslaught/generator_dmg9.md3");
\r
856 precache_model("models/onslaught/generator_dead.md3");
\r
857 precache_model("models/onslaught/shockwave.md3");
\r
858 precache_model("models/onslaught/shockwavetransring.md3");
\r
859 precache_model("models/onslaught/gen_gib1.md3");
\r
860 precache_model("models/onslaught/gen_gib2.md3");
\r
861 precache_model("models/onslaught/gen_gib3.md3");
\r
862 precache_model("models/onslaught/ons_ray.md3");
\r
863 precache_sound("onslaught/generator_decay.wav");
\r
864 precache_sound("weapons/grenade_impact.wav");
\r
865 precache_sound("weapons/rocket_impact.wav");
\r
866 precache_sound("onslaught/generator_underattack.wav");
\r
867 precache_sound("onslaught/shockwave.wav");
\r
868 precache_sound("onslaught/ons_hit1.wav");
\r
869 precache_sound("onslaught/ons_hit2.wav");
\r
870 precache_sound("onslaught/electricity_explode.wav");
\r
872 objerror("team must be set");
\r
873 self.team_saved = self.team;
\r
874 self.colormap = 1024 + (self.team - 1) * 17;
\r
875 self.solid = SOLID_BBOX;
\r
876 self.movetype = MOVETYPE_NONE;
\r
877 self.lasthealth = self.max_health = self.health = cvar("g_onslaught_gen_health");
\r
878 setmodel(self, "models/onslaught/generator.md3");
\r
879 setsize(self, '-52 -52 -14', '52 52 75');
\r
880 setorigin(self, self.origin);
\r
881 self.takedamage = DAMAGE_AIM;
\r
882 self.bot_attack = TRUE;
\r
883 self.event_damage = onslaught_generator_damage;
\r
884 self.iscaptured = TRUE;
\r
885 self.islinked = TRUE;
\r
886 self.isshielded = TRUE;
\r
887 // helper entity that create fx when generator is damaged
\r
888 onslaught_generator_damage_spawn(self);
\r
889 // spawn shield model which indicates whether this can be damaged
\r
890 self.enemy = e = spawn();
\r
891 e.classname = "onslaught_generator_shield";
\r
892 e.solid = SOLID_NOT;
\r
893 e.movetype = MOVETYPE_NONE;
\r
894 e.effects = EF_ADDITIVE;
\r
895 setmodel(e, "models/onslaught/generator_shield.md3");
\r
896 setorigin(e, self.origin);
\r
897 e.colormap = self.colormap;
\r
898 e.team = self.team;
\r
899 self.think = onslaught_generator_delayed;
\r
900 self.nextthink = time + 0.2;
\r
901 InitializeEntity(self, onslaught_generator_delayed, INITPRIO_LAST);
\r
903 WaypointSprite_SpawnFixed(string_null, e.origin + '0 0 1' * e.maxs_z, self, sprite);
\r
904 WaypointSprite_UpdateRule(self.sprite, COLOR_TEAM2, SPRITERULE_TEAMPLAY);
\r
905 WaypointSprite_UpdateMaxHealth(self.sprite, self.max_health);
\r
906 WaypointSprite_UpdateHealth(self.sprite, self.health);
\r
908 waypoint_spawnforitem(self);
\r
910 onslaught_updatelinks();
\r
912 self.reset = onslaught_generator_reset;
\r
917 .vector cp_origin, cp_bob_origin, cp_bob_dmg;
\r
919 float ons_notification_time_team1;
\r
920 float ons_notification_time_team2;
\r
922 void onslaught_controlpoint_icon_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
\r
929 if (self.owner.isshielded)
\r
931 // this is protected by a shield, so ignore the damage
\r
932 if (time > self.pain_finished)
\r
933 if (attacker.classname == "player")
\r
935 play2(attacker, "onslaught/damageblockedbyshield.wav");
\r
936 self.pain_finished = time + 1;
\r
941 if (attacker.classname == "player")
\r
943 if(self.team == COLOR_TEAM1)
\r
945 if(time - ons_notification_time_team1 > 10)
\r
948 ons_notification_time_team1 = time;
\r
951 else if(self.team == COLOR_TEAM2)
\r
953 if(time - ons_notification_time_team2 > 10)
\r
956 ons_notification_time_team2 = time;
\r
963 play2team(self.team, "onslaught/controlpoint_underattack.wav");
\r
966 self.health = self.health - damage;
\r
967 if(self.owner.iscaptured)
\r
968 WaypointSprite_UpdateHealth(self.owner.sprite, self.health);
\r
970 WaypointSprite_UpdateBuildFinished(self.owner.sprite, time + (self.max_health - self.health) / (self.count / sys_frametime));
\r
971 self.pain_finished = time + 1;
\r
972 self.punchangle = (2 * randomvec() - '1 1 1') * 45;
\r
973 self.cp_bob_dmg_z = (2 * random() - 1) * 15;
\r
974 // colormod flash when shot
\r
975 self.colormod = '2 2 2';
\r
976 // particles on every hit
\r
977 pointparticles(particleeffectnum("sparks"), hitloc, force*-1, 1);
\r
978 //sound on every hit
\r
979 if (random() < 0.5)
\r
980 sound(self, CHAN_TRIGGER, "onslaught/ons_hit1.wav", VOL_BASE+0.3, ATTN_NORM);
\r
982 sound(self, CHAN_TRIGGER, "onslaught/ons_hit2.wav", VOL_BASE+0.3, ATTN_NORM);
\r
984 if (self.health < 0)
\r
986 sound(self, CHAN_TRIGGER, "weapons/grenade_impact.wav", VOL_BASE, ATTN_NORM);
\r
987 pointparticles(particleeffectnum("rocket_explode"), self.origin, '0 0 0', 1);
\r
990 t = ColoredTeamName(attacker.team);
\r
991 bprint(ColoredTeamName(self.team), " ", self.message, " control point destroyed by ", t, "\n");
\r
992 ons_throwgib(self.origin, (2 * randomvec() - '1 1 1') * 25, "models/onslaught/controlpoint_icon_gib1.md3", 3, FALSE);
\r
993 ons_throwgib(self.origin, (2 * randomvec() - '1 1 1') * 45, "models/onslaught/controlpoint_icon_gib2.md3", 3, FALSE);
\r
994 ons_throwgib(self.origin, (2 * randomvec() - '1 1 1') * 45, "models/onslaught/controlpoint_icon_gib2.md3", 3, FALSE);
\r
995 ons_throwgib(self.origin, (2 * randomvec() - '1 1 1') * 75, "models/onslaught/controlpoint_icon_gib4.md3", 3, FALSE);
\r
996 ons_throwgib(self.origin, (2 * randomvec() - '1 1 1') * 75, "models/onslaught/controlpoint_icon_gib4.md3", 3, FALSE);
\r
997 ons_throwgib(self.origin, (2 * randomvec() - '1 1 1') * 75, "models/onslaught/controlpoint_icon_gib4.md3", 3, FALSE);
\r
998 ons_throwgib(self.origin, (2 * randomvec() - '1 1 1') * 75, "models/onslaught/controlpoint_icon_gib4.md3", 3, FALSE);
\r
1000 self.owner.goalentity = world;
\r
1001 self.owner.islinked = FALSE;
\r
1002 self.owner.iscaptured = FALSE;
\r
1003 self.owner.team = 0;
\r
1004 self.owner.colormap = 1024;
\r
1006 WaypointSprite_UpdateMaxHealth(self.owner.sprite, 0);
\r
1008 onslaught_updatelinks();
\r
1010 // Use targets now (somebody make sure this is in the right place..)
\r
1012 self = self.owner;
\r
1014 SUB_UseTargets ();
\r
1018 self.owner.waslinked = self.owner.islinked;
\r
1019 if(self.owner.model != "models/onslaught/controlpoint_pad.md3")
\r
1020 setmodel(self.owner, "models/onslaught/controlpoint_pad.md3");
\r
1021 //setsize(self, '-32 -32 0', '32 32 8');
\r
1027 void onslaught_controlpoint_icon_think()
\r
1030 self.nextthink = time + sys_frametime;
\r
1031 if (time > self.pain_finished + 5)
\r
1033 if(self.health < self.max_health)
\r
1035 self.health = self.health + self.count;
\r
1036 if (self.health >= self.max_health)
\r
1037 self.health = self.max_health;
\r
1038 WaypointSprite_UpdateHealth(self.owner.sprite, self.health);
\r
1041 if (self.health < self.max_health * 0.25)
\r
1042 setmodel(self, "models/onslaught/controlpoint_icon_dmg3.md3");
\r
1043 else if (self.health < self.max_health * 0.50)
\r
1044 setmodel(self, "models/onslaught/controlpoint_icon_dmg2.md3");
\r
1045 else if (self.health < self.max_health * 0.75)
\r
1046 setmodel(self, "models/onslaught/controlpoint_icon_dmg1.md3");
\r
1047 else if (self.health < self.max_health * 0.90)
\r
1048 setmodel(self, "models/onslaught/controlpoint_icon.md3");
\r
1049 // colormod flash when shot
\r
1050 self.colormod = '1 1 1' * (2 - bound(0, (self.pain_finished - time) / 10, 1));
\r
1052 if(self.owner.islinked != self.owner.waslinked)
\r
1054 // unteam the spawnpoint if needed
\r
1056 t = self.owner.team;
\r
1057 if(!self.owner.islinked)
\r
1058 self.owner.team = 0;
\r
1061 self = self.owner;
\r
1063 SUB_UseTargets ();
\r
1066 self.owner.team = t;
\r
1068 self.owner.waslinked = self.owner.islinked;
\r
1070 if (self.punchangle_x > 2)
\r
1071 self.punchangle_x = self.punchangle_x - 2;
\r
1072 else if (self.punchangle_x < -2)
\r
1073 self.punchangle_x = self.punchangle_x + 2;
\r
1075 self.punchangle_x = 0;
\r
1076 if (self.punchangle_y > 2)
\r
1077 self.punchangle_y = self.punchangle_y - 2;
\r
1078 else if (self.punchangle_y < -2)
\r
1079 self.punchangle_y = self.punchangle_y + 2;
\r
1081 self.punchangle_y = 0;
\r
1082 if (self.punchangle_z > 2)
\r
1083 self.punchangle_z = self.punchangle_z - 2;
\r
1084 else if (self.punchangle_z < -2)
\r
1085 self.punchangle_z = self.punchangle_z + 2;
\r
1087 self.punchangle_z = 0;
\r
1088 self.angles_x = self.punchangle_x;
\r
1089 self.angles_y = self.punchangle_y + self.mangle_y;
\r
1090 self.angles_z = self.punchangle_z;
\r
1091 self.mangle_y = self.mangle_y + 1.5;
\r
1093 self.cp_bob_origin_z = 4 * PI * (1 - cos(self.cp_bob_spd / 8));
\r
1094 self.cp_bob_spd = self.cp_bob_spd + 0.5;
\r
1095 if(self.cp_bob_dmg_z > 0)
\r
1096 self.cp_bob_dmg_z = self.cp_bob_dmg_z - 0.1;
\r
1098 self.cp_bob_dmg_z = 0;
\r
1099 setorigin(self,self.cp_origin + self.cp_bob_origin + self.cp_bob_dmg);
\r
1102 if(random() < 0.6 - self.health / self.max_health)
\r
1104 pointparticles(particleeffectnum("electricity_sparks"), self.origin + randompos('-10 -10 -20', '10 10 20'), '0 0 0', 1);
\r
1106 if(random() > 0.8)
\r
1107 sound(self, CHAN_PAIN, "onslaught/ons_spark1.wav", VOL_BASE, ATTN_NORM);
\r
1108 else if (random() > 0.5)
\r
1109 sound(self, CHAN_PAIN, "onslaught/ons_spark2.wav", VOL_BASE, ATTN_NORM);
\r
1113 void onslaught_controlpoint_icon_buildthink()
\r
1115 local entity oself;
\r
1118 self.nextthink = time + sys_frametime;
\r
1120 // only do this if there is power
\r
1121 a = onslaught_controlpoint_can_be_linked(self.owner, self.owner.team);
\r
1125 self.health = self.health + self.count;
\r
1127 if (self.health >= self.max_health)
\r
1129 self.health = self.max_health;
\r
1130 self.count = cvar("g_onslaught_cp_regen") * sys_frametime; // slow repair rate from now on
\r
1131 self.think = onslaught_controlpoint_icon_think;
\r
1132 sound(self, CHAN_TRIGGER, "onslaught/controlpoint_built.wav", VOL_BASE, ATTN_NORM);
\r
1133 bprint(ColoredTeamName(self.team), " captured ", self.owner.message, " control point\n");
\r
1134 self.owner.iscaptured = TRUE;
\r
1136 WaypointSprite_UpdateMaxHealth(self.owner.sprite, self.max_health);
\r
1137 WaypointSprite_UpdateHealth(self.owner.sprite, self.health);
\r
1139 onslaught_updatelinks();
\r
1141 // Use targets now (somebody make sure this is in the right place..)
\r
1143 self = self.owner;
\r
1145 SUB_UseTargets ();
\r
1147 self.cp_origin = self.origin;
\r
1148 self.cp_bob_origin = '0 0 0.1';
\r
1149 self.cp_bob_spd = 0;
\r
1151 self.alpha = self.health / self.max_health;
\r
1152 // colormod flash when shot
\r
1153 self.colormod = '1 1 1' * (2 - bound(0, (self.pain_finished - time) / 10, 1));
\r
1154 if(self.owner.model != "models/onslaught/controlpoint_pad2.md3")
\r
1155 setmodel(self.owner, "models/onslaught/controlpoint_pad2.md3");
\r
1156 //setsize(self, '-32 -32 0', '32 32 8');
\r
1158 if(random() < 0.9 - self.health / self.max_health)
\r
1159 pointparticles(particleeffectnum("rage"), self.origin + 10 * randomvec(), '0 0 -1', 1);
\r
1165 void onslaught_controlpoint_touch()
\r
1169 if (other.classname != "player")
\r
1171 a = onslaught_controlpoint_attackable(self, other.team);
\r
1172 if(a != 2 && a != 4)
\r
1174 // we've verified that this player has a legitimate claim to this point,
\r
1175 // so start building the captured point icon (which only captures this
\r
1176 // point if it successfully builds without being destroyed first)
\r
1177 self.goalentity = e = spawn();
\r
1178 e.classname = "onslaught_controlpoint_icon";
\r
1180 e.max_health = cvar("g_onslaught_cp_health");
\r
1181 e.health = cvar("g_onslaught_cp_buildhealth");
\r
1182 e.solid = SOLID_BBOX;
\r
1183 e.movetype = MOVETYPE_NONE;
\r
1184 setmodel(e, "models/onslaught/controlpoint_icon.md3");
\r
1185 setsize(e, '-32 -32 -32', '32 32 32');
\r
1186 setorigin(e, self.origin + '0 0 96');
\r
1187 e.takedamage = DAMAGE_AIM;
\r
1188 e.bot_attack = TRUE;
\r
1189 e.event_damage = onslaught_controlpoint_icon_damage;
\r
1190 e.team = other.team;
\r
1191 e.colormap = 1024 + (e.team - 1) * 17;
\r
1192 e.think = onslaught_controlpoint_icon_buildthink;
\r
1193 e.nextthink = time + sys_frametime;
\r
1194 e.count = (e.max_health - e.health) * sys_frametime / cvar("g_onslaught_cp_buildtime"); // how long it takes to build
\r
1195 sound(e, CHAN_TRIGGER, "onslaught/controlpoint_build.wav", VOL_BASE, ATTN_NORM);
\r
1196 self.team = e.team;
\r
1197 self.colormap = e.colormap;
\r
1198 WaypointSprite_UpdateBuildFinished(self.sprite, time + (e.max_health - e.health) / (e.count / sys_frametime));
\r
1199 onslaught_updatelinks();
\r
1202 void onslaught_controlpoint_reset()
\r
1204 if(self.goalentity && self.goalentity != world)
\r
1205 remove(self.goalentity);
\r
1206 self.goalentity = world;
\r
1208 self.colormap = 1024;
\r
1209 self.iscaptured = FALSE;
\r
1210 self.islinked = FALSE;
\r
1211 self.isshielded = TRUE;
\r
1212 self.enemy.solid = SOLID_NOT;
\r
1213 self.enemy.colormap = self.colormap;
\r
1214 self.think = self.enemy.think = SUB_Null;
\r
1215 self.nextthink = 0; // don't like SUB_Null :P
\r
1216 setmodel(self, "models/onslaught/controlpoint_pad.md3");
\r
1217 //setsize(self, '-32 -32 0', '32 32 8');
\r
1219 WaypointSprite_UpdateMaxHealth(self.sprite, 0);
\r
1221 onslaught_updatelinks();
\r
1224 SUB_UseTargets(); // to reset the structures, playerspawns etc.
\r
1227 /*QUAKED spawnfunc_onslaught_controlpoint (0 .5 .8) (-32 -32 0) (32 32 128)
\r
1228 Control point. Be sure to give this enough clearance so that the shootable part has room to exist
\r
1230 This should link to an spawnfunc_onslaught_controlpoint entity or spawnfunc_onslaught_generator entity.
\r
1233 "targetname" - name that spawnfunc_onslaught_link entities will use to target this.
\r
1234 "target" - target any entities that are tied to this control point, such as vehicles and buildable structure entities.
\r
1235 "message" - name of this control point (should reflect the location in the map, such as "center bridge", "north tower", etc)
\r
1237 void spawnfunc_onslaught_controlpoint()
\r
1245 precache_model("models/onslaught/controlpoint_pad.md3");
\r
1246 precache_model("models/onslaught/controlpoint_pad2.md3");
\r
1247 precache_model("models/onslaught/controlpoint_shield.md3");
\r
1248 precache_model("models/onslaught/controlpoint_icon.md3");
\r
1249 precache_model("models/onslaught/controlpoint_icon_dmg1.md3");
\r
1250 precache_model("models/onslaught/controlpoint_icon_dmg2.md3");
\r
1251 precache_model("models/onslaught/controlpoint_icon_dmg3.md3");
\r
1252 precache_model("models/onslaught/controlpoint_icon_gib1.md3");
\r
1253 precache_model("models/onslaught/controlpoint_icon_gib2.md3");
\r
1254 precache_model("models/onslaught/controlpoint_icon_gib4.md3");
\r
1255 precache_sound("onslaught/controlpoint_build.wav");
\r
1256 precache_sound("onslaught/controlpoint_built.wav");
\r
1257 precache_sound("weapons/grenade_impact.wav");
\r
1258 precache_sound("onslaught/damageblockedbyshield.wav");
\r
1259 precache_sound("onslaught/controlpoint_underattack.wav");
\r
1260 precache_sound("onslaught/ons_spark1.wav");
\r
1261 precache_sound("onslaught/ons_spark2.wav");
\r
1262 self.solid = SOLID_BBOX;
\r
1263 self.movetype = MOVETYPE_NONE;
\r
1264 setmodel(self, "models/onslaught/controlpoint_pad.md3");
\r
1265 //setsize(self, '-32 -32 0', '32 32 8');
\r
1266 setorigin(self, self.origin);
\r
1267 self.touch = onslaught_controlpoint_touch;
\r
1269 self.colormap = 1024;
\r
1270 self.iscaptured = FALSE;
\r
1271 self.islinked = FALSE;
\r
1272 self.isshielded = TRUE;
\r
1273 // spawn shield model which indicates whether this can be damaged
\r
1274 self.enemy = e = spawn();
\r
1275 e.classname = "onslaught_controlpoint_shield";
\r
1276 e.solid = SOLID_NOT;
\r
1277 e.movetype = MOVETYPE_NONE;
\r
1278 e.effects = EF_ADDITIVE;
\r
1279 setmodel(e, "models/onslaught/controlpoint_shield.md3");
\r
1280 //setsize(e, '-32 -32 0', '32 32 128');
\r
1281 setorigin(e, self.origin);
\r
1282 e.colormap = self.colormap;
\r
1284 waypoint_spawnforitem(self);
\r
1286 WaypointSprite_SpawnFixed(string_null, e.origin + '0 0 1' * e.maxs_z, self, sprite);
\r
1287 WaypointSprite_UpdateRule(self.sprite, COLOR_TEAM2, SPRITERULE_TEAMPLAY);
\r
1289 onslaught_updatelinks();
\r
1291 self.reset = onslaught_controlpoint_reset;
\r
1294 float onslaught_link_send(entity to, float sendflags)
\r
1296 WriteByte(MSG_ENTITY, ENT_CLIENT_RADARLINK);
\r
1297 WriteByte(MSG_ENTITY, sendflags);
\r
1300 WriteCoord(MSG_ENTITY, self.goalentity.origin_x);
\r
1301 WriteCoord(MSG_ENTITY, self.goalentity.origin_y);
\r
1302 WriteCoord(MSG_ENTITY, self.goalentity.origin_z);
\r
1306 WriteCoord(MSG_ENTITY, self.enemy.origin_x);
\r
1307 WriteCoord(MSG_ENTITY, self.enemy.origin_y);
\r
1308 WriteCoord(MSG_ENTITY, self.enemy.origin_z);
\r
1312 WriteByte(MSG_ENTITY, self.clientcolors); // which is goalentity's color + enemy's color * 16
\r
1317 void onslaught_link_checkupdate()
\r
1319 // TODO check if the two sides have moved (currently they won't move anyway)
\r
1320 float redpower, bluepower;
\r
1322 redpower = bluepower = 0;
\r
1323 if(self.goalentity.islinked)
\r
1325 if(self.goalentity.team == COLOR_TEAM1)
\r
1327 else if(self.goalentity.team == COLOR_TEAM2)
\r
1330 if(self.enemy.islinked)
\r
1332 if(self.enemy.team == COLOR_TEAM1)
\r
1334 else if(self.enemy.team == COLOR_TEAM2)
\r
1339 if(redpower == 1 && bluepower == 2)
\r
1340 cc = (COLOR_TEAM1 - 1) * 0x01 + (COLOR_TEAM2 - 1) * 0x10;
\r
1341 else if(redpower == 2 && bluepower == 1)
\r
1342 cc = (COLOR_TEAM1 - 1) * 0x10 + (COLOR_TEAM2 - 1) * 0x01;
\r
1344 cc = (COLOR_TEAM1 - 1) * 0x11;
\r
1345 else if(bluepower)
\r
1346 cc = (COLOR_TEAM2 - 1) * 0x11;
\r
1350 //print(etos(self), " rp=", ftos(redpower), " bp=", ftos(bluepower), " ");
\r
1351 //print("cc=", ftos(cc), "\n");
\r
1353 if(cc != self.clientcolors)
\r
1355 self.clientcolors = cc;
\r
1356 self.SendFlags |= 4;
\r
1359 self.nextthink = time;
\r
1362 void onslaught_link_delayed()
\r
1364 self.goalentity = find(world, targetname, self.target);
\r
1365 self.enemy = find(world, targetname, self.target2);
\r
1366 if (!self.goalentity)
\r
1367 objerror("can not find target\n");
\r
1369 objerror("can not find target2\n");
\r
1370 dprint(etos(self.goalentity), " linked with ", etos(self.enemy), "\n");
\r
1371 self.SendFlags |= 3;
\r
1372 self.think = onslaught_link_checkupdate;
\r
1373 self.nextthink = time;
\r
1376 /*QUAKED spawnfunc_onslaught_link (0 .5 .8) (-16 -16 -16) (16 16 16)
\r
1377 Link between control points.
\r
1379 This entity targets two different spawnfunc_onslaught_controlpoint or spawnfunc_onslaught_generator entities, and suppresses shielding on both if they are owned by different teams.
\r
1382 "target" - first control point.
\r
1383 "target2" - second control point.
\r
1385 void spawnfunc_onslaught_link()
\r
1392 if (self.target == "" || self.target2 == "")
\r
1393 objerror("target and target2 must be set\n");
\r
1394 InitializeEntity(self, onslaught_link_delayed, INITPRIO_FINDTARGET);
\r
1395 Net_LinkEntity(self, FALSE, 0, onslaught_link_send);
\r