1 void spawnfunc_item_minst_cells (void)
3 if not(g_minstagib) { remove(self); return; }
4 if not(self.ammo_cells)
5 self.ammo_cells = autocvar_g_minstagib_ammo_drop;
7 StartItem ("models/items/a_cells.md3",
8 "misc/itempickup.wav", 45, 0,
9 "MinstaNex Ammo", IT_CELLS, 0, 0, generic_pickupevalfunc, 100);
12 .float minstagib_nextthink;
13 .float minstagib_needammo;
14 void minstagib_stop_countdown(entity e)
16 if (!e.minstagib_needammo)
18 Send_CSQC_Centerprint_Generic_Expire(e, CPID_MINSTA_FINDAMMO);
19 e.minstagib_needammo = FALSE;
21 void minstagib_ammocheck(void)
23 if (time < self.minstagib_nextthink)
26 if (self.deadflag || gameover)
27 minstagib_stop_countdown(self);
28 else if (self.ammo_cells > 0 || (self.items & IT_UNLIMITED_WEAPON_AMMO))
30 minstagib_stop_countdown(self);
36 self.minstagib_needammo = TRUE;
39 Damage(self, self, self, 5, DEATH_NOAMMO, self.origin, '0 0 0');
40 AnnounceTo(self, "terminated");
42 else if (self.health == 10)
44 Damage(self, self, self, 5, DEATH_NOAMMO, self.origin, '0 0 0');
45 AnnounceTo(self, "1");
47 else if (self.health == 20)
49 Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
50 AnnounceTo(self, "2");
52 else if (self.health == 30)
54 Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
55 AnnounceTo(self, "3");
57 else if (self.health == 40)
59 Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
60 AnnounceTo(self, "4");
62 else if (self.health == 50)
64 Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
65 AnnounceTo(self, "5");
67 else if (self.health == 60)
69 Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
70 AnnounceTo(self, "6");
72 else if (self.health == 70)
74 Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
75 AnnounceTo(self, "7");
77 else if (self.health == 80)
79 Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
80 AnnounceTo(self, "8");
82 else if (self.health == 90)
84 Send_CSQC_Centerprint_Generic(self, CPID_MINSTA_FINDAMMO, "^1%d^7 seconds left to find some ammo", 1, 9);
85 Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
86 AnnounceTo(self, "9");
88 else if (self.health == 100)
90 Send_CSQC_Centerprint_Generic(self, CPID_MINSTA_FINDAMMO, "get some ammo or\nyou'll be dead in ^3%d^7 seconds...", 1, 10);
91 Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
92 if not(self.flags & FL_GODMODE)
93 AnnounceTo(self, "10");
96 self.minstagib_nextthink = time + 1;
99 MUTATOR_HOOKFUNCTION(minstagib_BotShouldAttack)
101 if(checkentity.items & IT_STRENGTH)
107 MUTATOR_HOOKFUNCTION(minstagib_MakePlayerObserver)
109 minstagib_stop_countdown(self);
113 MUTATOR_HOOKFUNCTION(minstagib_PlayerSpawn)
115 self.effects |= EF_FULLBRIGHT;
119 MUTATOR_HOOKFUNCTION(minstagib_PlayerPreThink)
121 minstagib_ammocheck();
125 MUTATOR_HOOKFUNCTION(minstagib_PlayerPowerups)
127 if not(self.effects & EF_FULLBRIGHT)
128 self.effects |= EF_FULLBRIGHT;
130 if (self.items & IT_STRENGTH)
132 play_countdown(self.strength_finished, "misc/poweroff.wav");
133 if (time > self.strength_finished)
135 self.alpha = default_player_alpha;
136 self.exteriorweaponentity.alpha = default_weapon_alpha;
137 self.items &~= IT_STRENGTH;
138 sprint(self, "^3Invisibility has worn off\n");
143 if (time < self.strength_finished)
145 self.alpha = g_minstagib_invis_alpha;
146 self.exteriorweaponentity.alpha = g_minstagib_invis_alpha;
147 self.items |= IT_STRENGTH;
148 sprint(self, "^3You are invisible\n");
152 if (self.items & IT_INVINCIBLE)
154 play_countdown(self.invincible_finished, "misc/poweroff.wav");
155 if (time > self.invincible_finished)
157 self.items &~= IT_INVINCIBLE;
158 sprint(self, "^3Speed has worn off\n");
163 if (time < self.invincible_finished)
165 self.items |= IT_INVINCIBLE;
166 sprint(self, "^3You are on speed\n");
172 MUTATOR_HOOKFUNCTION(minstagib_PlayerPhysics)
174 if(self.items & IT_INVINCIBLE)
175 self.stat_sv_maxspeed = self.stat_sv_maxspeed * autocvar_g_minstagib_speed_highspeed;
180 MUTATOR_HOOKFUNCTION(minstagib_SplitHealthArmor)
183 damage_take = frag_damage;
188 MUTATOR_HOOKFUNCTION(minstagib_ForbidThrowing)
196 MUTATOR_HOOKFUNCTION(minstagib_PlayStrengthSound)
198 // You shall not play!
202 MUTATOR_HOOKFUNCTION(minstagib_PlayerDamage)
204 if(autocvar_g_friendlyfire == 0)
207 if(frag_target.classname == "player")
209 if ((frag_deathtype == DEATH_FALL) ||
210 (frag_deathtype == DEATH_DROWN) ||
211 (frag_deathtype == DEATH_SLIME) ||
212 (frag_deathtype == DEATH_LAVA))
217 if (frag_target.armorvalue && (frag_deathtype == WEP_MINSTANEX) && frag_damage)
219 frag_target.armorvalue -= 1;
220 centerprint(frag_target, strcat("^3Remaining extra lives: ",ftos(frag_target.armorvalue)));
222 frag_target.hitsound += 1;
223 frag_attacker.hitsound += 1; // TODO change this to a future specific hitsound for armor hit
225 if (DEATH_ISWEAPON(frag_deathtype, WEP_LASER))
228 frag_mirrordamage = 0;
229 if (frag_target != frag_attacker)
231 if ((frag_target.health >= 1) && (frag_target.classname == "player"))
232 centerprint(frag_attacker, "Secondary fire inflicts no damage!");
233 frag_force = '0 0 0';
234 // keep mirrorfrag_force
235 frag_attacker = frag_target;
240 if(frag_mirrordamage > 0)
242 // just lose extra LIVES, don't kill the player for mirror damage
243 if(frag_attacker.armorvalue > 0)
245 frag_attacker.armorvalue = frag_attacker.armorvalue - 1;
246 centerprint(frag_attacker, strcat("^3Remaining extra lives: ", ftos(frag_attacker.armorvalue)));
247 frag_attacker.hitsound += 1;
249 frag_mirrordamage = 0;
252 if(frag_target.items & IT_STRENGTH)
258 MUTATOR_HOOKFUNCTION(minstagib_SetStartItems)
260 start_ammo_cells = cvar("g_minstagib_ammo_start");
262 g_pinata = 0; // incompatible
263 g_weapon_stay = 0; // incompatible
264 g_bloodloss = 0; // incompatible
266 start_armorvalue = 0;
267 WEPSET_COPY_AW(start_weapons, WEP_MINSTANEX);
268 g_minstagib_invis_alpha = cvar("g_minstagib_invis_alpha");
269 start_items |= IT_UNLIMITED_SUPERWEAPONS;
271 if (g_minstagib_invis_alpha <= 0)
272 g_minstagib_invis_alpha = -1;
277 MUTATOR_HOOKFUNCTION(minstagib_FilterItem)
279 if(self.classname == "item_cells")
280 return TRUE; // no normal cells?
282 if(self.weapon == WEP_MINSTANEX && self.classname == "droppedweapon")
284 self.ammo_cells = autocvar_g_minstagib_ammo_drop;
288 if(self.weapon == WEP_ROCKET_LAUNCHER || self.weapon == WEP_NEX)
291 setorigin(e, self.origin);
295 spawnfunc_item_minst_cells();
300 if(self.flags & FL_POWERUP)
303 if(self.ammo_cells > autocvar_g_minstagib_ammo_drop && self.classname != "item_minst_cells")
304 self.ammo_cells = autocvar_g_minstagib_ammo_drop;
306 if(self.ammo_cells && !self.weapon)
312 MUTATOR_HOOKFUNCTION(minstagib_ItemCountdown)
316 case IT_STRENGTH: item_name = "item-invis"; item_color = '0 0 1'; break;
317 case IT_NAILS: item_name = "item-extralife"; item_color = '1 0 0'; break;
318 case IT_INVINCIBLE: item_name = "item-speed"; item_color = '1 0 1'; break;
323 MUTATOR_HOOKFUNCTION(minstagib_GiveItem)
326 float prevcells = giveplayer.ammo_cells;
328 player_pickedup |= Item_GiveAmmoTo(giveitem, giveplayer, ammo_cells, 999, ITEM_MODE_NONE);
330 if(giveplayer.ammo_cells > prevcells)
332 player_wswitch = TRUE;
333 // play some cool sounds ;)
334 if (clienttype(giveplayer) == CLIENTTYPE_REAL)
336 if(giveplayer.health <= 5)
337 AnnounceTo(giveplayer, "lastsecond");
338 else if(giveplayer.health < 50)
339 AnnounceTo(giveplayer, "narrowly");
342 if (WEPSET_CONTAINS_EW(giveitem, WEP_MINSTANEX))
343 W_GiveWeapon (giveplayer, WEP_MINSTANEX, giveitem.netname);
344 if(giveplayer.health < 100)
345 giveplayer.health = 100;
348 if((it = (giveitem.items - (giveitem.items & giveplayer.items)) & IT_PICKUPMASK))
350 player_pickedup = TRUE;
351 giveplayer.items |= it;
352 sprint (giveplayer, strcat("You got the ^2", giveitem.netname, "\n"));
356 if (giveitem.max_health)
358 player_pickedup = TRUE;
359 // sound not available
360 // AnnounceTo(giveplayer, "_lives");
361 giveplayer.armorvalue = bound(giveplayer.armorvalue, 999, giveplayer.armorvalue + autocvar_g_minstagib_extralives);
362 sprint(giveplayer, "^3You picked up some extra lives\n");
366 if (giveitem.strength_finished)
368 player_pickedup = TRUE;
369 // sound not available
370 // AnnounceTo(giveplayer, "invisible");
371 giveplayer.strength_finished = max(giveplayer.strength_finished, time) + autocvar_g_balance_powerup_strength_time;
375 if (giveitem.invincible_finished)
377 player_pickedup = TRUE;
378 // sound not available
379 // AnnounceTo(giveplayer, "speed");
380 giveplayer.invincible_finished = max(giveplayer.invincible_finished, time) + autocvar_g_balance_powerup_invincible_time;
386 MUTATOR_HOOKFUNCTION(minstagib_BuildMutatorsString)
388 ret_string = strcat(ret_string, ":MinstaGib");
392 MUTATOR_HOOKFUNCTION(minstagib_BuildMutatorsPrettyString)
394 ret_string = strcat(ret_string, ", MinstaGib");
398 MUTATOR_DEFINITION(mutator_minstagib)
400 MUTATOR_HOOK(BotShouldAttack, minstagib_BotShouldAttack, CBC_ORDER_ANY);
401 MUTATOR_HOOK(PlayerPhysics, minstagib_PlayerPhysics, CBC_ORDER_ANY);
402 MUTATOR_HOOK(PlayerSpawn, minstagib_PlayerSpawn, CBC_ORDER_ANY);
403 MUTATOR_HOOK(PlayerDamage_Calculate, minstagib_PlayerDamage, CBC_ORDER_ANY);
404 MUTATOR_HOOK(PlayStrengthSound, minstagib_PlayStrengthSound, CBC_ORDER_ANY);
405 MUTATOR_HOOK(MakePlayerObserver, minstagib_MakePlayerObserver, CBC_ORDER_ANY);
406 MUTATOR_HOOK(SetStartItems, minstagib_SetStartItems, CBC_ORDER_ANY);
407 MUTATOR_HOOK(FilterItem, minstagib_FilterItem, CBC_ORDER_ANY);
408 MUTATOR_HOOK(Item_RespawnCountdown, minstagib_ItemCountdown, CBC_ORDER_ANY);
409 MUTATOR_HOOK(PlayerDamage_SplitHealthArmor, minstagib_SplitHealthArmor, CBC_ORDER_ANY);
410 MUTATOR_HOOK(PlayerPowerups, minstagib_PlayerPowerups, CBC_ORDER_ANY);
411 MUTATOR_HOOK(ForbidThrowCurrentWeapon, minstagib_ForbidThrowing, CBC_ORDER_ANY);
412 MUTATOR_HOOK(PlayerPreThink, minstagib_PlayerPreThink, CBC_ORDER_ANY);
413 MUTATOR_HOOK(BuildMutatorsString, minstagib_BuildMutatorsString, CBC_ORDER_ANY);
414 MUTATOR_HOOK(BuildMutatorsPrettyString, minstagib_BuildMutatorsPrettyString, CBC_ORDER_ANY);