-void spawnfunc_item_minst_cells (void)
+void spawnfunc_item_minst_cells (void)
{
- if not(g_minstagib)
- {
- remove(self);
- return;
- }
+ if (!g_minstagib) { remove(self); return; }
+ if (!self.ammo_cells)
+ self.ammo_cells = autocvar_g_minstagib_ammo_drop;
+
+ StartItem ("models/items/a_cells.md3",
+ "misc/itempickup.wav", 45, 0,
+ "MinstaNex Ammo", IT_CELLS, 0, 0, generic_pickupevalfunc, 100);
+}
+
+void minstagib_health_mega()
+{
+ self.max_health = 1;
+ StartItem ("models/items/g_h100.md3",
+ "misc/megahealth.wav", g_pickup_respawntime_powerup, g_pickup_respawntimejitter_powerup,
+ "Extralife", IT_NAILS, 0, FL_POWERUP, generic_pickupevalfunc, BOT_PICKUP_RATING_HIGH);
}
.float minstagib_nextthink;
{
if (!e.minstagib_needammo)
return;
- Send_CSQC_Centerprint_Generic_Expire(e, CPID_MINSTA_FINDAMMO);
+ Kill_Notification(NOTIF_ONE_ONLY, e, MSG_CENTER_CPID, CPID_MINSTA_FINDAMMO);
e.minstagib_needammo = FALSE;
}
-void minstagib_ammocheck(void)
+void minstagib_ammocheck()
{
+ if (!IS_PLAYER(self))
+ return; // not a player
if (time < self.minstagib_nextthink)
return;
if (self.deadflag || gameover)
minstagib_stop_countdown(self);
else if (self.ammo_cells > 0 || (self.items & IT_UNLIMITED_WEAPON_AMMO))
- {
minstagib_stop_countdown(self);
- if(self.health < 100)
- self.health = 100;
- }
else
{
self.minstagib_needammo = TRUE;
if (self.health == 5)
{
Damage(self, self, self, 5, DEATH_NOAMMO, self.origin, '0 0 0');
- AnnounceTo(self, "terminated");
+ Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_MINSTAGIB_TERMINATED);
}
else if (self.health == 10)
{
Damage(self, self, self, 5, DEATH_NOAMMO, self.origin, '0 0 0');
- AnnounceTo(self, "1");
+ Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_1);
}
else if (self.health == 20)
{
Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
- AnnounceTo(self, "2");
+ Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_2);
}
else if (self.health == 30)
{
Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
- AnnounceTo(self, "3");
+ Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_3);
}
else if (self.health == 40)
{
Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
- AnnounceTo(self, "4");
+ Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_4);
}
else if (self.health == 50)
{
Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
- AnnounceTo(self, "5");
+ Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_5);
}
else if (self.health == 60)
{
Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
- AnnounceTo(self, "6");
+ Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_6);
}
else if (self.health == 70)
{
Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
- AnnounceTo(self, "7");
+ Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_7);
}
else if (self.health == 80)
{
Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
- AnnounceTo(self, "8");
+ Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_8);
}
else if (self.health == 90)
{
- Send_CSQC_Centerprint_Generic(self, CPID_MINSTA_FINDAMMO, "^1%d^7 seconds left to find some ammo", 1, 9);
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_MINSTA_FINDAMMO);
Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
- AnnounceTo(self, "9");
+ Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_9);
}
else if (self.health == 100)
{
- Send_CSQC_Centerprint_Generic(self, CPID_MINSTA_FINDAMMO, "get some ammo or\nyou'll be dead in ^3%d^7 seconds...", 1, 10);
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_MULTI, MULTI_MINSTA_FINDAMMO);
Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
- if not(self.flags & FL_GODMODE)
- AnnounceTo(self, "10");
}
}
self.minstagib_nextthink = time + 1;
}
+MUTATOR_HOOKFUNCTION(minstagib_MatchEnd)
+{
+ entity head;
+ FOR_EACH_PLAYER(head)
+ minstagib_stop_countdown(head);
+
+ return FALSE;
+}
+
MUTATOR_HOOKFUNCTION(minstagib_BotShouldAttack)
{
if(checkentity.items & IT_STRENGTH)
return TRUE;
-
+
return FALSE;
}
MUTATOR_HOOKFUNCTION(minstagib_PlayerPowerups)
{
- if not(self.effects & EF_FULLBRIGHT)
+ if (!(self.effects & EF_FULLBRIGHT))
self.effects |= EF_FULLBRIGHT;
if (self.items & IT_STRENGTH)
{
self.alpha = default_player_alpha;
self.exteriorweaponentity.alpha = default_weapon_alpha;
- self.items &~= IT_STRENGTH;
- sprint(self, "^3Invisibility has worn off\n");
+ self.items &= ~IT_STRENGTH;
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERDOWN_INVISIBILITY);
}
}
else
{
if (time < self.strength_finished)
{
- self.alpha = g_minstagib_invis_alpha;
- self.exteriorweaponentity.alpha = g_minstagib_invis_alpha;
+ self.alpha = autocvar_g_minstagib_invis_alpha;
+ self.exteriorweaponentity.alpha = autocvar_g_minstagib_invis_alpha;
self.items |= IT_STRENGTH;
- sprint(self, "^3You are invisible\n");
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERUP_INVISIBILITY, self.netname);
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERUP_INVISIBILITY);
}
}
play_countdown(self.invincible_finished, "misc/poweroff.wav");
if (time > self.invincible_finished)
{
- self.items &~= IT_INVINCIBLE;
- sprint(self, "^3Speed has worn off\n");
+ self.items &= ~IT_INVINCIBLE;
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERDOWN_SPEED);
}
}
else
if (time < self.invincible_finished)
{
self.items |= IT_INVINCIBLE;
- sprint(self, "^3You are on speed\n");
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERUP_SPEED, self.netname);
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERUP_SPEED);
}
}
return FALSE;
{
if(self.items & IT_INVINCIBLE)
self.stat_sv_maxspeed = self.stat_sv_maxspeed * autocvar_g_minstagib_speed_highspeed;
-
+
return FALSE;
}
{
damage_save = 0;
damage_take = frag_damage;
-
+
return FALSE;
}
MUTATOR_HOOKFUNCTION(minstagib_ForbidThrowing)
{
- if (self.health < 1)
- return FALSE;
-
- return TRUE;
-}
+ // weapon dropping on death handled by FilterItem
+ nades_CheckThrow();
-MUTATOR_HOOKFUNCTION(minstagib_PlayStrengthSound)
-{
- // You shall not play!
return TRUE;
}
MUTATOR_HOOKFUNCTION(minstagib_PlayerDamage)
{
- if(autocvar_g_friendlyfire == 0)
+ if(autocvar_g_friendlyfire == 0 && SAME_TEAM(frag_target, frag_attacker) && IS_PLAYER(frag_target) && IS_PLAYER(frag_attacker))
frag_damage = 0;
-
- if(frag_target.classname == "player")
+
+ if(IS_PLAYER(frag_target))
{
if ((frag_deathtype == DEATH_FALL) ||
(frag_deathtype == DEATH_DROWN) ||
{
frag_damage = 0;
}
-
- if (frag_target.armorvalue && (frag_deathtype == WEP_MINSTANEX) && frag_damage)
+
+ if(IS_PLAYER(frag_attacker))
+ if(DEATH_ISWEAPON(frag_deathtype, WEP_MINSTANEX))
+ if(frag_target.armorvalue)
{
frag_target.armorvalue -= 1;
- centerprint(frag_target, strcat("^3Remaining extra lives: ",ftos(frag_target.armorvalue)));
+ Send_Notification(NOTIF_ONE, frag_target, MSG_CENTER, CENTER_MINSTA_LIVES_REMAINING, frag_target.armorvalue);
frag_damage = 0;
frag_target.hitsound += 1;
frag_attacker.hitsound += 1; // TODO change this to a future specific hitsound for armor hit
}
+
+ if(IS_PLAYER(frag_attacker))
if (DEATH_ISWEAPON(frag_deathtype, WEP_LASER))
{
frag_damage = 0;
frag_mirrordamage = 0;
if (frag_target != frag_attacker)
{
- if ((frag_target.health >= 1) && (frag_target.classname == "player"))
- centerprint(frag_attacker, "Secondary fire inflicts no damage!");
+ if (frag_target.health >= 1)
+ Send_Notification(NOTIF_ONE, frag_attacker, MSG_CENTER, CENTER_MINSTA_SECONDARY);
frag_force = '0 0 0';
// keep mirrorfrag_force
- frag_attacker = frag_target;
+ //frag_attacker = frag_target;
}
}
}
-
+
+ if(IS_PLAYER(frag_attacker))
if(frag_mirrordamage > 0)
{
// just lose extra LIVES, don't kill the player for mirror damage
if(frag_attacker.armorvalue > 0)
{
- frag_attacker.armorvalue = frag_attacker.armorvalue - 1;
- centerprint(frag_attacker, strcat("^3Remaining extra lives: ", ftos(frag_attacker.armorvalue)));
+ frag_attacker.armorvalue -= 1;
+ Send_Notification(NOTIF_ONE, frag_attacker, MSG_CENTER, CENTER_MINSTA_LIVES_REMAINING, frag_attacker.armorvalue);
frag_attacker.hitsound += 1;
}
frag_mirrordamage = 0;
}
-
+
if(frag_target.items & IT_STRENGTH)
yoda = 1;
-
+
return FALSE;
}
MUTATOR_HOOKFUNCTION(minstagib_SetStartItems)
{
start_ammo_cells = cvar("g_minstagib_ammo_start");
-
- g_pinata = 0; // incompatible
- g_weapon_stay = 0; // incompatible
- g_bloodloss = 0; // incompatible
+
start_health = 100;
start_armorvalue = 0;
- WEPSET_COPY_AW(start_weapons, WEP_MINSTANEX);
- g_minstagib_invis_alpha = cvar("g_minstagib_invis_alpha");
+ start_weapons = WEPSET_MINSTANEX;
+ warmup_start_weapons = WEPSET_MINSTANEX;
start_items |= IT_UNLIMITED_SUPERWEAPONS;
- if (g_minstagib_invis_alpha <= 0)
- g_minstagib_invis_alpha = -1;
-
return FALSE;
}
MUTATOR_HOOKFUNCTION(minstagib_FilterItem)
{
- if(self.weapon == -2)
- return FALSE;
-
- if(self.classname == "item_minst_cells" || self.weapon == WEP_ROCKET_LAUNCHER || self.weapon == WEP_NEX)
+ if(self.classname == "item_cells")
+ return TRUE; // no normal cells?
+
+ if(self.weapon == WEP_MINSTANEX && self.classname == "droppedweapon")
{
self.ammo_cells = autocvar_g_minstagib_ammo_drop;
- StartItem ("models/items/a_cells.md3",
- "misc/itempickup.wav", 45, 0,
- "MinstaNex Ammo", IT_CELLS, -2, 0, generic_pickupevalfunc, 100);
return FALSE;
}
-
- if(self.flags & FL_POWERUP)
+
+ if(self.weapon == WEP_ROCKET_LAUNCHER || self.weapon == WEP_NEX)
{
- // randomize
- float rnd = random() * 3;
- if (rnd <= 1)
- self.items = IT_STRENGTH;
- else if (rnd <= 2)
- self.items = IT_NAILS;
- else
- self.items = IT_INVINCIBLE;
-
- if (self.items == IT_STRENGTH)
- {
- if(!self.strength_finished)
- self.strength_finished = autocvar_g_balance_powerup_strength_time;
- StartItem ("models/items/g_strength.md3",
- "misc/powerup.wav", g_pickup_respawntime_powerup, g_pickup_respawntimejitter_powerup,
- "Invisibility", IT_STRENGTH, -2, FL_POWERUP, generic_pickupevalfunc, BOT_PICKUP_RATING_MID);
- }
- // replace with extra lives
- else if (self.items == IT_NAILS)
- {
- self.max_health = 1;
- StartItem ("models/items/g_h100.md3",
- "misc/megahealth.wav", g_pickup_respawntime_powerup, g_pickup_respawntimejitter_powerup,
- "Extralife", IT_NAILS, -2, FL_POWERUP, generic_pickupevalfunc, BOT_PICKUP_RATING_HIGH);
- }
- // replace with speed
- else if (self.items == IT_INVINCIBLE)
- {
- if(!self.invincible_finished)
- self.invincible_finished = autocvar_g_balance_powerup_invincible_time;
- StartItem ("models/items/g_invincible.md3",
- "misc/powerup_shield.wav", g_pickup_respawntime_powerup, g_pickup_respawntimejitter_powerup,
- "Speed", IT_INVINCIBLE, -2, FL_POWERUP, generic_pickupevalfunc, BOT_PICKUP_RATING_MID);
- }
- return FALSE;
+ entity e = spawn();
+ setorigin(e, self.origin);
+ entity oldself;
+ oldself = self;
+ self = e;
+ spawnfunc_item_minst_cells();
+ self = oldself;
+ return TRUE;
}
-
+
+ if(self.flags & FL_POWERUP)
+ return FALSE;
+
+ if(self.ammo_cells > autocvar_g_minstagib_ammo_drop && self.classname != "item_minst_cells")
+ self.ammo_cells = autocvar_g_minstagib_ammo_drop;
+
+ if(self.ammo_cells && !self.weapon)
+ return FALSE;
+
return TRUE;
}
+MUTATOR_HOOKFUNCTION(minstagib_CustomizeWaypoint)
+{
+ entity e = WaypointSprite_getviewentity(other);
+
+ // if you have the invisibility powerup, sprites ALWAYS are restricted to your team
+ // but only apply this to real players, not to spectators
+ if((self.owner.flags & FL_CLIENT) && (self.owner.items & IT_STRENGTH) && (e == other))
+ if(DIFF_TEAM(self.owner, e))
+ return TRUE;
+
+ return FALSE;
+}
+
MUTATOR_HOOKFUNCTION(minstagib_ItemCountdown)
{
switch(self.items)
return FALSE;
}
-MUTATOR_HOOKFUNCTION(minstagib_GiveItem)
+MUTATOR_HOOKFUNCTION(minstagib_ItemTouch)
{
- float it;
- float prevcells = giveplayer.ammo_cells;
-
- player_pickedup |= Item_GiveAmmoTo(giveitem, giveplayer, ammo_fuel, g_pickup_fuel_max, ITEM_MODE_FUEL);
- player_pickedup |= Item_GiveAmmoTo(giveitem, giveplayer, ammo_cells, 999, ITEM_MODE_NONE);
-
- if(giveplayer.ammo_cells > prevcells)
+ if(self.ammo_cells)
{
- player_wswitch = TRUE;
// play some cool sounds ;)
- if (clienttype(giveplayer) == CLIENTTYPE_REAL)
+ if (IS_CLIENT(other))
{
- if(giveplayer.health <= 5)
- AnnounceTo(giveplayer, "lastsecond");
- else if(giveplayer.health < 50)
- AnnounceTo(giveplayer, "narrowly");
+ if(other.health <= 5)
+ Send_Notification(NOTIF_ONE, other, MSG_ANNCE, ANNCE_MINSTAGIB_LASTSECOND);
+ else if(other.health < 50)
+ Send_Notification(NOTIF_ONE, other, MSG_ANNCE, ANNCE_MINSTAGIB_NARROWLY);
}
- if (WEPSET_CONTAINS_EW(giveitem, WEP_MINSTANEX))
- W_GiveWeapon (giveplayer, WEP_MINSTANEX, giveitem.netname);
- giveplayer.health = 100;
- }
+ if(other.health < 100)
+ other.health = 100;
- if((it = (giveitem.items - (giveitem.items & giveplayer.items)) & IT_PICKUPMASK))
- {
- player_pickedup = TRUE;
- giveplayer.items |= it;
- sprint (giveplayer, strcat("You got the ^2", giveitem.netname, "\n"));
+ return MUT_ITEMTOUCH_CONTINUE;
}
- // extralife powerup
- if (giveitem.max_health)
+ if(self.max_health)
{
- player_pickedup = TRUE;
- // sound not available
- // AnnounceTo(giveplayer, "_lives");
- giveplayer.armorvalue = bound(giveplayer.armorvalue, 999, giveplayer.armorvalue + autocvar_g_minstagib_extralives);
- sprint(giveplayer, "^3You picked up some extra lives\n");
+ other.armorvalue = bound(other.armorvalue, 999, other.armorvalue + autocvar_g_minstagib_extralives);
+ Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_EXTRALIVES);
+ return MUT_ITEMTOUCH_PICKUP;
}
- // invis powerup
- if (giveitem.strength_finished)
- {
- player_pickedup = TRUE;
- // sound not available
- // AnnounceTo(giveplayer, "invisible");
- giveplayer.strength_finished = max(giveplayer.strength_finished, time) + autocvar_g_balance_powerup_strength_time;
- }
+ return MUT_ITEMTOUCH_CONTINUE;
+}
+
+MUTATOR_HOOKFUNCTION(minstagib_OnEntityPreSpawn)
+{
+ if (!autocvar_g_powerups) { return FALSE; }
+ if (!(self.classname == "item_strength" || self.classname == "item_invincible" || self.classname == "item_health_mega"))
+ return FALSE;
+
+ entity e = spawn();
+
+ if(random() < 0.3)
+ e.think = spawnfunc_item_strength;
+ else if(random() < 0.6)
+ e.think = minstagib_health_mega;
+ else
+ e.think = spawnfunc_item_invincible;
+
+ e.nextthink = time + 0.1;
+ e.spawnflags = self.spawnflags;
+ e.noalign = self.noalign;
+ setorigin(e, self.origin);
- // speed powerup
- if (giveitem.invincible_finished)
- {
- player_pickedup = TRUE;
- // sound not available
- // AnnounceTo(giveplayer, "speed");
- giveplayer.invincible_finished = max(giveplayer.invincible_finished, time) + autocvar_g_balance_powerup_invincible_time;
- }
-
return TRUE;
}
return FALSE;
}
+MUTATOR_HOOKFUNCTION(minstagib_SetModname)
+{
+ modname = "MinstaGib";
+ return TRUE;
+}
+
MUTATOR_DEFINITION(mutator_minstagib)
{
+ MUTATOR_HOOK(MatchEnd, minstagib_MatchEnd, CBC_ORDER_ANY);
MUTATOR_HOOK(BotShouldAttack, minstagib_BotShouldAttack, CBC_ORDER_ANY);
MUTATOR_HOOK(PlayerPhysics, minstagib_PlayerPhysics, CBC_ORDER_ANY);
MUTATOR_HOOK(PlayerSpawn, minstagib_PlayerSpawn, CBC_ORDER_ANY);
MUTATOR_HOOK(PlayerDamage_Calculate, minstagib_PlayerDamage, CBC_ORDER_ANY);
- MUTATOR_HOOK(PlayStrengthSound, minstagib_PlayStrengthSound, CBC_ORDER_ANY);
MUTATOR_HOOK(MakePlayerObserver, minstagib_MakePlayerObserver, CBC_ORDER_ANY);
MUTATOR_HOOK(SetStartItems, minstagib_SetStartItems, CBC_ORDER_ANY);
+ MUTATOR_HOOK(ItemTouch, minstagib_ItemTouch, CBC_ORDER_ANY);
MUTATOR_HOOK(FilterItem, minstagib_FilterItem, CBC_ORDER_ANY);
+ MUTATOR_HOOK(CustomizeWaypoint, minstagib_CustomizeWaypoint, CBC_ORDER_ANY);
MUTATOR_HOOK(Item_RespawnCountdown, minstagib_ItemCountdown, CBC_ORDER_ANY);
MUTATOR_HOOK(PlayerDamage_SplitHealthArmor, minstagib_SplitHealthArmor, CBC_ORDER_ANY);
MUTATOR_HOOK(PlayerPowerups, minstagib_PlayerPowerups, CBC_ORDER_ANY);
MUTATOR_HOOK(ForbidThrowCurrentWeapon, minstagib_ForbidThrowing, CBC_ORDER_ANY);
MUTATOR_HOOK(PlayerPreThink, minstagib_PlayerPreThink, CBC_ORDER_ANY);
+ MUTATOR_HOOK(OnEntityPreSpawn, minstagib_OnEntityPreSpawn, CBC_ORDER_ANY);
MUTATOR_HOOK(BuildMutatorsString, minstagib_BuildMutatorsString, CBC_ORDER_ANY);
MUTATOR_HOOK(BuildMutatorsPrettyString, minstagib_BuildMutatorsPrettyString, CBC_ORDER_ANY);
+ MUTATOR_HOOK(SetModname, minstagib_SetModname, CBC_ORDER_ANY);
return FALSE;
}