1 #include "sv_overkill.qh"
3 bool autocvar_g_overkill_powerups_replace;
5 bool autocvar_g_overkill_itemwaypoints = true;
7 .Weapon ok_lastwep[MAX_WEAPONSLOTS];
9 MUTATOR_HOOKFUNCTION(ok, Damage_Calculate, CBC_ORDER_LAST)
11 entity frag_attacker = M_ARGV(1, entity);
12 entity frag_target = M_ARGV(2, entity);
13 float frag_deathtype = M_ARGV(3, float);
15 if(IS_PLAYER(frag_attacker) && (IS_PLAYER(frag_target) || IS_VEHICLE(frag_target) || IS_TURRET(frag_target)))
16 if(DEATH_ISWEAPON(frag_deathtype, WEP_BLASTER))
18 if(frag_attacker != frag_target)
19 if(!STAT(FROZEN, frag_target))
20 if(!IS_DEAD(frag_target))
22 Send_Notification(NOTIF_ONE, frag_attacker, MSG_CENTER, CENTER_SECONDARY_NODAMAGE);
23 M_ARGV(6, vector) = '0 0 0'; // force
26 M_ARGV(4, float) = 0; // damage
30 void ok_DropItem(entity this, entity targ)
34 Item_InitializeLoot(e, "item_armor_small", this.origin + '0 0 32',
35 '0 0 200' + normalize(targ.origin - this.origin) * 500, 5);
38 MUTATOR_HOOKFUNCTION(ok, PlayerDies)
40 entity frag_attacker = M_ARGV(1, entity);
41 entity frag_target = M_ARGV(2, entity);
43 entity targ = ((frag_attacker) ? frag_attacker : frag_target);
45 ok_DropItem(frag_target, targ);
47 for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
49 .entity weaponentity = weaponentities[slot];
51 frag_target.ok_lastwep[slot] = frag_target.(weaponentity).m_switchweapon;
55 MUTATOR_HOOKFUNCTION(ok, MonsterDropItem)
57 entity mon = M_ARGV(0, entity);
58 entity olditem = M_ARGV(1, entity);
59 entity frag_attacker = M_ARGV(2, entity);
63 M_ARGV(1, entity) = NULL;
65 ok_DropItem(mon, frag_attacker);
68 MUTATOR_HOOKFUNCTION(ok, ForbidThrowCurrentWeapon)
73 MUTATOR_HOOKFUNCTION(ok, PlayerPreThink)
79 entity player = M_ARGV(0, entity);
80 if (!IS_PLAYER(player) || IS_DEAD(player) || STAT(FROZEN, player))
84 if (!PHYS_INPUT_BUTTON_ATCK2(player) || forbidWeaponUse(player) ||
85 !(round_handler_IsActive() && !round_handler_IsRoundStarted()))
89 // Allow secondary blaster during countdown.
90 for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
92 .entity weaponentity = weaponentities[slot];
93 Weapon weapon = player.(weaponentity).m_weapon;
94 if (weapon == WEP_Null && slot != 0)
98 weapon.wr_think(weapon, player, weaponentity, 2);
100 PHYS_INPUT_BUTTON_ATCK2(player) = false;
103 MUTATOR_HOOKFUNCTION(ok, ForbidRandomStartWeapons)
108 MUTATOR_HOOKFUNCTION(ok, PlayerWeaponSelect)
110 entity player = M_ARGV(0, entity);
112 for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
114 .entity weaponentity = weaponentities[slot];
115 entity thiswep = player.(weaponentity);
117 if(player.ok_lastwep[slot] && player.ok_lastwep[slot] != WEP_Null)
119 Weapon newwep = player.ok_lastwep[slot];
120 if(player.ok_lastwep[slot] == WEP_OVERKILL_HMG)
121 newwep = WEP_OVERKILL_MACHINEGUN;
122 if(player.ok_lastwep[slot] == WEP_OVERKILL_RPC)
123 newwep = WEP_OVERKILL_NEX;
124 thiswep.m_switchweapon = newwep;
125 player.ok_lastwep[slot] = WEP_Null;
130 bool ok_HandleItemWaypoints(entity e)
132 if(!autocvar_g_overkill_itemwaypoints)
133 return false; // don't handle it
137 case ITEM_HealthMega: return true;
138 case ITEM_ArmorMedium: return true;
139 case ITEM_ArmorBig: return true;
140 case ITEM_ArmorMega: return true;
146 MUTATOR_HOOKFUNCTION(ok, Item_RespawnCountdown)
148 entity item = M_ARGV(0, entity);
149 return ok_HandleItemWaypoints(item);
152 MUTATOR_HOOKFUNCTION(ok, Item_ScheduleRespawn)
154 entity item = M_ARGV(0, entity);
155 return ok_HandleItemWaypoints(item);
158 MUTATOR_HOOKFUNCTION(ok, FilterItem)
160 entity item = M_ARGV(0, entity);
168 case ITEM_HealthMega: return autocvar_g_overkill_filter_healthmega;
169 case ITEM_ArmorMedium: return autocvar_g_overkill_filter_armormedium;
170 case ITEM_ArmorBig: return autocvar_g_overkill_filter_armorbig;
171 case ITEM_ArmorMega: return autocvar_g_overkill_filter_armormega;
173 if (!autocvar_g_powerups || !autocvar_g_overkill_powerups_replace)
177 if (item.classname == "item_strength")
179 entity wep = new(weapon_okhmg);
180 setorigin(wep, item.origin);
182 wep.noalign = Item_ShouldKeepPosition(item);
184 wep.team = item.team;
185 wep.respawntime = g_pickup_respawntime_superweapon;
186 wep.pickup_anyway = true;
187 wep.spawnfunc_checked = true;
188 Item_Initialize(wep, "weapon_okhmg"); // doesn't actually use spawnfunc
191 else if (item.classname == "item_shield")
193 entity wep = new(weapon_okrpc);
194 setorigin(wep, item.origin);
196 wep.noalign = Item_ShouldKeepPosition(item);
198 wep.team = item.team;
199 wep.respawntime = g_pickup_respawntime_superweapon;
200 wep.pickup_anyway = true;
201 wep.spawnfunc_checked = true;
202 Item_Initialize(wep, "weapon_okrpc"); // doesn't actually use spawnfunc
208 MUTATOR_HOOKFUNCTION(ok, SetStartItems, CBC_ORDER_LAST)
210 WepSet ok_start_items = (WEPSET(OVERKILL_MACHINEGUN) | WEPSET(OVERKILL_NEX) | WEPSET(OVERKILL_SHOTGUN));
212 if(WEP_OVERKILL_RPC.weaponstart > 0) { ok_start_items |= WEPSET(OVERKILL_RPC); }
213 if(WEP_OVERKILL_HMG.weaponstart > 0) { ok_start_items |= WEPSET(OVERKILL_HMG); }
215 start_items |= IT_UNLIMITED_WEAPON_AMMO;
216 start_weapons = warmup_start_weapons = ok_start_items;
219 MUTATOR_HOOKFUNCTION(ok, SetWeaponArena)
221 // turn weapon arena off
222 M_ARGV(0, string) = "off";
225 MUTATOR_HOOKFUNCTION(ok, BuildMutatorsString)
227 M_ARGV(0, string) = strcat(M_ARGV(0, string), ":OK");
230 MUTATOR_HOOKFUNCTION(ok, BuildMutatorsPrettyString)
232 M_ARGV(0, string) = strcat(M_ARGV(0, string), ", Overkill");
235 MUTATOR_HOOKFUNCTION(ok, SetModname)
237 M_ARGV(0, string) = "Overkill";