else if(self.health>WEP_CVAR(devastator, damage)*0.5)
{
if(self.velocity.z < 0)
- if(client_hasweapon(self, WEP_DEVASTATOR, true, false))
+ if(client_hasweapon(self, WEP_DEVASTATOR.m_id, true, false))
{
self.movement_x = maxspeed;
return;
}
- self.switchweapon = WEP_DEVASTATOR;
+ self.switchweapon = WEP_DEVASTATOR.m_id;
self.v_angle_x = 90;
self.BUTTON_ATCK = true;
self.rocketjumptime = time + WEP_CVAR(devastator, detonatedelay);
void havocbot_chooseenemy()
{
entity head, best, head2;
- float rating, bestrating, i, hf;
+ float rating, bestrating, hf;
vector eye, v;
if (autocvar_bot_nofire || IS_INDEPENDENT_PLAYER(self))
{
self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE;
- for(i = 0; ; ++i)
+ bool scan_transparent = false;
+ bool scan_secondary_targets = false;
+ while(true)
{
- while (head)
+ scan_secondary_targets = false;
+ for ( ; head; head = head.chain)
{
+ if(!scan_secondary_targets)
+ {
+ if(head.classname == "misc_breakablemodel")
+ continue;
+ }
+ else
+ {
+ if(head.classname != "misc_breakablemodel")
+ continue;
+ }
+
v = (head.absmin + head.absmax) * 0.5;
rating = vlen(v - eye);
if (rating<autocvar_bot_ai_enemydetectionradius)
bestrating = rating;
}
}
- head = head.chain;
+
+ if(!best && !scan_secondary_targets)
+ {
+ scan_secondary_targets = true;
+ head = head2;
+ bestrating = 100000000;
+ }
}
// I want to do a second scan if no enemy was found or I don't have weapons
// TODO: Perform the scan when using the rifle (requires changes on the rifle code)
- if(best || self.weapons) // || self.weapon == WEP_RIFLE
+ if(best || self.weapons) // || self.weapon == WEP_RIFLE.m_id
break;
- if(i)
+ if(scan_transparent)
break;
// Set flags to see through transparent objects
self.dphitcontentsmask |= DPCONTENTS_OPAQUE;
head = head2;
+ scan_transparent = true;
}
// Restore hit flags
self.enemy = best;
self.havocbot_stickenemy = true;
+ if(best && best.classname == "misc_breakablemodel")
+ self.havocbot_stickenemy = false;
}
float havocbot_chooseweapon_checkreload(int new_weapon)
// ;)
if(g_weaponarena_weapons == WEPSET_TUBA)
{
- self.switchweapon = WEP_TUBA;
+ self.switchweapon = WEP_TUBA.m_id;
return;
}
{
// If no weapon was chosen get the first available weapon
if(self.weapon==0)
- for(i = WEP_FIRST; i <= WEP_LAST; ++i) if(i != WEP_BLASTER)
+ for(i = WEP_FIRST; i <= WEP_LAST; ++i) if(i != WEP_BLASTER.m_id)
{
if(client_hasweapon(self, i, true, false))
{
#include "bot/bot.qh"
#include "bot/navigation.qh"
- #include "vehicles/vehicle.qh"
+ #include "../common/vehicles/sv_vehicles.qh"
#include "weapons/hitplot.qh"
#include "weapons/weaponsystem.qh"
#include "../common/net_notice.qh"
#include "../common/physics.qh"
+ #include "../common/items/all.qc"
+
#include "../common/triggers/subs.qh"
#include "../common/triggers/triggers.qh"
#include "../common/triggers/trigger/secret.qh"
entity spot;
self.hud = HUD_NORMAL;
- if(IS_PLAYER(self)) { pointparticles(particleeffectnum("spawn_event_neutral"), self.origin, '0 0 0', 1); }
+ if(IS_PLAYER(self)) { Send_Effect("spawn_event_neutral", self.origin, '0 0 0', 1); }
spot = SelectSpawnPoint (true);
if(!spot)
}
self.frags = FRAGS_SPECTATOR;
+ self.bot_attack = false;
MUTATOR_CALLHOOK(MakePlayerObserver);
}
if(self.vehicle)
- vehicles_exit(VHEF_RELESE);
+ vehicles_exit(VHEF_RELEASE);
WaypointSprite_PlayerDead();
RemoveGrapplingHook(self); // Wazat's Grappling Hook
- if(self.vehicle)
- vehicles_exit(VHEF_RELESE);
-
self.classname = "player";
self.wasplayer = true;
self.iscreature = true;
{
if(self.vehicle)
{
- vehicles_exit(VHEF_RELESE);
+ vehicles_exit(VHEF_RELEASE);
if(!self.killindicator_teamchange)
{
self.vehicle_health = -1;
void ClientDisconnect (void)
{
if(self.vehicle)
- vehicles_exit(VHEF_RELESE);
+ vehicles_exit(VHEF_RELEASE);
if (!IS_CLIENT(self))
{
PlayerStats_GameReport_FinalizePlayer(self);
- if(IS_PLAYER(self)) { pointparticles(particleeffectnum("spawn_event_neutral"), self.origin, '0 0 0', 1); }
+ if(IS_PLAYER(self)) { Send_Effect("spawn_event_neutral", self.origin, '0 0 0', 1); }
CheatShutdownClient();
self.velocity = '0 0 1' * autocvar_g_respawn_ghosts_speed;
self.avelocity = randomvec() * autocvar_g_respawn_ghosts_speed * 3 - randomvec() * autocvar_g_respawn_ghosts_speed * 3;
self.effects |= CSQCMODEL_EF_RESPAWNGHOST;
- pointparticles(particleeffectnum("respawn_ghost"), self.origin, '0 0 0', 1);
+ Send_Effect("respawn_ghost", self.origin, '0 0 0', 1);
if(autocvar_g_respawn_ghosts_maxtime)
SUB_SetFade (self, time + autocvar_g_respawn_ghosts_maxtime / 2 + random () * (autocvar_g_respawn_ghosts_maxtime - autocvar_g_respawn_ghosts_maxtime / 2), 1.5);
}
if (!g_instagib)
{
- if (self.items & IT_STRENGTH)
+ if (self.items & ITEM_Strength.m_itemid)
{
play_countdown(self.strength_finished, "misc/poweroff.wav");
self.effects = self.effects | (EF_BLUE | EF_ADDITIVE | EF_FULLBRIGHT);
if (time > self.strength_finished)
{
- self.items = self.items - (self.items & IT_STRENGTH);
+ self.items = self.items - (self.items & ITEM_Strength.m_itemid);
//Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERDOWN_STRENGTH, self.netname);
Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERDOWN_STRENGTH);
}
{
if (time < self.strength_finished)
{
- self.items = self.items | IT_STRENGTH;
+ self.items = self.items | ITEM_Strength.m_itemid;
Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERUP_STRENGTH, self.netname);
Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERUP_STRENGTH);
}
}
- if (self.items & IT_INVINCIBLE)
+ if (self.items & ITEM_Shield.m_itemid)
{
play_countdown(self.invincible_finished, "misc/poweroff.wav");
self.effects = self.effects | (EF_RED | EF_ADDITIVE | EF_FULLBRIGHT);
if (time > self.invincible_finished)
{
- self.items = self.items - (self.items & IT_INVINCIBLE);
+ self.items = self.items - (self.items & ITEM_Shield.m_itemid);
//Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERDOWN_SHIELD, self.netname);
Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERDOWN_SHIELD);
}
{
if (time < self.invincible_finished)
{
- self.items = self.items | IT_INVINCIBLE;
+ self.items = self.items | ITEM_Shield.m_itemid;
Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERUP_SHIELD, self.netname);
Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERUP_SHIELD);
}
// if player rotted to death... die!
// check this outside above checks, as player may still be able to rot to death
if(self.health < 1)
+ {
+ if(self.vehicle)
+ vehicles_exit(VHEF_RELEASE);
self.event_damage(self, self, 1, DEATH_ROT, self.origin, '0 0 0');
+ }
if (!(self.items & IT_UNLIMITED_WEAPON_AMMO))
{
minf = autocvar_g_balance_fuel_regenstable;
limitf = autocvar_g_balance_fuel_limit;
- self.ammo_fuel = CalcRotRegen(self.ammo_fuel, minf, autocvar_g_balance_fuel_regen, autocvar_g_balance_fuel_regenlinear, frametime * (time > self.pauseregen_finished) * ((self.items & IT_FUEL_REGEN) != 0), maxf, autocvar_g_balance_fuel_rot, autocvar_g_balance_fuel_rotlinear, frametime * (time > self.pauserotfuel_finished), limitf);
+ self.ammo_fuel = CalcRotRegen(self.ammo_fuel, minf, autocvar_g_balance_fuel_regen, autocvar_g_balance_fuel_regenlinear, frametime * (time > self.pauseregen_finished) * ((self.items & ITEM_JetpackRegen.m_itemid) != 0), maxf, autocvar_g_balance_fuel_rot, autocvar_g_balance_fuel_rotlinear, frametime * (time > self.pauserotfuel_finished), limitf);
}
}
self.flags |= FL_CLIENT | FL_NOTARGET;
}
+ void vehicles_enter (entity pl, entity veh);
void PlayerUseKey()
{
if (!IS_PLAYER(self))
if(self.vehicle)
{
- vehicles_exit(VHEF_NORMAL);
- return;
+ if(!gameover)
+ {
+ vehicles_exit(VHEF_NORMAL);
+ return;
+ }
+ }
+ else if(autocvar_g_vehicles_enter)
+ {
+ if(!self.frozen)
+ if(self.deadflag == DEAD_NO)
+ if(!gameover)
+ {
+ entity head, closest_target = world;
+ head = WarpZone_FindRadius(self.origin, autocvar_g_vehicles_enter_radius, TRUE);
+
+ while(head) // find the closest acceptable target to enter
+ {
+ if(head.vehicle_flags & VHF_ISVEHICLE)
+ if(head.deadflag == DEAD_NO)
+ if(!head.owner || ((head.vehicle_flags & VHF_MULTISLOT) && SAME_TEAM(head.owner, self)))
+ if(head.takedamage != DAMAGE_NO)
+ {
+ if(closest_target)
+ {
+ if(vlen(self.origin - head.origin) < vlen(self.origin - closest_target.origin))
+ { closest_target = head; }
+ }
+ else { closest_target = head; }
+ }
+
+ head = head.chain;
+ }
+
+ if(closest_target) { vehicles_enter(self, closest_target); return; }
+ }
}
// a use key was pressed; call handlers
*/
.float usekeypressed;
void() nexball_setstatus;
+ .float last_vehiclecheck;
.int items_added;
void PlayerPreThink (void)
{
if(self.health < 1)
{
if(self.vehicle)
- vehicles_exit(VHEF_RELESE);
+ vehicles_exit(VHEF_RELEASE);
self.event_damage(self, self.frozen_by, 1, DEATH_NADE_ICE_FREEZE, self.origin, '0 0 0');
}
else if ( self.revive_progress <= 0 )
MUTATOR_CALLHOOK(PlayerPreThink);
+ if(autocvar_g_vehicles_enter)
+ if(time > self.last_vehiclecheck)
+ if(IS_PLAYER(self))
+ if(!gameover)
+ if(!self.frozen)
+ if(!self.vehicle)
+ if(self.deadflag == DEAD_NO)
+ {
+ entity veh;
+ for(veh = world; (veh = findflags(veh, vehicle_flags, VHF_ISVEHICLE)); )
+ if(vlen(veh.origin - self.origin) < autocvar_g_vehicles_enter_radius)
+ if(veh.deadflag == DEAD_NO)
+ if(veh.takedamage != DAMAGE_NO)
+ if((veh.vehicle_flags & VHF_MULTISLOT) && SAME_TEAM(veh.owner, self))
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_VEHICLE_ENTER_GUNNER);
+ else if(!veh.owner)
+ if(!veh.team || SAME_TEAM(self, veh))
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_VEHICLE_ENTER);
+ else if(autocvar_g_vehicles_steal)
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_VEHICLE_ENTER_STEAL);
+
+ self.last_vehiclecheck = time + 1;
+ }
+
if(!self.cvar_cl_newusekeysupported) // FIXME remove this - it was a stupid idea to begin with, we can JUST use the button
{
if(self.BUTTON_USE && !self.usekeypressed)
if(frametime)
{
- if(self.weapon == WEP_VORTEX && WEP_CVAR(vortex, charge))
+ if(self.weapon == WEP_VORTEX.m_id && WEP_CVAR(vortex, charge))
{
self.weaponentity_glowmod_x = autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_red_half * min(1, self.vortex_charge / WEP_CVAR(vortex, charge_animlimit));
self.weaponentity_glowmod_y = autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_green_half * min(1, self.vortex_charge / WEP_CVAR(vortex, charge_animlimit));
// WEAPONTODO: THIS SHIT NEEDS TO GO EVENTUALLY
// It cannot be predicted by the engine!
- if((self.weapon == WEP_SHOCKWAVE || self.weapon == WEP_SHOTGUN) && self.weaponentity.wframe == WFRAME_FIRE2 && time < self.weapon_nextthink)
+ if((self.weapon == WEP_SHOCKWAVE.m_id || self.weapon == WEP_SHOTGUN.m_id) && self.weaponentity.wframe == WFRAME_FIRE2 && time < self.weapon_nextthink)
do_crouch = 0;
if (do_crouch)
W_WeaponFrame();
self.items_added = 0;
- if(self.items & IT_JETPACK)
- if(self.items & IT_FUEL_REGEN || self.ammo_fuel >= 0.01)
+ if(self.items & ITEM_Jetpack.m_itemid)
+ if(self.items & ITEM_JetpackRegen.m_itemid || self.ammo_fuel >= 0.01)
self.items_added |= IT_FUEL;
self.items |= self.items_added;
// WEAPONTODO: Add weapon request for this
if(!zoomstate_set)
- SetZoomState(self.BUTTON_ZOOM || self.BUTTON_ZOOMSCRIPT || (self.BUTTON_ATCK2 && self.weapon == WEP_VORTEX) || (self.BUTTON_ATCK2 && self.weapon == WEP_RIFLE && WEP_CVAR(rifle, secondary) == 0)); // WEAPONTODO
+ SetZoomState(self.BUTTON_ZOOM || self.BUTTON_ZOOMSCRIPT || (self.BUTTON_ATCK2 && self.weapon == WEP_VORTEX.m_id) || (self.BUTTON_ATCK2 && self.weapon == WEP_RIFLE.m_id && WEP_CVAR(rifle, secondary) == 0)); // WEAPONTODO
float oldspectatee_status;
oldspectatee_status = self.spectatee_status;
#include "spawnpoints.qh"
#include "tturrets/include/turrets_early.qh"
#include "t_items.qh"
- #include "vehicles/vehicle.qh"
+ #include "../common/vehicles/sv_vehicles.qh"
#include "weapons/accuracy.qh"
#include "weapons/csqcprojectile.qh"
#include "weapons/selection.qh"
else if(!(attacker.weapons & WepSet_FromWeapon(culprit)))
culprit = attacker.weapon;
- if(g_weaponarena_random_with_blaster && culprit == WEP_BLASTER) // WEAPONTODO: Shouldn't this be in a mutator?
+ if(g_weaponarena_random_with_blaster && culprit == WEP_BLASTER.m_id) // WEAPONTODO: Shouldn't this be in a mutator?
{
// no exchange
}
void Freeze (entity targ, float freeze_time, float frozen_type, float show_waypoint)
{
- if(!IS_PLAYER(targ) && !(targ.flags & FL_MONSTER)) // only specified entities can be freezed
+ if(!IS_PLAYER(targ) && !IS_MONSTER(targ)) // only specified entities can be freezed
return;
if(targ.frozen)
return;
- float targ_maxhealth = ((targ.flags & FL_MONSTER) ? targ.max_health : start_health);
+ float targ_maxhealth = ((IS_MONSTER(targ)) ? targ.max_health : start_health);
targ.frozen = frozen_type;
targ.revive_progress = ((frozen_type == 3) ? 1 : 0);
targ.health = ((frozen_type == 3) ? targ_maxhealth : 1);
targ.revive_speed = freeze_time;
+ self.bot_attack = false;
entity ice, head;
ice = spawn();
void Unfreeze (entity targ)
{
+ if(!targ.frozen)
+ return;
+
if(targ.frozen && targ.frozen != 3) // only reset health if target was frozen
targ.health = ((IS_PLAYER(targ)) ? start_health : targ.max_health);
targ.frozen = 0;
targ.revive_progress = 0;
targ.revival_time = time;
+ self.bot_attack = true;
WaypointSprite_Kill(targ.waypointsprite_attached);
RemoveGrapplingHook(targ); // STOP THAT, you parasite!
// special rule: gravity bomb does not hit team mates (other than for disconnecting the hook)
- if(DEATH_ISWEAPON(deathtype, WEP_HOOK) || DEATH_ISWEAPON(deathtype, WEP_TUBA))
+ if(DEATH_ISWEAPON(deathtype, WEP_HOOK.m_id) || DEATH_ISWEAPON(deathtype, WEP_TUBA.m_id))
{
if(IS_PLAYER(targ))
if(SAME_TEAM(targ, attacker))
{
// exit the vehicle before killing (fixes a crash)
if(IS_PLAYER(targ) && targ.vehicle)
- vehicles_exit(VHEF_RELESE);
+ vehicles_exit(VHEF_RELEASE);
// These are ALWAYS lethal
// No damage modification here
{
Unfreeze(targ);
targ.health = autocvar_g_freezetag_revive_falldamage_health;
- pointparticles(particleeffectnum("iceorglass"), targ.origin, '0 0 0', 3);
+ Send_Effect("iceorglass", targ.origin, '0 0 0', 3);
Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_FREEZETAG_REVIVED_FALL, targ.netname);
Send_Notification(NOTIF_ONE, targ, MSG_CENTER, CENTER_FREEZETAG_REVIVE_SELF);
}
if(targ.frozen && deathtype == DEATH_HURTTRIGGER && !autocvar_g_freezetag_frozen_damage_trigger)
{
- pointparticles(particleeffectnum("teleport"), targ.origin, '0 0 0', 1);
+ Send_Effect("teleport", targ.origin, '0 0 0', 1);
entity oldself = self;
self = targ;
self.oldorigin = self.origin;
self.prevorigin = self.origin;
- pointparticles(particleeffectnum("teleport"), self.origin, '0 0 0', 1);
+ Send_Effect("teleport", self.origin, '0 0 0', 1);
}
self = oldself;
if(!g_instagib)
{
// apply strength multiplier
- if (attacker.items & IT_STRENGTH)
+ if (attacker.items & ITEM_Strength.m_itemid)
{
if(targ == attacker)
{
}
// apply invincibility multiplier
- if (targ.items & IT_INVINCIBLE)
+ if (targ.items & ITEM_Shield.m_itemid)
damage = damage * autocvar_g_balance_powerup_invincible_takedamage;
}
if(targ != attacker)
{
entity victim;
- if((targ.vehicle_flags & VHF_ISVEHICLE) && targ.owner)
+ if(IS_VEHICLE(targ) && targ.owner)
victim = targ.owner;
else
victim = targ;
- if(IS_PLAYER(victim) || (victim.turrcaps_flags & TFL_TURRCAPS_ISTURRET) || (victim.flags & FL_MONSTER))
+ if(IS_PLAYER(victim) || IS_TURRET(victim) || IS_MONSTER(victim))
{
if(DIFF_TEAM(victim, attacker) && !victim.frozen)
{
total_damage_to_creatures = 0;
- if(deathtype != (WEP_HOOK | HITTYPE_SECONDARY | HITTYPE_BOUNCE)) // only send gravity bomb damage once
- if(DEATH_WEAPONOF(deathtype) != WEP_TUBA) // do not send tuba damage (bandwidth hog)
+ if(deathtype != (WEP_HOOK.m_id | HITTYPE_SECONDARY | HITTYPE_BOUNCE)) // only send gravity bomb damage once
+ if(DEATH_WEAPONOF(deathtype) != WEP_TUBA.m_id) // do not send tuba damage (bandwidth hog)
{
force = inflictorvelocity;
if(vlen(force) == 0)
force = force * (finaldmg / coredamage) * forceintensity;
hitloc = nearest;
- if(deathtype & WEP_BLASTER)
+ if(deathtype & WEP_BLASTER.m_id)
force *= WEP_CVAR_BOTH(blaster, !(deathtype & HITTYPE_SECONDARY), force_zscale);
if(targ != directhitentity)