- #if defined(CSQC)
- #include "../dpdefs/csprogsdefs.qh"
- #include "defs.qh"
- #include "../common/constants.qh"
- #include "../common/util.qh"
- #include "../common/weapons/weapons.qh"
- #include "autocvars.qh"
- #include "../common/deathtypes.qh"
- #include "damage.qh"
- #include "movetypes.qh"
- #include "prandom.qh"
- #include "vehicles/vehicles.qh"
- #elif defined(MENUQC)
- #elif defined(SVQC)
- #endif
+ #include "damage.qh"
+ #include "_all.qh"
+
+ #include "gibs.qh"
+ #include "prandom.qh"
+
+ #include "../common/vehicles/cl_vehicles.qh"
+
+ #include "../common/constants.qh"
+ #include "../common/deathtypes.qh"
+ #include "../common/movetypes/movetypes.qh"
+ #include "../common/util.qh"
+
+ #include "../common/weapons/all.qh"
+
+ .entity tag_entity;
+
+ .float cnt;
+ .int state;
+ .bool isplayermodel;
void DamageEffect_Think()
{
pointparticles(self.team, org, '0 0 0', 1);
}
- void DamageEffect(vector hitorg, float dmg, int type, int specnum)
+ void DamageEffect(vector hitorg, float thedamage, int type, int specnum)
{
// particle effects for players and objects damaged by weapons (eg: flames coming out of victims shot with rockets)
return; // allow a single damage on non-skeletal models
}
- life = bound(autocvar_cl_damageeffect_lifetime_min, dmg * autocvar_cl_damageeffect_lifetime, autocvar_cl_damageeffect_lifetime_max);
+ life = bound(autocvar_cl_damageeffect_lifetime_min, thedamage * autocvar_cl_damageeffect_lifetime, autocvar_cl_damageeffect_lifetime_max);
effectname = get_weaponinfo(DEATH_WEAPONOF(type)).netname;
void Ent_DamageInfo(float isNew)
{
- float dmg, rad, edge, thisdmg;
+ float thedamage, rad, edge, thisdmg;
bool hitplayer = false;
int species, forcemul;
vector force, thisforce;
w_org.y = ReadCoord();
w_org.z = ReadCoord();
- dmg = ReadByte();
+ thedamage = ReadByte();
rad = ReadByte();
edge = ReadByte();
force = decompressShortVector(ReadShort());
continue;
if(thisdmg < 0)
thisdmg = 0;
- if(dmg)
+ if(thedamage)
{
- thisdmg = dmg + (edge - dmg) * thisdmg;
- thisforce = forcemul * vlen(force) * (thisdmg / dmg) * normalize(self.origin - w_org);
+ thisdmg = thedamage + (edge - thedamage) * thisdmg;
+ thisforce = forcemul * vlen(force) * (thisdmg / thedamage) * normalize(self.origin - w_org);
}
else
{
if(vlen(nearest - w_org) > bound(MIN_DAMAGEEXTRARADIUS, self.damageextraradius, MAX_DAMAGEEXTRARADIUS))
continue;
- thisdmg = dmg;
+ thisdmg = thedamage;
thisforce = forcemul * force;
}
pointparticles(particleeffectnum("electro_impact"), self.origin, w_backoff * 1000, 1);
break;
- case DEATH_TURRET_WALK_MEELE:
+ case DEATH_TURRET_WALK_MELEE:
sound(self, CH_SHOTS, "weapons/ric1.wav", VOL_BASE, ATTEN_MIN);
pointparticles(particleeffectnum("TE_SPARK"), self.origin, w_backoff * 1000, 1);
break;
w_random = prandom();
traceline(w_org - normalize(force) * 16, w_org + normalize(force) * 16, MOVE_NOMONSTERS, world);
- if(trace_fraction < 1 && hitwep != WEP_VORTEX && hitwep != WEP_VAPORIZER)
+ if(trace_fraction < 1 && hitwep != WEP_VORTEX.m_id && hitwep != WEP_VAPORIZER.m_id)
w_backoff = trace_plane_normal;
else
w_backoff = -1 * normalize(force);
+ #include "main.qh"
+ #include "_all.qh"
+
+ #include "casings.qh"
+ #include "csqcmodel_hooks.qh"
+ #include "damage.qh"
+ #include "effects.qh"
+ #include "gibs.qh"
+ #include "hook.qh"
+ #include "hud.qh"
+ #include "hud_config.qh"
+ #include "laser.qh"
#include "mapvoting.qh"
#include "modeleffects.qh"
#include "particles.qh"
+ #include "prandom.qh"
#include "scoreboard.qh"
#include "shownames.qh"
- #include "target_music.qh"
+ #include "sortlist.qh"
-#include "tturrets.qh"
#include "tuba.qh"
+ #include "t_items.qh"
#include "wall.qh"
#include "waypointsprites.qh"
- #include "vehicles/vehicles.qh"
+ #include "../common/vehicles/unit/bumblebee.qh"
+ #include "../common/vehicles/cl_vehicles.qh"
+ #include "../common/vehicles/vehicles.qh"
- #include "../server/vehicles/bumblebee.qh"
+ #include "weapons/projectile.qh"
+ #include "../common/buffs.qh"
+ #include "../common/deathtypes.qh"
+ #include "../common/effects.qh"
+ #include "../common/mapinfo.qh"
+ #include "../common/monsters/all.qh"
+ #include "../common/nades.qh"
#include "../common/net_notice.qh"
+ #include "../common/notifications.qh"
+ #include "../common/stats.qh"
+ #include "../common/teams.qh"
- #include "../common/monsters/monsters.qh"
+ #include "../common/items/all.qh"
+
+ #include "../common/mutators/base.qh"
+
+ #include "../common/weapons/all.qh"
+
+ #include "../csqcmodellib/cl_model.qh"
+ #include "../csqcmodellib/interpolate.qh"
+
+ #include "../common/triggers/include.qh"
+#include "../common/turrets/cl_turrets.qh"
+#include "../common/turrets/turrets.qh"
+
#include "../warpzonelib/client.qh"
// --------------------------------------------------------------------------
registercvar("cl_nade_type", "3");
registercvar("cl_pokenade_type", "zombie");
+ registercvar("cl_jumpspeedcap_min", "");
+ registercvar("cl_jumpspeedcap_max", "");
+
gametype = 0;
// hud_fields uses strunzone on the titles!
GetTeam(NUM_SPECTATOR, true); // add specs first
// needs to be done so early because of the constants they create
- CALL_ACCUMULATED_FUNCTION(RegisterWeapons);
+ static_init();
+ CALL_ACCUMULATED_FUNCTION(RegisterTurrets);
- CALL_ACCUMULATED_FUNCTION(RegisterMonsters);
- CALL_ACCUMULATED_FUNCTION(RegisterGametypes);
CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
CALL_ACCUMULATED_FUNCTION(RegisterHUD_Panels);
- CALL_ACCUMULATED_FUNCTION(RegisterBuffs);
+ CALL_ACCUMULATED_FUNCTION(RegisterEffects);
+ CALL_ACCUMULATED_FUNCTION(RegisterVehicles);
WaypointSprite_Load();
Hook_Precache();
GibSplash_Precache();
Casings_Precache();
- Vehicles_Precache();
- turrets_precache();
Tuba_Precache();
CSQCPlayer_Precache();
// --------------------------------------------------------------------------
// BEGIN OPTIONAL CSQC FUNCTIONS
+
void Ent_RemoveEntCS()
{
entcs_receiver[self.sv_entnum] = world;
if(is_new)
{
self.origin = spn_origin;
- setsize(self, PL_MIN, PL_MAX);
+ setsize(self, PL_MIN_CONST, PL_MAX_CONST);
droptofloor();
/*if(autocvar_cl_spawn_point_model) // needs a model first
case ENT_CLIENT_WARPZONE_TELEPORTED: WarpZone_Teleported_Read(bIsNewEntity); break;
case ENT_CLIENT_TRIGGER_MUSIC: Ent_ReadTriggerMusic(); break;
case ENT_CLIENT_HOOK: Ent_ReadHook(bIsNewEntity, ENT_CLIENT_HOOK); break;
+ case ENT_CLIENT_INVENTORY: Inventory_Read(self); break;
case ENT_CLIENT_ARC_BEAM: Ent_ReadArcBeam(bIsNewEntity); break;
case ENT_CLIENT_ACCURACY: Ent_ReadAccuracy(); break;
case ENT_CLIENT_AUXILIARYXHAIR: Net_AuXair2(bIsNewEntity); break;
case ENT_CLIENT_SPAWNEVENT: Ent_ReadSpawnEvent(bIsNewEntity); break;
case ENT_CLIENT_NOTIFICATION: Read_Notification(bIsNewEntity); break;
case ENT_CLIENT_HEALING_ORB: ent_healer(); break;
+ case ENT_CLIENT_VIEWLOC: ent_viewloc(); break;
+ case ENT_CLIENT_VIEWLOC_TRIGGER: ent_viewloc_trigger(); break;
+ case ENT_CLIENT_LADDER: ent_func_ladder(); break;
+ case ENT_CLIENT_TRIGGER_PUSH: ent_trigger_push(); break;
+ case ENT_CLIENT_TARGET_PUSH: ent_target_push(); break;
+ case ENT_CLIENT_CONVEYOR: ent_conveyor(); break;
+ case ENT_CLIENT_DOOR: ent_door(); break;
+ case ENT_CLIENT_PLAT: ent_plat(); break;
+ case ENT_CLIENT_SWAMP: ent_swamp(); break;
+ case ENT_CLIENT_CORNER: ent_corner(); break;
+ case ENT_CLIENT_KEYLOCK: ent_keylock(); break;
+ case ENT_CLIENT_TRAIN: ent_train(); break;
+ case ENT_CLIENT_TRIGGER_IMPULSE: ent_trigger_impulse(); break;
+ case ENT_CLIENT_EFFECT: Read_Effect(bIsNewEntity); break;
default:
//error(strcat(_("unknown entity type in CSQC_Ent_Update: %d\n"), self.enttype));
../common/util-pre.qh
../dpdefs/csprogsdefs.qh
+ ../common/util-post.qh
announcer.qc
bgmscript.qc
effects.qc
gibs.qc
hook.qc
- hud_config.qc
hud.qc
- laser.qc
+ hud_config.qc
main.qc
mapvoting.qc
miscfunctions.qc
modeleffects.qc
- movetypes.qc
+ movelib.qc
noise.qc
particles.qc
player_skeleton.qc
scoreboard.qc
shownames.qc
sortlist.qc
- target_music.qc
teamradar.qc
-tturrets.qc
tuba.qc
- vehicles/vehicles.qc
+ t_items.qc
view.qc
wall.qc
waypointsprites.qc
- command/cl_cmd.qc
+ command/all.qc
weapons/projectile.qc // TODO
../common/animdecide.qc
../common/buffs.qc
+ ../common/effects.qc
../common/mapinfo.qc
+ ../common/movetypes/include.qc
../common/nades.qc
../common/net_notice.qc
../common/notifications.qc
+ ../common/physics.qc
../common/playerstats.qc
+ ../common/p2mathlib.qc
../common/test.qc
../common/urllib.qc
../common/util.qc
- ../common/command/generic.qc
- ../common/command/markup.qc
- ../common/command/rpn.qc
+ ../common/viewloc.qc
- ../common/monsters/monsters.qc
++../common/weapons/all.qc // TODO
+
+ ../common/items/all.qc
+
+ ../common/monsters/all.qc
+../common/turrets/cl_turrets.qc
+../common/turrets/turrets.qc
+
- ../common/weapons/weapons.qc // TODO
+
+ ../common/weapons/all.qc // TODO
+
+ ../common/triggers/include.qc
../csqcmodellib/cl_model.qc
../csqcmodellib/cl_player.qc
../csqcmodellib/interpolate.qc
- ../server/movelib.qc
- ../server/t_items.qc
- ../server/vehicles/bumblebee.qc
+ ../common/vehicles/vehicles_include.qc
+
+ ../server/mutators/mutator_multijump.qc
../warpzonelib/anglestransform.qc
../warpzonelib/client.qc
+
../warpzonelib/common.qc
../warpzonelib/mathlib.qc
+ ../warpzonelib/util_server.qc
+
+ ../../mod/client/progs.inc
+ #include "command.qh"
#include "generic.qh"
- #include "shared_defs.qh"
- #include "../turrets/config.qh"
+
+ #include "markup.qh"
+ #include "rpn.qh"
+
+ #include "../mapinfo.qh"
+ #include "../test.qh"
+
+ #ifndef MENUQC
+ #include "../notifications.qh"
+ #endif
+
+ #ifdef CSQC
+ #include "../../client/command/cl_cmd.qh"
+ #endif
+
+ #ifdef SVQC
+ #include "../../server/command/banning.qh"
+ #include "../../server/command/cmd.qh"
+ #include "../../server/command/common.qh"
+ #include "../../server/command/sv_cmd.qh"
-
++ #include "../../common/turrets/config.qh"
+ #include "../../common/weapons/config.qh"
+ #endif
// =========================================================
// Generic program common command code, written by Samual
}
}
+ void GenericCommand_dumpitems(float request)
+ {
+ switch(request)
+ {
+ case CMD_REQUEST_COMMAND:
+ {
+ Dump_Items();
+ return;
+ }
+
+ default:
+ case CMD_REQUEST_USAGE:
+ {
+ printf("\nUsage:^3 %s dumpitems", GetProgramCommandPrefix());
+ return;
+ }
+ }
+ }
+
void GenericCommand_dumpnotifs(float request)
{
switch(request)
}
}
+void GenericCommand_dumpturrets(float request)
+{
+ switch(request)
+ {
+ case CMD_REQUEST_COMMAND:
+ {
+ #ifdef SVQC
+ tur_config_file = -1;
+ tur_config_alsoprint = -1;
+ string filename = argv(1);
+
+ if(filename == "")
+ {
+ filename = "turrets_dump.cfg";
+ tur_config_alsoprint = FALSE;
+ }
+ else if(filename == "-")
+ {
+ filename = "turrets_dump.cfg";
+ tur_config_alsoprint = TRUE;
+ }
+ tur_config_file = fopen(filename, FILE_WRITE);
+
+ if(tur_config_file >= 0)
+ {
+ Dump_Turret_Settings();
+ print(sprintf("Dumping turrets... File located in ^2data/data/%s^7.\n", filename));
+ fclose(tur_config_file);
+ tur_config_file = -1;
+ tur_config_alsoprint = -1;
+ }
+ else
+ {
+ print(sprintf("^1Error: ^7Could not open file '%s'!\n", filename));
+ }
+ #else
+ print(_("Turrets dump command only works with sv_cmd.\n"));
+ #endif
+ return;
+ }
+
+ default:
+ case CMD_REQUEST_USAGE:
+ {
+ print(strcat("\nUsage:^3 ", GetProgramCommandPrefix(), " dumpturrets [filename]"));
+ print(" Where 'filename' is the file to write (default is turrets_dump.cfg),\n");
+ print(" if supplied with '-' output to console as well as default,\n");
+ print(" if left blank, it will only write to default.\n");
+ return;
+ }
+ }
+}
+
void GenericCommand_maplist(float request, float argc)
{
switch(request)
#define GENERIC_COMMANDS(request,arguments,command) \
GENERIC_COMMAND("addtolist", GenericCommand_addtolist(request, arguments), "Add a string to a cvar") \
GENERIC_COMMAND("dumpcommands", GenericCommand_dumpcommands(request), "Dump all commands on the program to *_cmd_dump.txt") \
+ GENERIC_COMMAND("dumpitems", GenericCommand_dumpitems(request), "Dump all items to the console") \
GENERIC_COMMAND("dumpnotifs", GenericCommand_dumpnotifs(request), "Dump all notifications into notifications_dump.txt") \
+ GENERIC_COMMAND("dumpturrets", GenericCommand_dumpturrets(request), "Dump all turrets into turrets_dump.txt") \
GENERIC_COMMAND("dumpweapons", GenericCommand_dumpweapons(request), "Dump all weapons into weapons_dump.txt") \
GENERIC_COMMAND("maplist", GenericCommand_maplist(request, arguments), "Automatic control of maplist") \
GENERIC_COMMAND("nextframe", GenericCommand_nextframe(request, arguments, command), "Execute the given command next frame of this VM") \
#define DEATHTYPES \
DEATHTYPE(DEATH_AUTOTEAMCHANGE, DEATH_SELF_AUTOTEAMCHANGE, NO_MSG, DEATH_SPECIAL_START) \
- DEATHTYPE(DEATH_BUFF_VENGEANCE, NO_MSG, DEATH_MURDER_VENGEANCE, NORMAL_POS) \
+ DEATHTYPE(DEATH_BUFF, NO_MSG, DEATH_MURDER_BUFF, NORMAL_POS) \
DEATHTYPE(DEATH_CAMP, DEATH_SELF_CAMP, NO_MSG, NORMAL_POS) \
DEATHTYPE(DEATH_CHEAT, DEATH_SELF_CHEAT, DEATH_MURDER_CHEAT, NORMAL_POS) \
DEATHTYPE(DEATH_CUSTOM, DEATH_SELF_CUSTOM, NO_MSG, NORMAL_POS) \
DEATHTYPE(DEATH_TURRET_PLASMA, DEATH_SELF_TURRET_PLASMA, NO_MSG, NORMAL_POS) \
DEATHTYPE(DEATH_TURRET_TESLA, DEATH_SELF_TURRET_TESLA, NO_MSG, NORMAL_POS) \
DEATHTYPE(DEATH_TURRET_WALK_GUN, DEATH_SELF_TURRET_WALK_GUN, NO_MSG, NORMAL_POS) \
- DEATHTYPE(DEATH_TURRET_WALK_MEELE, DEATH_SELF_TURRET_WALK_MEELE, NO_MSG, NORMAL_POS) \
+ DEATHTYPE(DEATH_TURRET_WALK_MELEE, DEATH_SELF_TURRET_WALK_MELEE, NO_MSG, NORMAL_POS) \
DEATHTYPE(DEATH_TURRET_WALK_ROCKET, DEATH_SELF_TURRET_WALK_ROCKET, NO_MSG, DEATH_TURRET_LAST) \
DEATHTYPE(DEATH_VH_BUMB_DEATH, DEATH_SELF_VH_BUMB_DEATH, DEATH_MURDER_VH_BUMB_DEATH, DEATH_VHFIRST) \
DEATHTYPE(DEATH_VH_BUMB_GUN, NO_MSG, DEATH_MURDER_VH_BUMB_GUN, NORMAL_POS) \
#include "../constants.qh"
#include "../teams.qh"
#include "../util.qh"
- #include "monsters.qh"
+ #include "all.qh"
#include "sv_monsters.qh"
- #include "../weapons/weapons.qh"
+ #include "../weapons/all.qh"
#include "../../server/autocvars.qh"
#include "../../server/defs.qh"
#include "../deathtypes.qh"
#include "../../server/mutators/mutators_include.qh"
- #include "../../server/vehicles/vehicles_def.qh"
- #include "../../server/tturrets/include/turrets_early.qh"
++ #include "../../server/steerlib.qh"
++ #include "../turrets/sv_turrets.qh"
++ #include "../turrets/util.qh"
+ #include "../vehicles/sv_vehicles.qh"
#include "../../server/campaign.qh"
#include "../../server/command/common.qh"
#include "../../server/command/cmd.qh"
+ #include "../triggers/triggers.qh"
#include "../../csqcmodellib/sv_model.qh"
#include "../../server/round_handler.qh"
- #include "../../server/tturrets/include/turrets.qh"
#endif
// =========================
e.monster_loot = self.monster_loot;
- other = e;
- MUTATOR_CALLHOOK(MonsterDropItem);
+ MUTATOR_CALLHOOK(MonsterDropItem, e);
e = other;
if(e && e.monster_loot)
//if(trace_ent != targ)
//return false;
- if(targ.vehicle_flags & VHF_ISVEHICLE)
+ if(IS_VEHICLE(targ))
if(!((get_monsterinfo(ent.monsterid)).spawnflags & MON_FLAG_RANGED))
return false; // melee attacks are useless against vehicles
if(IS_SPEC(targ) || IS_OBSERVER(targ))
return false; // enemy is a spectator
- if(!(targ.vehicle_flags & VHF_ISVEHICLE))
+ if(!IS_VEHICLE(targ))
if(targ.deadflag != DEAD_NO || ent.deadflag != DEAD_NO || targ.health <= 0 || ent.health <= 0)
return false; // enemy/self is dead
if(targ.monster_owner == ent)
return false; // don't attack our pet
- if(!(targ.vehicle_flags & VHF_ISVEHICLE))
+ if(!IS_VEHICLE(targ))
if(targ.flags & FL_NOTARGET)
return false; // enemy can't be targeted
return;
if(self.enemy != other)
- if(!(other.flags & FL_MONSTER))
+ if(!IS_MONSTER(other))
if(monster_isvalidtarget(other, self))
self.enemy = other;
}
field = GetMonsterSoundSampleField(argv(0));
if(GetMonsterSoundSampleField_notFound)
continue;
- if(self.field)
- strunzone(self.field);
- self.field = strzone(strcat(argv(1), " ", argv(2)));
+ if (self.(field))
+ strunzone(self.(field));
+ self.(field) = strzone(strcat(argv(1), " ", argv(2)));
}
fclose(fh);
return 1;
if(delaytoo)
if(time < self.msound_delay)
return; // too early
- GlobalSound(self.samplefield, chan, VOICETYPE_PLAYERSOUND);
+ GlobalSound(self.(samplefield), chan, VOICETYPE_PLAYERSOUND);
self.msound_delay = time + sound_delay;
}
makevectors(self.v_angle);
}
- float monster_melee(entity targ, float damg, float anim, float er, float anim_finished, float deathtype, float dostop)
+ float monster_melee(entity targ, float damg, float anim, float er, float anim_finished, int deathtype, float dostop)
{
if (self.health <= 0)
return false; // attacking while dead?!
self.health += autocvar_g_monsters_miniboss_healthboost;
self.effects |= EF_RED;
if(!self.weapon)
- self.weapon = WEP_VORTEX;
+ self.weapon = WEP_VORTEX.m_id;
}
}
{
other = ent;
if(ent.deadflag == DEAD_DEAD) // don't call when monster isn't dead
- if(MUTATOR_CALLHOOK(MonsterRespawn))
+ if(MUTATOR_CALLHOOK(MonsterRespawn, ent))
return true; // enabled by a mutator
if(ent.spawnflags & MONSTERFLAG_NORESPAWN)
{
float current_distance = vlen((('1 0 0' * to.x) + ('0 1 0' * to.y)) - (('1 0 0' * from.x) + ('0 1 0' * from.y))); // for the sake of this check, exclude Z axis
float initial_height = 0; //min(50, (targ_distance * tanh(20)));
- float current_height = (initial_height * min(1, (current_distance / self.pass_distance)));
+ float current_height = (initial_height * min(1, self.pass_distance ? (current_distance / self.pass_distance) : 0));
//print("current_height = ", ftos(current_height), ", initial_height = ", ftos(initial_height), ".\n");
vector targpos;
targ = self.goalentity;
- monster_target = targ;
- monster_speed_run = runspeed;
- monster_speed_walk = walkspeed;
-
- if(MUTATOR_CALLHOOK(MonsterMove) || gameover || self.draggedby != world || (round_handler_IsActive() && !round_handler_IsRoundStarted()) || time < game_starttime || (autocvar_g_campaign && !campaign_bots_may_start) || time < self.spawn_time)
+ if (MUTATOR_CALLHOOK(MonsterMove, runspeed, walkspeed, targ)
+ || gameover
+ || self.draggedby != world
+ || (round_handler_IsActive() && !round_handler_IsRoundStarted())
+ || time < game_starttime
+ || (autocvar_g_campaign && !campaign_bots_may_start)
+ || time < self.spawn_time)
{
runspeed = walkspeed = 0;
if(time >= self.spawn_time)
return;
}
- targ = monster_target;
runspeed = bound(0, monster_speed_run * Monster_SkillModifier(), runspeed * 2); // limit maxspeed to prevent craziness
walkspeed = bound(0, monster_speed_walk * Monster_SkillModifier(), walkspeed * 2); // limit maxspeed to prevent craziness
if(!mon)
return; // nothing to remove
- pointparticles(particleeffectnum("item_pickup"), mon.origin, '0 0 0', 1);
+ Send_Effect("item_pickup", mon.origin, '0 0 0', 1);
if(mon.weaponentity)
remove(mon.weaponentity);
self.moveto = self.origin;
}
- void monsters_corpse_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
+ void monsters_corpse_damage (entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
{
self.health -= damage;
MON_ACTION(self.monsterid, MR_DEATH);
}
- void monsters_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
+ void monsters_damage (entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
{
if(self.frozen && deathtype != DEATH_KILL && deathtype != DEATH_NADE_ICE_FREEZE)
return;
WaypointSprite_Kill(self.sprite);
- frag_attacker = attacker;
frag_target = self;
- MUTATOR_CALLHOOK(MonsterDies);
+ MUTATOR_CALLHOOK(MonsterDies, attacker);
if(self.health <= -100 || deathtype == DEATH_KILL) // check if we're already gibbed
{
#include "../client/defs.qh"
#include "nades.qh"
#include "buffs.qh"
- #include "../client/movetypes.qh"
+ #include "../common/movetypes/movetypes.qh"
- #include "../server/tturrets/include/turrets_early.qh"
#include "../client/main.qh"
#include "../csqcmodellib/cl_model.qh"
#elif defined(MENUQC)
#include "../dpdefs/progsdefs.qh"
#include "constants.qh"
#include "../server/constants.qh"
++ #include "../common/turrets/sv_turrets.qh"
#endif
#include "constants.qh"
#include "teams.qh"
+ #include "util.qh"
// ================================================
// Unified notification system, written by Samual
#define MSG_INFO_NOTIFICATIONS \
MSG_INFO_NOTIF(2, INFO_CHAT_NOSPECTATORS, 0, 0, "", "", "", _("^F4NOTE: ^BGSpectator chat is not sent to players during the match"), "") \
+ MULTITEAM_INFO(1, INFO_CTF_CAPTURE_, 4, 1, 0, "s1", "s1", "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag"), "") \
+ MULTITEAM_INFO(1, INFO_CTF_CAPTURE_BROKEN_, 4, 2, 2, "s1 f1p2dec s2 f2p2dec", "s1", "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag in ^F1%s^BG seconds, breaking ^BG%s^BG's previous record of ^F2%s^BG seconds"), "") \
+ MSG_INFO_NOTIF(1, INFO_CTF_CAPTURE_NEUTRAL, 1, 0, "s1", "s1", "notify_%s_captured", _("^BG%s^BG captured the flag"), "") \
+ MULTITEAM_INFO(1, INFO_CTF_CAPTURE_TIME_, 4, 1, 1, "s1 f1p2dec", "s1", "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag in ^F1%s^BG seconds"), "") \
+ MULTITEAM_INFO(1, INFO_CTF_CAPTURE_UNBROKEN_, 4, 2, 2, "s1 f1p2dec s2 f2p2dec", "s1", "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag in ^F2%s^BG seconds, failing to break ^BG%s^BG's previous record of ^F1%s^BG seconds"), "") \
+ MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_ABORTRUN_, 4, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag was returned to base by its owner"), "") \
+ MSG_INFO_NOTIF(1, INFO_CTF_FLAGRETURN_ABORTRUN_NEUTRAL,0, 0, "", "", "", _("^BGThe flag was returned by its owner"), "") \
+ MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_DAMAGED_, 4, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag was destroyed and returned to base"), "") \
+ MSG_INFO_NOTIF(1, INFO_CTF_FLAGRETURN_DAMAGED_NEUTRAL, 0, 0, "", "", "", _("^BGThe flag was destroyed and returned to base"), "") \
+ MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_DROPPED_, 4, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag was dropped in the base and returned itself"), "") \
+ MSG_INFO_NOTIF(1, INFO_CTF_FLAGRETURN_DROPPED_NEUTRAL, 0, 0, "", "", "", _("^BGThe flag was dropped in the base and returned itself"), "") \
+ MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_NEEDKILL_, 4, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag fell somewhere it couldn't be reached and returned to base"), "") \
+ MSG_INFO_NOTIF(1, INFO_CTF_FLAGRETURN_NEEDKILL_NEUTRAL,0, 0, "", "", "", _("^BGThe flag fell somewhere it couldn't be reached and returned to base"), "") \
+ MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_SPEEDRUN_, 4, 0, 1, "f1p2dec", "", "", _("^BGThe ^TC^TT^BG flag became impatient after ^F1%.2f^BG seconds and returned itself"), "") \
+ MSG_INFO_NOTIF(1, INFO_CTF_FLAGRETURN_SPEEDRUN_NEUTRAL,0, 1, "f1p2dec", "", "", _("^BGThe flag became impatient after ^F1%.2f^BG seconds and returned itself"), "") \
+ MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_TIMEOUT_, 4, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag has returned to the base"), "") \
+ MSG_INFO_NOTIF(1, INFO_CTF_FLAGRETURN_TIMEOUT_NEUTRAL, 0, 0, "", "", "", _("^BGThe flag has returned to the base"), "") \
+ MULTITEAM_INFO(1, INFO_CTF_LOST_, 4, 1, 0, "s1", "s1", "notify_%s_lost", _("^BG%s^BG lost the ^TC^TT^BG flag"), "") \
+ MSG_INFO_NOTIF(1, INFO_CTF_LOST_NEUTRAL, 1, 0, "s1", "s1", "notify_%s_lost", _("^BG%s^BG lost the flag"), "") \
+ MULTITEAM_INFO(1, INFO_CTF_PICKUP_, 4, 1, 0, "s1", "s1", "notify_%s_taken", _("^BG%s^BG got the ^TC^TT^BG flag"), "") \
+ MSG_INFO_NOTIF(1, INFO_CTF_PICKUP_NEUTRAL, 1, 0, "s1", "s1", "notify_%s_taken", _("^BG%s^BG got the flag"), "") \
+ MULTITEAM_INFO(1, INFO_CTF_RETURN_, 4, 1, 0, "s1", "s1", "notify_%s_returned", _("^BG%s^BG returned the ^TC^TT^BG flag"), "") \
+ MULTITEAM_INFO(1, INFO_CTF_RETURN_MONSTER_, 4, 1, 0, "s1", "s1", "notify_%s_returned", _("^BG%s^BG returned the ^TC^TT^BG flag"), "") \
MSG_INFO_NOTIF(2, INFO_COINTOSS, 1, 0, "s1", "", "", _("^F2Throwing coin... Result: %s^F2!"), "") \
MSG_INFO_NOTIF(1, INFO_JETPACK_NOFUEL, 0, 0, "", "", "", _("^BGYou don't have any fuel for the ^F1Jetpack"), "") \
MSG_INFO_NOTIF(2, INFO_SUPERSPEC_MISSING_UID, 0, 0, "", "", "", _("^F2You lack a UID, superspec options will not be saved/restored"), "") \
MSG_INFO_NOTIF(1, INFO_CA_JOIN_LATE, 0, 0, "", "", "", _("^F1Round already started, you will join the game in the next round"), "") \
MSG_INFO_NOTIF(1, INFO_CA_LEAVE, 0, 0, "", "", "", _("^F2You will spectate in the next round"), "") \
- MULTITEAM_INFO(1, INFO_CTF_CAPTURE_, 2, 1, 0, "s1", "s1", "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag"), "") \
- MULTITEAM_INFO(1, INFO_CTF_CAPTURE_BROKEN_, 2, 2, 2, "s1 f1p2dec s2 f2p2dec", "s1", "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag in ^F1%s^BG seconds, breaking ^BG%s^BG's previous record of ^F2%s^BG seconds"), "") \
- MULTITEAM_INFO(1, INFO_CTF_CAPTURE_TIME_, 2, 1, 1, "s1 f1p2dec", "s1", "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag in ^F1%s^BG seconds"), "") \
- MULTITEAM_INFO(1, INFO_CTF_CAPTURE_UNBROKEN_, 2, 2, 2, "s1 f1p2dec s2 f2p2dec", "s1", "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag in ^F2%s^BG seconds, failing to break ^BG%s^BG's previous record of ^F1%s^BG seconds"), "") \
- MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_ABORTRUN_, 2, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag was returned to base by its owner"), "") \
- MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_DAMAGED_, 2, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag was destroyed and returned to base"), "") \
- MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_DROPPED_, 2, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag was dropped in the base and returned itself"), "") \
- MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_NEEDKILL_, 2, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag fell somewhere it couldn't be reached and returned to base"), "") \
- MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_SPEEDRUN_, 2, 0, 1, "f1p2dec", "", "", _("^BGThe ^TC^TT^BG flag became impatient after ^F1%.2f^BG seconds and returned itself"), "") \
- MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_TIMEOUT_, 2, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag has returned to the base"), "") \
- MULTITEAM_INFO(1, INFO_CTF_LOST_, 2, 1, 0, "s1", "s1", "notify_%s_lost", _("^BG%s^BG lost the ^TC^TT^BG flag"), "") \
- MULTITEAM_INFO(1, INFO_CTF_PICKUP_, 2, 1, 0, "s1", "s1", "notify_%s_taken", _("^BG%s^BG got the ^TC^TT^BG flag"), "") \
- MULTITEAM_INFO(1, INFO_CTF_RETURN_, 2, 1, 0, "s1", "s1", "notify_%s_returned", _("^BG%s^BG returned the ^TC^TT^BG flag"), "") \
- MULTITEAM_INFO(1, INFO_CTF_RETURN_MONSTER_, 2, 1, 0, "s1", "s1", "notify_%s_returned", _("^BG%s^BG returned the ^TC^TT^BG flag"), "") \
+ MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_BUFF, 3, 3, "spree_inf s1 s2 f3buffname s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was killed by ^BG%s^K1's ^BG%s^K1 buff ^K1%s%s"), _("^BG%s%s^K1 was scored against by ^BG%s^K1's ^BG%s^K1 buff ^K1%s%s")) \
MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_CHEAT, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was unfairly eliminated by ^BG%s^K1%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_DROWN, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_water", _("^BG%s%s^K1 was drowned by ^BG%s^K1%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_FALL, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_fall", _("^BG%s%s^K1 was grounded by ^BG%s^K1%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_FIRE, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was burnt up into a crisp by ^BG%s^K1%s%s"), _("^BG%s%s^K1 felt a little hot from ^BG%s^K1's fire^K1%s%s")) \
MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_LAVA, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_lava", _("^BG%s%s^K1 was cooked by ^BG%s^K1%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_MONSTER, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was pushed infront of a monster by ^BG%s^K1%s%s"), "") \
- MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_NADE, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_nade", _("^BG%s%s^K1 was blown up by ^BG%s^K1's Nade%s%s"), "") \
- MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_NADE_NAPALM, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_nade_napalm", _("^BG%s%s^K1 was burned to death by ^BG%s^K1's Napalm Nade%s%s"), _("^BG%s%s^K1 got too close to a napalm explosion%s%s")) \
- MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_NADE_ICE, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_nade_ice", _("^BG%s%s^K1 was blown up by ^BG%s^K1's Ice Nade%s%s"), "") \
- MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_NADE_ICE_FREEZE, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_nade_ice", _("^BG%s%s^K1 was frozen to death by ^BG%s^K1's Ice Nade%s%s"), "") \
- MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_NADE_HEAL, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_nade_heal", _("^BG%s%s^K1 has not been healed by ^BG%s^K1's Healing Nade%s%s"), "") \
+ MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_NADE, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "nade_normal", _("^BG%s%s^K1 was blown up by ^BG%s^K1's Nade%s%s"), "") \
+ MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_NADE_NAPALM, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "nade_napalm", _("^BG%s%s^K1 was burned to death by ^BG%s^K1's Napalm Nade%s%s"), _("^BG%s%s^K1 got too close to a napalm explosion%s%s")) \
+ MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_NADE_ICE, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "nade_ice", _("^BG%s%s^K1 was blown up by ^BG%s^K1's Ice Nade%s%s"), "") \
+ MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_NADE_ICE_FREEZE, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "nade_ice", _("^BG%s%s^K1 was frozen to death by ^BG%s^K1's Ice Nade%s%s"), "") \
+ MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_NADE_HEAL, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "nade_heal", _("^BG%s%s^K1 has not been healed by ^BG%s^K1's Healing Nade%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_SHOOTING_STAR, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_shootingstar", _("^BG%s%s^K1 was shot into space by ^BG%s^K1%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_SLIME, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_slime", _("^BG%s%s^K1 was slimed by ^BG%s^K1%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_SWAMP, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_slime", _("^BG%s%s^K1 was preserved by ^BG%s^K1%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_WAKI_DEATH, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Racer exploded%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_WAKI_GUN, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was bolted down by ^BG%s^K1's Racer%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_WAKI_ROCKET, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 couldn't find shelter from ^BG%s^K1's Racer%s%s"), "") \
- MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VENGEANCE, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was destroyed by the vengeful ^BG%s^K1%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VOID, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_void", _("^BG%s%s^K1 was thrown into a world of hurt by ^BG%s^K1%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_SELF_AUTOTEAMCHANGE, 2, 1, "s1 s2loc death_team", "", "", _("^BG%s^K1 was moved into the %s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_SELF_BETRAYAL, 2, 1, "s1 s2loc spree_lost", "s1", "notify_teamkill_red", _("^BG%s^K1 became enemies with the Lord of Teamplay%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_WYVERN, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was fireballed by a Wyvern%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_ZOMBIE_JUMP, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 joins the Zombies%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_ZOMBIE_MELEE, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was given kung fu lessons by a Zombie%s%s"), "") \
- MSG_INFO_NOTIF(1, INFO_DEATH_SELF_NADE, 2, 1, "s1 s2loc spree_lost", "s1", "notify_nade", _("^BG%s^K1 mastered the art of self-nading%s%s"), "") \
- MSG_INFO_NOTIF(1, INFO_DEATH_SELF_NADE_NAPALM, 2, 1, "s1 s2loc spree_lost", "s1", "notify_nade_napalm", _("^BG%s^K1 was burned to death by their own Napalm Nade%s%s"), _("^BG%s^K1 decided to take a look at the results of their napalm explosion%s%s")) \
- MSG_INFO_NOTIF(1, INFO_DEATH_SELF_NADE_ICE, 2, 1, "s1 s2loc spree_lost", "s1", "notify_nade_ice", _("^BG%s^K1 mastered the art of self-nading%s%s"), "") \
- MSG_INFO_NOTIF(1, INFO_DEATH_SELF_NADE_ICE_FREEZE, 2, 1, "s1 s2loc spree_lost", "s1", "notify_nade_ice", _("^BG%s^K1 was frozen to death by their own Ice Nade%s%s"), _("^BG%s^K1 felt a little chilly%s%s")) \
- MSG_INFO_NOTIF(1, INFO_DEATH_SELF_NADE_HEAL, 2, 1, "s1 s2loc spree_lost", "s1", "notify_nade_heal", _("^BG%s^K1's Healing Nade didn't quite heal them%s%s"), "") \
+ MSG_INFO_NOTIF(1, INFO_DEATH_SELF_NADE, 2, 1, "s1 s2loc spree_lost", "s1", "nade_normal", _("^BG%s^K1 mastered the art of self-nading%s%s"), "") \
+ MSG_INFO_NOTIF(1, INFO_DEATH_SELF_NADE_NAPALM, 2, 1, "s1 s2loc spree_lost", "s1", "nade_napalm", _("^BG%s^K1 was burned to death by their own Napalm Nade%s%s"), _("^BG%s^K1 decided to take a look at the results of their napalm explosion%s%s")) \
+ MSG_INFO_NOTIF(1, INFO_DEATH_SELF_NADE_ICE, 2, 1, "s1 s2loc spree_lost", "s1", "nade_ice", _("^BG%s^K1 mastered the art of self-nading%s%s"), "") \
+ MSG_INFO_NOTIF(1, INFO_DEATH_SELF_NADE_ICE_FREEZE, 2, 1, "s1 s2loc spree_lost", "s1", "nade_ice", _("^BG%s^K1 was frozen to death by their own Ice Nade%s%s"), _("^BG%s^K1 felt a little chilly%s%s")) \
+ MSG_INFO_NOTIF(1, INFO_DEATH_SELF_NADE_HEAL, 2, 1, "s1 s2loc spree_lost", "s1", "nade_heal", _("^BG%s^K1's Healing Nade didn't quite heal them%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_SELF_NOAMMO, 2, 1, "s1 s2loc spree_lost", "s1", "notify_outofammo", _("^BG%s^K1 died%s%s. What's the point of living without ammo?"), _("^BG%s^K1 ran out of ammo%s%s")) \
MSG_INFO_NOTIF(1, INFO_DEATH_SELF_ROT, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 rotted away%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_SELF_SHOOTING_STAR, 2, 1, "s1 s2loc spree_lost", "s1", "notify_shootingstar", _("^BG%s^K1 became a shooting star%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_PLASMA, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 got served some superheated plasma from a turret%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_TESLA, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was electrocuted by a Tesla turret%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_WALK_GUN, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 got served a lead enrichment by a Walker turret%s%s"), "") \
- MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_WALK_MEELE, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was impaled by a Walker turret%s%s"), "") \
+ MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_WALK_MELEE, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was impaled by a Walker turret%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_WALK_ROCKET, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was blasted away by a Walker turret%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VH_BUMB_DEATH, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 got caught in the blast of a Bumblebee explosion%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VH_CRUSH, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was crushed by a vehicle%s%s"), "") \
MSG_CENTER_NOTIF(1, CENTER_CAMPCHECK, 0, 0, "", CPID_CAMPCHECK, "0 0", _("^F2Don't camp!"), "") \
MSG_CENTER_NOTIF(1, CENTER_COINTOSS, 1, 0, "s1", NO_CPID, "0 0", _("^F2Throwing coin... Result: %s^F2!"), "") \
MSG_CENTER_NOTIF(1, CENTER_CTF_CAPTURESHIELD_FREE, 0, 0, "", CPID_CTF_CAPSHIELD, "0 0", _("^BGYou are now free.\n^BGFeel free to ^F2try to capture^BG the flag again\n^BGif you think you will succeed."), "") \
- MSG_CENTER_NOTIF(1, CENTER_CTF_CAPTURESHIELD_SHIELDED, 0, 0, "", CPID_CTF_CAPSHIELD, "0 0", _("^BGYou are now ^F1shielded^BG from the flag\n^BGfor ^F2too many unsuccessful attempts^BG to capture.\n^BGMake some defensive scores before trying again."), "") \
- MULTITEAM_CENTER(1, CENTER_CTF_CAPTURE_, 2, 0, 0, "", CPID_CTF_LOWPRIO, "0 0", _("^BGYou captured the ^TC^TT^BG flag!"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_CTF_CAPTURESHIELD_INACTIVE, 0, 0, "", CPID_CTF_CAPSHIELD, "0 0", _("^BGThis flag is currently inactive"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_CTF_CAPTURESHIELD_SHIELDED, 0, 0, "", CPID_CTF_CAPSHIELD, "0 0", _("^BGYou are now ^F1shielded^BG from the flag(s)\n^BGfor ^F2too many unsuccessful attempts^BG to capture.\n^BGMake some defensive scores before trying again."), "") \
+ MULTITEAM_CENTER(1, CENTER_CTF_CAPTURE_, 4, 0, 0, "", CPID_CTF_LOWPRIO, "0 0", _("^BGYou captured the ^TC^TT^BG flag!"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_CTF_CAPTURE_NEUTRAL, 0, 0, "", CPID_CTF_LOWPRIO, "0 0", _("^BGYou captured the flag!"), "") \
MSG_CENTER_NOTIF(1, CENTER_CTF_FLAG_THROW_PUNISH, 0, 1, "f1secs", CPID_CTF_LOWPRIO, "0 0", _("^BGToo many flag throws! Throwing disabled for %s."), "") \
- MULTITEAM_CENTER(1, CENTER_CTF_PASS_OTHER_, 2, 2, 0, "s1 s2", CPID_CTF_PASS, "0 0", _("^BG%s^BG passed the ^TC^TT^BG flag to %s"), "") \
- MULTITEAM_CENTER(1, CENTER_CTF_PASS_RECEIVED_, 2, 1, 0, "s1", CPID_CTF_PASS, "0 0", _("^BGYou received the ^TC^TT^BG flag from %s"), "") \
+ MULTITEAM_CENTER(1, CENTER_CTF_PASS_OTHER_, 4, 2, 0, "s1 s2", CPID_CTF_PASS, "0 0", _("^BG%s^BG passed the ^TC^TT^BG flag to %s"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_CTF_PASS_OTHER_NEUTRAL, 2, 0, "s1 s2", CPID_CTF_PASS, "0 0", _("^BG%s^BG passed the flag to %s"), "") \
+ MULTITEAM_CENTER(1, CENTER_CTF_PASS_RECEIVED_, 4, 1, 0, "s1", CPID_CTF_PASS, "0 0", _("^BGYou received the ^TC^TT^BG flag from %s"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_CTF_PASS_RECEIVED_NEUTRAL, 1, 0, "s1", CPID_CTF_PASS, "0 0", _("^BGYou received the flag from %s"), "") \
MSG_CENTER_NOTIF(1, CENTER_CTF_PASS_REQUESTED, 1, 0, "s1 pass_key", CPID_CTF_PASS, "0 0", _("^BG%s^BG requests you to pass the flag%s"), "") \
MSG_CENTER_NOTIF(1, CENTER_CTF_PASS_REQUESTING, 1, 0, "s1", CPID_CTF_PASS, "0 0", _("^BGRequesting %s^BG to pass you the flag"), "") \
- MULTITEAM_CENTER(1, CENTER_CTF_PASS_SENT_, 2, 1, 0, "s1", CPID_CTF_PASS, "0 0", _("^BGYou passed the ^TC^TT^BG flag to %s"), "") \
- MULTITEAM_CENTER(1, CENTER_CTF_PICKUP_, 2, 0, 0, "", CPID_CTF_LOWPRIO, "0 0", _("^BGYou got the ^TC^TT^BG flag!"), "") \
+ MULTITEAM_CENTER(1, CENTER_CTF_PASS_SENT_, 4, 1, 0, "s1", CPID_CTF_PASS, "0 0", _("^BGYou passed the ^TC^TT^BG flag to %s"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_CTF_PASS_SENT_NEUTRAL, 1, 0, "s1", CPID_CTF_PASS, "0 0", _("^BGYou passed the flag to %s"), "") \
+ MULTITEAM_CENTER(1, CENTER_CTF_PICKUP_, 4, 0, 0, "", CPID_CTF_LOWPRIO, "0 0", _("^BGYou got the ^TC^TT^BG flag!"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_NEUTRAL, 0, 0, "", CPID_CTF_LOWPRIO, "0 0", _("^BGYou got the flag!"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_TEAM, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGYou got your %steam^BG's flag, return it!"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_TEAM_ENEMY, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGYou got the %senemy^BG's flag, return it!"), "") \
MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_ENEMY, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGThe %senemy^BG got your flag! Retrieve it!"), "") \
MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_ENEMY_VERBOSE, 2, 0, "s1 s2 s1", CPID_CTF_LOWPRIO, "0 0", _("^BGThe %senemy (^BG%s%s)^BG got your flag! Retrieve it!"), "") \
- MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_TEAM, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGYour %steam mate^BG got the flag! Protect them!"), "") \
- MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_TEAM_VERBOSE, 2, 0, "s1 s2 s1", CPID_CTF_LOWPRIO, "0 0", _("^BGYour %steam mate (^BG%s%s)^BG got the flag! Protect them!"), "") \
- MULTITEAM_CENTER(1, CENTER_CTF_RETURN_, 2, 0, 0, "", CPID_CTF_LOWPRIO, "0 0", _("^BGYou returned the ^TC^TT^BG flag!"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_ENEMY_NEUTRAL, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGThe %senemy^BG got the flag! Retrieve it!"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_ENEMY_NEUTRAL_VERBOSE, 2, 0, "s1 s2 s1",CPID_CTF_LOWPRIO, "0 0", _("^BGThe %senemy (^BG%s%s)^BG got the flag! Retrieve it!"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_ENEMY_TEAM, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGThe %senemy^BG got their flag! Retrieve it!"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_ENEMY_TEAM_VERBOSE,2, 0, "s1 s2 s1", CPID_CTF_LOWPRIO, "0 0", _("^BGThe %senemy (^BG%s%s)^BG got their flag! Retrieve it!"), "") \
+ MULTITEAM_CENTER(1, CENTER_CTF_PICKUP_TEAM_, 4, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGYour %steam mate^BG got the ^TC^TT^BG flag! Protect them!"), "") \
+ MULTITEAM_CENTER(1, CENTER_CTF_PICKUP_TEAM_VERBOSE_, 4, 2, 0, "s1 s2 s1", CPID_CTF_LOWPRIO, "0 0", _("^BGYour %steam mate (^BG%s%s)^BG got the ^TC^TT^BG flag! Protect them!"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_TEAM_NEUTRAL, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGYour %steam mate^BG got the flag! Protect them!"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_TEAM_VERBOSE_NEUTRAL, 2, 0, "s1 s2 s1", CPID_CTF_LOWPRIO, "0 0", _("^BGYour %steam mate (^BG%s%s)^BG got the flag! Protect them!"), "") \
+ MULTITEAM_CENTER(1, CENTER_CTF_RETURN_, 4, 0, 0, "", CPID_CTF_LOWPRIO, "0 0", _("^BGYou returned the ^TC^TT^BG flag!"), "") \
MSG_CENTER_NOTIF(1, CENTER_CTF_STALEMATE_CARRIER, 0, 0, "", CPID_STALEMATE, "0 0", _("^BGStalemate! Enemies can now see you on radar!"), "") \
MSG_CENTER_NOTIF(1, CENTER_CTF_STALEMATE_OTHER, 0, 0, "", CPID_STALEMATE, "0 0", _("^BGStalemate! Flag carriers can now be seen by enemies on radar!"), "") \
MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_FRAG, 1, 1, "spree_cen s1", NO_CPID, "0 0", _("^K3%sYou fragged ^BG%s"), _("^K3%sYou scored against ^BG%s")) \
MSG_CENTER_NOTIF(1, CENTER_KEYHUNT_ROUNDSTART, 0, 1, "", CPID_KEYHUNT_OTHER, "1 f1", _("^F4Round will start in ^COUNT"), "") \
MSG_CENTER_NOTIF(1, CENTER_KEYHUNT_SCAN, 0, 1, "", CPID_KEYHUNT_OTHER, "f1 0", _("^BGScanning frequency range..."), "") \
MULTITEAM_CENTER(1, CENTER_KEYHUNT_START_, 4, 0, 0, "", CPID_KEYHUNT, "0 0", _("^BGYou are starting with the ^TC^TT Key"), "") \
- MSG_CENTER_NOTIF(1, CENTER_KEYHUNT_WAIT, 0, 1, "missing_teams", CPID_KEYHUNT_OTHER, "0 0", _("^BGWaiting for players to join...\nNeed active players for: %s"), "") \
MSG_CENTER_NOTIF(1, CENTER_LMS_NOLIVES, 0, 0, "", CPID_LMS, "0 0", _("^BGYou have no lives left, you must wait until the next match"), "") \
MSG_CENTER_NOTIF(1, CENTER_MISSING_TEAMS, 0, 1, "missing_teams", CPID_MISSING_TEAMS, "-1 0", _("^BGWaiting for players to join...\nNeed active players for: %s"), "") \
MSG_CENTER_NOTIF(1, CENTER_MISSING_PLAYERS, 0, 1, "f1", CPID_MISSING_PLAYERS, "-1 0", _("^BGWaiting for %s player(s) to join..."), "") \
MSG_CENTER_NOTIF(1, CENTER_OVERTIME_TIME, 0, 1, "f1time", CPID_OVERTIME, "0 0", _("^F2Now playing ^F4OVERTIME^F2!\n^BGAdded ^F4%s^BG to the game!"), "") \
MSG_CENTER_NOTIF(1, CENTER_PORTO_CREATED_IN, 0, 0, "", NO_CPID, "0 0", _("^K1In^BG-portal created"), "") \
MSG_CENTER_NOTIF(1, CENTER_PORTO_CREATED_OUT, 0, 0, "", NO_CPID, "0 0", _("^F3Out^BG-portal created"), "") \
- MSG_CENTER_NOTIF(1, CENTER_PORTO_FAILED, 0, 0, "", NO_CPID, "0 0", _("^K1Portal deployment failed.\n\n^F2Catch it to try again!"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_PORTO_FAILED, 0, 0, "", NO_CPID, "0 0", _("^F1Portal creation failed"), "") \
MSG_CENTER_NOTIF(1, CENTER_POWERDOWN_INVISIBILITY, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Invisibility has worn off"), "") \
MSG_CENTER_NOTIF(1, CENTER_POWERDOWN_SHIELD, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Shield has worn off"), "") \
MSG_CENTER_NOTIF(1, CENTER_POWERDOWN_SPEED, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Speed has worn off"), "") \
MSG_CENTER_NOTIF(1, CENTER_TEAMCHANGE_SUICIDE, 0, 1, "", CPID_TEAMCHANGE, "1 f1", _("^K1Suicide in ^COUNT"), "") \
MSG_CENTER_NOTIF(1, CENTER_TIMEOUT_BEGINNING, 0, 1, "", CPID_TIMEOUT, "1 f1", _("^F4Timeout begins in ^COUNT"), "") \
MSG_CENTER_NOTIF(1, CENTER_TIMEOUT_ENDING, 0, 1, "", CPID_TIMEOUT, "1 f1", _("^F4Timeout ends in ^COUNT"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_VEHICLE_ENTER, 0, 0, "pass_key", CPID_VEHICLES, "0 0", _("^BGPress ^F2DROPFLAG%s^BG to enter/exit the vehicle"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_VEHICLE_ENTER_GUNNER, 0, 0, "pass_key", CPID_VEHICLES, "0 0", _("^BGPress ^F2DROPFLAG%s^BG to enter the vehicle gunner"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_VEHICLE_ENTER_STEAL, 0, 0, "pass_key", CPID_VEHICLES, "0 0", _("^BGPress ^F2DROPFLAG%s^BG to steal this vehicle"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_VEHICLE_STEAL, 0, 0, "", CPID_VEHICLES_OTHER, "0 0", _("^F2The enemy is stealing one of your vehicles!\n^F4Stop them!"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_VEHICLE_STEAL_SELF, 0, 0, "", CPID_VEHICLES_OTHER, "4 0", _("^F2You have stolen the enemy's vehicle, you are now visible on their radar!"), "") \
MSG_CENTER_NOTIF(1, CENTER_WEAPON_MINELAYER_LIMIT, 0, 1, "f1", NO_CPID, "0 0", _("^BGYou cannot place more than ^F2%s^BG mines at a time"), "")
#define MULTITEAM_MULTI2(default,prefix,anncepre,infopre,centerpre) \
MULTITEAM_MULTI##teams(default,prefix,anncepre,infopre,centerpre)
#define MSG_MULTI_NOTIFICATIONS \
+ MSG_MULTI_NOTIF(1, DEATH_MURDER_BUFF, NO_MSG, INFO_DEATH_MURDER_BUFF, NO_MSG) \
MSG_MULTI_NOTIF(1, DEATH_MURDER_CHEAT, NO_MSG, INFO_DEATH_MURDER_CHEAT, NO_MSG) \
MSG_MULTI_NOTIF(1, DEATH_MURDER_DROWN, NO_MSG, INFO_DEATH_MURDER_DROWN, NO_MSG) \
MSG_MULTI_NOTIF(1, DEATH_MURDER_FALL, NO_MSG, INFO_DEATH_MURDER_FALL, NO_MSG) \
MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_WAKI_DEATH, NO_MSG, INFO_DEATH_MURDER_VH_WAKI_DEATH, NO_MSG) \
MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_WAKI_GUN, NO_MSG, INFO_DEATH_MURDER_VH_WAKI_GUN, NO_MSG) \
MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_WAKI_ROCKET, NO_MSG, INFO_DEATH_MURDER_VH_WAKI_ROCKET, NO_MSG) \
- MSG_MULTI_NOTIF(1, DEATH_MURDER_VENGEANCE, NO_MSG, INFO_DEATH_MURDER_VENGEANCE, NO_MSG) \
MSG_MULTI_NOTIF(1, DEATH_MURDER_VOID, NO_MSG, INFO_DEATH_MURDER_VOID, NO_MSG) \
MSG_MULTI_NOTIF(1, DEATH_SELF_AUTOTEAMCHANGE, NO_MSG, INFO_DEATH_SELF_AUTOTEAMCHANGE, CENTER_DEATH_SELF_AUTOTEAMCHANGE) \
MSG_MULTI_NOTIF(1, DEATH_SELF_BETRAYAL, NO_MSG, INFO_DEATH_SELF_BETRAYAL, CENTER_DEATH_SELF_BETRAYAL) \
MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_PLASMA, NO_MSG, INFO_DEATH_SELF_TURRET_PLASMA, CENTER_DEATH_SELF_TURRET) \
MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_TESLA, NO_MSG, INFO_DEATH_SELF_TURRET_TESLA, CENTER_DEATH_SELF_TURRET) \
MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_WALK_GUN, NO_MSG, INFO_DEATH_SELF_TURRET_WALK_GUN, CENTER_DEATH_SELF_TURRET_WALK) \
- MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_WALK_MEELE, NO_MSG, INFO_DEATH_SELF_TURRET_WALK_MEELE, CENTER_DEATH_SELF_TURRET_WALK) \
+ MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_WALK_MELEE, NO_MSG, INFO_DEATH_SELF_TURRET_WALK_MELEE, CENTER_DEATH_SELF_TURRET_WALK) \
MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_WALK_ROCKET, NO_MSG, INFO_DEATH_SELF_TURRET_WALK_ROCKET, CENTER_DEATH_SELF_TURRET_WALK) \
MSG_MULTI_NOTIF(1, DEATH_SELF_VH_BUMB_DEATH, NO_MSG, INFO_DEATH_SELF_VH_BUMB_DEATH, CENTER_DEATH_SELF_VH_BUMB_DEATH) \
MSG_MULTI_NOTIF(1, DEATH_SELF_VH_CRUSH, NO_MSG, INFO_DEATH_SELF_VH_CRUSH, CENTER_DEATH_SELF_VH_CRUSH) \
MULTITEAM_CHOICE##teams(default,challow,prefix,chtype,optiona,optionb)
#define MSG_CHOICE_NOTIFICATIONS \
- MULTITEAM_CHOICE(1, 2, CHOICE_CTF_CAPTURE_BROKEN_, 2, MSG_INFO, INFO_CTF_CAPTURE_, INFO_CTF_CAPTURE_BROKEN_) \
- MULTITEAM_CHOICE(1, 2, CHOICE_CTF_CAPTURE_TIME_, 2, MSG_INFO, INFO_CTF_CAPTURE_, INFO_CTF_CAPTURE_TIME_) \
- MULTITEAM_CHOICE(1, 2, CHOICE_CTF_CAPTURE_UNBROKEN_, 2, MSG_INFO, INFO_CTF_CAPTURE_, INFO_CTF_CAPTURE_UNBROKEN_) \
- MSG_CHOICE_NOTIF(1, 2, CHOICE_CTF_PICKUP_TEAM, MSG_CENTER, CENTER_CTF_PICKUP_TEAM, CENTER_CTF_PICKUP_TEAM_VERBOSE) \
+ MULTITEAM_CHOICE(1, 2, CHOICE_CTF_CAPTURE_BROKEN_, 4, MSG_INFO, INFO_CTF_CAPTURE_, INFO_CTF_CAPTURE_BROKEN_) \
+ MULTITEAM_CHOICE(1, 2, CHOICE_CTF_CAPTURE_TIME_, 4, MSG_INFO, INFO_CTF_CAPTURE_, INFO_CTF_CAPTURE_TIME_) \
+ MULTITEAM_CHOICE(1, 2, CHOICE_CTF_CAPTURE_UNBROKEN_, 4, MSG_INFO, INFO_CTF_CAPTURE_, INFO_CTF_CAPTURE_UNBROKEN_) \
+ MULTITEAM_CHOICE(1, 2, CHOICE_CTF_PICKUP_TEAM_, 4, MSG_CENTER, CENTER_CTF_PICKUP_TEAM_, CENTER_CTF_PICKUP_TEAM_VERBOSE_) \
+ MSG_CHOICE_NOTIF(1, 2, CHOICE_CTF_PICKUP_TEAM_NEUTRAL, MSG_CENTER, CENTER_CTF_PICKUP_TEAM_NEUTRAL, CENTER_CTF_PICKUP_TEAM_VERBOSE_NEUTRAL) \
MSG_CHOICE_NOTIF(1, 2, CHOICE_CTF_PICKUP_ENEMY, MSG_CENTER, CENTER_CTF_PICKUP_ENEMY, CENTER_CTF_PICKUP_ENEMY_VERBOSE) \
+ MSG_CHOICE_NOTIF(1, 2, CHOICE_CTF_PICKUP_ENEMY_NEUTRAL, MSG_CENTER, CENTER_CTF_PICKUP_ENEMY_NEUTRAL, CENTER_CTF_PICKUP_ENEMY_NEUTRAL_VERBOSE) \
+ MSG_CHOICE_NOTIF(1, 2, CHOICE_CTF_PICKUP_ENEMY_TEAM, MSG_CENTER, CENTER_CTF_PICKUP_ENEMY_TEAM, CENTER_CTF_PICKUP_ENEMY_TEAM_VERBOSE) \
MSG_CHOICE_NOTIF(1, 1, CHOICE_FRAG, MSG_CENTER, CENTER_DEATH_MURDER_FRAG, CENTER_DEATH_MURDER_FRAG_VERBOSE) \
MSG_CHOICE_NOTIF(1, 1, CHOICE_FRAGGED, MSG_CENTER, CENTER_DEATH_MURDER_FRAGGED, CENTER_DEATH_MURDER_FRAGGED_VERBOSE) \
MSG_CHOICE_NOTIF(1, 1, CHOICE_TYPEFRAG, MSG_CENTER, CENTER_DEATH_MURDER_TYPEFRAG, CENTER_DEATH_MURDER_TYPEFRAG_VERBOSE) \
ARG_CASE(ARG_CS_SV, "spree_end", (autocvar_notification_show_sprees ? notif_arg_spree_inf(-1, "", "", f1) : "")) \
ARG_CASE(ARG_CS_SV, "spree_lost", (autocvar_notification_show_sprees ? notif_arg_spree_inf(-2, "", "", f1) : "")) \
ARG_CASE(ARG_CS_SV, "item_wepname", WEP_NAME(f1)) \
- ARG_CASE(ARG_CS_SV, "item_buffname", sprintf("%s%s", rgb_to_hexcolor(Buff_Color(f1)), Buff_PrettyName(f1))) \
+ ARG_CASE(ARG_CS_SV, "item_buffname", sprintf("%s%s", rgb_to_hexcolor(BUFFS[f1].m_color), BUFFS[f1].m_prettyName)) \
+ ARG_CASE(ARG_CS_SV, "f3buffname", sprintf("%s%s", rgb_to_hexcolor(BUFFS[f3].m_color), BUFFS[f3].m_prettyName)) \
ARG_CASE(ARG_CS_SV, "item_wepammo", (s1 != "" ? sprintf(_(" with %s"), s1) : "")) \
ARG_CASE(ARG_DC, "item_centime", ftos(autocvar_notification_item_centerprinttime)) \
ARG_CASE(ARG_SV, "death_team", Team_ColoredFullName(f1)) \
, CPID_RACE_FINISHLAP
, CPID_TEAMCHANGE
, CPID_TIMEOUT
+ , CPID_VEHICLES
+ , CPID_VEHICLES_OTHER
// always last
, NOTIF_CPID_COUNT
};
// notification limits -- INCREASE AS NECESSARY
const float NOTIF_ANNCE_MAX = 100;
const float NOTIF_INFO_MAX = 300;
- const float NOTIF_CENTER_MAX = 200;
+ const float NOTIF_CENTER_MAX = 250;
const float NOTIF_MULTI_MAX = 200;
- const float NOTIF_CHOICE_MAX = 20;
+ const float NOTIF_CHOICE_MAX = 30;
// notification entities
entity msg_annce_notifs[NOTIF_ANNCE_MAX];
--- /dev/null
- #include "../../server/tturrets/include/turrets_early.qh"
+ #include "teleporters.qh"
+
+ #if defined(CSQC)
+ #elif defined(MENUQC)
+ #elif defined(SVQC)
+ #include "../../server/_all.qh"
+ #include "../../warpzonelib/common.qh"
+ #include "../../warpzonelib/util_server.qh"
+ #include "../../warpzonelib/server.qh"
+ #include "../constants.qh"
+ #include "../triggers/subs.qh"
+ #include "../util.qh"
+ #include "../../server/weapons/csqcprojectile.qh"
+ #include "../../server/autocvars.qh"
+ #include "../../server/constants.qh"
+ #include "../../server/defs.qh"
+ #include "../deathtypes.qh"
++ #include "../turrets/sv_turrets.qh"
+ #include "../vehicles/sv_vehicles.qh"
+ #include "../mapinfo.qh"
+ #include "../../server/anticheat.qh"
+ #endif
+
+ #ifdef SVQC
+
+ float check_tdeath(entity player, vector org, vector telefragmin, vector telefragmax)
+ {
+ if (IS_PLAYER(player) && player.health >= 1)
+ {
+ TDEATHLOOP(org)
+ {
+ if (!(teamplay && autocvar_g_telefrags_teamplay && head.team == player.team))
+ if(IS_PLAYER(head))
+ if(head.health >= 1)
+ return 1;
+ }
+ }
+ return 0;
+ }
+
+ void tdeath(entity player, entity teleporter, entity telefragger, vector telefragmin, vector telefragmax)
+ {
+ TDEATHLOOP(player.origin)
+ {
+ if (IS_PLAYER(player) && player.health >= 1)
+ {
+ if (!(teamplay && autocvar_g_telefrags_teamplay && head.team == player.team))
+ {
+ if(IS_PLAYER(head))
+ if(head.health >= 1)
+ ++tdeath_hit;
+ Damage (head, teleporter, telefragger, 10000, DEATH_TELEFRAG, head.origin, '0 0 0');
+ }
+ }
+ else // dead bodies and monsters gib themselves instead of telefragging
+ Damage (telefragger, teleporter, telefragger, 10000, DEATH_TELEFRAG, telefragger.origin, '0 0 0');
+ }
+ }
+
+ void spawn_tdeath(vector v0, entity e, vector v)
+ {
+ tdeath(e, e, e, '0 0 0', '0 0 0');
+ }
+
+ void TeleportPlayer(entity teleporter, entity player, vector to, vector to_angles, vector to_velocity, vector telefragmin, vector telefragmax, float tflags)
+ {
+ entity telefragger;
+ vector from;
+
+ if(teleporter.owner)
+ telefragger = teleporter.owner;
+ else
+ telefragger = player;
+
+ makevectors (to_angles);
+
+ if(player.teleportable == TELEPORT_NORMAL) // don't play sounds or show particles for anything that isn't a player, maybe change later to block only observers
+ {
+ if(self.pushltime < time) // only show one teleport effect per teleporter per 0.2 seconds, for better fps
+ {
+ if(tflags & TELEPORT_FLAG_SOUND)
+ sound (player, CH_TRIGGER, "misc/teleport.wav", VOL_BASE, ATTEN_NORM);
+ if(tflags & TELEPORT_FLAG_PARTICLES)
+ {
+ Send_Effect("teleport", player.origin, '0 0 0', 1);
+ Send_Effect("teleport", to + v_forward * 32, '0 0 0', 1);
+ }
+ self.pushltime = time + 0.2;
+ }
+ }
+
+ // Relocate the player
+ // assuming to allows PL_MIN to PL_MAX box and some more
+ from = player.origin;
+ setorigin (player, to);
+ player.oldorigin = to; // don't undo the teleport by unsticking
+ player.angles = to_angles;
+ player.fixangle = true;
+ player.velocity = to_velocity;
+ BITXOR_ASSIGN(player.effects, EF_TELEPORT_BIT);
+
+ makevectors(player.angles);
+ Reset_ArcBeam(player, v_forward);
+ UpdateCSQCProjectileAfterTeleport(player);
+
+ if(IS_PLAYER(player))
+ {
+ if(tflags & TELEPORT_FLAG_TDEATH)
+ if(player.takedamage && player.deadflag == DEAD_NO && !g_race && !g_cts && (autocvar_g_telefrags || (tflags & TELEPORT_FLAG_FORCE_TDEATH)))
+ tdeath(player, teleporter, telefragger, telefragmin, telefragmax);
+
+ // player no longer is on ground
+ player.flags &= ~FL_ONGROUND;
+
+ // reset tracking of oldvelocity for impact damage (sudden velocity changes)
+ player.oldvelocity = player.velocity;
+
+ // reset tracking of who pushed you into a hazard (for kill credit)
+ if(teleporter.owner)
+ {
+ player.pusher = teleporter.owner;
+ player.pushltime = time + autocvar_g_maxpushtime;
+ player.istypefrag = player.BUTTON_CHAT;
+ }
+ else
+ {
+ player.pushltime = 0;
+ player.istypefrag = 0;
+ }
+
+ player.lastteleporttime = time;
+ }
+ }
+
+ entity Simple_TeleportPlayer(entity teleporter, entity player)
+ {
+ vector locout;
+ entity e;
+ float p;
+
+ // Find the output teleporter
+ if(teleporter.enemy)
+ {
+ e = teleporter.enemy;
+ }
+ else
+ {
+ RandomSelection_Init();
+ for(e = world; (e = find(e, targetname, teleporter.target)); )
+ {
+ p = 1;
+ if(autocvar_g_telefrags_avoid)
+ {
+ locout = e.origin + '0 0 1' * (1 - player.mins.z - 24);
+ if(check_tdeath(player, locout, '0 0 0', '0 0 0'))
+ p = 0;
+ }
+ RandomSelection_Add(e, 0, string_null, (e.cnt ? e.cnt : 1), p);
+ }
+ e = RandomSelection_chosen_ent;
+ }
+
+ if(!e) { sprint(player, "Teleport destination vanished. Sorry... please complain to the mapper.\n"); }
+
+ makevectors(e.mangle);
+
+ if(e.speed)
+ if(vlen(player.velocity) > e.speed)
+ player.velocity = normalize(player.velocity) * max(0, e.speed);
+
+ if(autocvar_g_teleport_maxspeed)
+ if(vlen(player.velocity) > autocvar_g_teleport_maxspeed)
+ player.velocity = normalize(player.velocity) * max(0, autocvar_g_teleport_maxspeed);
+
+ locout = e.origin + '0 0 1' * (1 - player.mins.z - 24);
+ TeleportPlayer(teleporter, player, locout, e.mangle, v_forward * vlen(player.velocity), '0 0 0', '0 0 0', TELEPORT_FLAGS_TELEPORTER);
+
+ return e;
+ }
+
+ void teleport_findtarget (void)
+ {
+ entity e;
+ float n;
+
+ n = 0;
+ for(e = world; (e = find(e, targetname, self.target)); )
+ {
+ ++n;
+ if(e.movetype == MOVETYPE_NONE)
+ waypoint_spawnforteleporter(self, e.origin, 0);
+ if(e.classname != "info_teleport_destination")
+ print("^3MAPPER ERROR: teleporter does target an invalid teleport destination entity. Angles will not work.\n");
+ }
+
+ if(n == 0)
+ {
+ // no dest!
+ objerror ("Teleporter with nonexistant target");
+ return;
+ }
+ else if(n == 1)
+ {
+ // exactly one dest - bots love that
+ self.enemy = find(e, targetname, self.target);
+ }
+ else
+ {
+ // have to use random selection every single time
+ self.enemy = world;
+ }
+
+ // now enable touch
+ self.touch = Teleport_Touch;
+ }
+
+ entity Teleport_Find(vector mi, vector ma)
+ {
+ entity e;
+ for(e = world; (e = find(e, classname, "trigger_teleport")); )
+ if(WarpZoneLib_BoxTouchesBrush(mi, ma, e, world))
+ return e;
+ return world;
+ }
+
+ void WarpZone_PostTeleportPlayer_Callback(entity pl)
+ {
+ makevectors(pl.angles);
+ Reset_ArcBeam(pl, v_forward);
+ UpdateCSQCProjectileAfterTeleport(pl);
+ {
+ entity oldself = self;
+ self = pl;
+ anticheat_fixangle();
+ self = oldself;
+ }
+ // "disown" projectiles after teleport
+ if(pl.owner)
+ if(pl.owner == pl.realowner)
+ {
+ if(!(pl.flags & FL_PROJECTILE))
+ print("A non-projectile got through a warpzone and its owner cleared. It's a ", pl.classname, ".\n");
+ pl.owner = world;
+ }
+ if(IS_PLAYER(pl))
+ {
+ // reset tracking of oldvelocity for impact damage (sudden velocity changes)
+ pl.oldvelocity = pl.velocity;
+ // reset teleport time tracking too (or multijump can cause insane speeds)
+ pl.lastteleporttime = time;
+ }
+ }
+ #endif
--- /dev/null
- txt = "gfx/vehicles/vth-mover.tga";
+void turret_remove()
+{
+ remove(self.tur_head);
+ //remove(self.enemy);
+ self.tur_head = world;
+}
+
+.vector glowmod;
+void turret_changeteam()
+{
+ self.glowmod = Team_ColorRGB(self.team - 1) * 2;
+ self.teamradar_color = Team_ColorRGB(self.team - 1);
+
+ if(self.team)
+ self.colormap = 1024 + (self.team - 1) * 17;
+
+ self.tur_head.colormap = self.colormap;
+ self.tur_head.glowmod = self.glowmod;
+
+}
+
+void turret_head_draw()
+{
+ self.drawmask = MASK_NORMAL;
+}
+
+void turret_draw()
+{
+ float dt;
+
+ dt = time - self.move_time;
+ self.move_time = time;
+ if(dt <= 0)
+ return;
+
+ self.tur_head.angles += dt * self.tur_head.move_avelocity;
+
+ if (self.health < 127)
+ {
+ dt = random();
+
+ if(dt < 0.03)
+ te_spark(self.origin + '0 0 40', randomvec() * 256 + '0 0 256', 16);
+ }
+
+ if(self.health < 85)
+ if(dt < 0.01)
+ pointparticles(particleeffectnum("smoke_large"), (self.origin + (randomvec() * 80)), '0 0 0', 1);
+
+ if(self.health < 32)
+ if(dt < 0.015)
+ pointparticles(particleeffectnum("smoke_small"), (self.origin + (randomvec() * 80)), '0 0 0', 1);
+
+}
+
+void turret_draw2d()
+{
+ if(self.netname == "")
+ return;
+
+ if(!autocvar_g_waypointsprite_turrets)
+ return;
+
+ if(autocvar_cl_hidewaypoints)
+ return;
+
+ float dist = vlen(self.origin - view_origin);
+ float t = (GetPlayerColor(player_localnum) + 1);
+
+ vector o;
+ string txt;
+
+ if(autocvar_cl_vehicles_hud_tactical)
+ if(dist < 10240 && t != self.team)
+ {
+ // TODO: Vehicle tactical hud
+ o = project_3d_to_2d(self.origin + '0 0 32');
+ if(o_z < 0
+ || o_x < (vid_conwidth * waypointsprite_edgeoffset_left)
+ || o_y < (vid_conheight * waypointsprite_edgeoffset_top)
+ || o_x > (vid_conwidth - (vid_conwidth * waypointsprite_edgeoffset_right))
+ || o_y > (vid_conheight - (vid_conheight * waypointsprite_edgeoffset_bottom)))
+ return; // Dont draw wp's for turrets out of view
+ o_z = 0;
+ if(hud != HUD_NORMAL)
+ {
+ if((get_turretinfo(self.turretid)).spawnflags & TUR_FLAG_MOVE)
- txt = "gfx/vehicles/vth-stationary.tga";
++ txt = "gfx/vehicles/turret_moving.tga";
+ else
- vector pz = drawgetimagesize(txt) * 0.25;
- drawpic(o - pz * 0.5, txt, pz , '1 1 1', 0.75, DRAWFLAG_NORMAL);
++ txt = "gfx/vehicles/turret_stationary.tga";
+
++ vector pz = drawgetimagesize(txt) * autocvar_cl_vehicles_crosshair_size;
++ drawpic(o - pz * 0.5, txt, pz , '1 1 1', 0.7, DRAWFLAG_NORMAL);
+ }
+ }
+
+ if(dist > self.maxdistance)
+ return;
+
+ string spriteimage = self.netname;
+ float a = self.alpha * autocvar_hud_panel_fg_alpha;
+ vector rgb = spritelookupcolor(spriteimage, self.teamradar_color);
+
+
+ if(self.maxdistance > waypointsprite_normdistance)
+ a *= pow(bound(0, (self.maxdistance - dist) / (self.maxdistance - waypointsprite_normdistance), 1), waypointsprite_distancealphaexponent);
+ else if(self.maxdistance > 0)
+ a *= pow(bound(0, (waypointsprite_fadedistance - dist) / (waypointsprite_fadedistance - waypointsprite_normdistance), 1), waypointsprite_distancealphaexponent) * (1 - waypointsprite_minalpha) + waypointsprite_minalpha;
+
+ if(rgb == '0 0 0')
+ {
+ self.teamradar_color = '1 0 1';
+ printf("WARNING: sprite of name %s has no color, using pink so you notice it\n", spriteimage);
+ }
+
+ txt = self.netname;
+ if(autocvar_g_waypointsprite_spam && waypointsprite_count >= autocvar_g_waypointsprite_spam)
+ txt = _("Spam");
+ else
+ txt = spritelookuptext(spriteimage);
+
+ if(time - floor(time) > 0.5 && t == self.team)
+ {
+ if(self.helpme && time < self.helpme)
+ {
+ a *= SPRITE_HELPME_BLINK;
+ txt = sprintf(_("%s under attack!"), txt);
+ }
+ else
+ a *= spritelookupblinkvalue(spriteimage);
+ }
+
+ if(autocvar_g_waypointsprite_uppercase)
+ txt = strtoupper(txt);
+
+ if(a > 1)
+ {
+ rgb *= a;
+ a = 1;
+ }
+
+ if(a <= 0)
+ return;
+
+ rgb = fixrgbexcess(rgb);
+
+ o = project_3d_to_2d(self.origin + '0 0 64');
+ if(o_z < 0
+ || o_x < (vid_conwidth * waypointsprite_edgeoffset_left)
+ || o_y < (vid_conheight * waypointsprite_edgeoffset_top)
+ || o_x > (vid_conwidth - (vid_conwidth * waypointsprite_edgeoffset_right))
+ || o_y > (vid_conheight - (vid_conheight * waypointsprite_edgeoffset_bottom)))
+ return; // Dont draw wp's for turrets out of view
+
+ o_z = 0;
+
+ float edgedistance_min, crosshairdistance;
+ edgedistance_min = min((o_y - (vid_conheight * waypointsprite_edgeoffset_top)),
+ (o_x - (vid_conwidth * waypointsprite_edgeoffset_left)),
+ (vid_conwidth - (vid_conwidth * waypointsprite_edgeoffset_right)) - o_x,
+ (vid_conheight - (vid_conheight * waypointsprite_edgeoffset_bottom)) - o_y);
+
+ float vidscale = max(vid_conwidth / vid_width, vid_conheight / vid_height);
+
+ crosshairdistance = sqrt( pow(o_x - vid_conwidth/2, 2) + pow(o_y - vid_conheight/2, 2) );
+
+ t = waypointsprite_scale * vidscale;
+ a *= waypointsprite_alpha;
+
+ {
+ a = a * (1 - (1 - waypointsprite_distancefadealpha) * (bound(0, dist/waypointsprite_distancefadedistance, 1)));
+ t = t * (1 - (1 - waypointsprite_distancefadescale) * (bound(0, dist/waypointsprite_distancefadedistance, 1)));
+ }
+ if (edgedistance_min < waypointsprite_edgefadedistance) {
+ a = a * (1 - (1 - waypointsprite_edgefadealpha) * (1 - bound(0, edgedistance_min/waypointsprite_edgefadedistance, 1)));
+ t = t * (1 - (1 - waypointsprite_edgefadescale) * (1 - bound(0, edgedistance_min/waypointsprite_edgefadedistance, 1)));
+ }
+ if(crosshairdistance < waypointsprite_crosshairfadedistance) {
+ a = a * (1 - (1 - waypointsprite_crosshairfadealpha) * (1 - bound(0, crosshairdistance/waypointsprite_crosshairfadedistance, 1)));
+ t = t * (1 - (1 - waypointsprite_crosshairfadescale) * (1 - bound(0, crosshairdistance/waypointsprite_crosshairfadedistance, 1)));
+ }
+
+ o = drawspritearrow(o, M_PI, rgb, a, SPRITE_ARROW_SCALE * t);
+ o = drawspritetext(o, M_PI, (SPRITE_HEALTHBAR_WIDTH + 2 * SPRITE_HEALTHBAR_BORDER) * t, rgb, a, waypointsprite_fontsize * '1 1 0', txt);
+ drawhealthbar(
+ o,
+ 0,
+ self.health / 255,
+ '0 0 0',
+ '0 0 0',
+ 0.5 * SPRITE_HEALTHBAR_WIDTH * t,
+ 0.5 * SPRITE_HEALTHBAR_HEIGHT * t,
+ SPRITE_HEALTHBAR_MARGIN * t + 0.5 * waypointsprite_fontsize,
+ SPRITE_HEALTHBAR_BORDER * t,
+ 0,
+ rgb,
+ a * SPRITE_HEALTHBAR_BORDERALPHA,
+ rgb,
+ a * SPRITE_HEALTHBAR_HEALTHALPHA,
+ DRAWFLAG_NORMAL
+ );
+}
+
+void turret_construct()
+{
+ entity tur = get_turretinfo(self.turretid);
+
+ if(self.tur_head == world)
+ self.tur_head = spawn();
+
+ self.netname = TUR_NAME(self.turretid);
+
+ setorigin(self, self.origin);
+ setmodel(self, tur.model);
+ setmodel(self.tur_head, tur.head_model);
+ setsize(self, tur.mins, tur.maxs);
+ setsize(self.tur_head, '0 0 0', '0 0 0');
+
+ if(self.turretid == TUR_EWHEEL)
+ setattachment(self.tur_head, self, "");
+ else
+ setattachment(self.tur_head, self, "tag_head");
+
+ self.tur_head.classname = "turret_head";
+ self.tur_head.owner = self;
+ self.tur_head.move_movetype = MOVETYPE_NOCLIP;
+ self.move_movetype = MOVETYPE_NOCLIP;
+ self.tur_head.angles = self.angles;
+ self.health = 255;
+ self.solid = SOLID_BBOX;
+ self.tur_head.solid = SOLID_NOT;
+ self.movetype = MOVETYPE_NOCLIP;
+ self.tur_head.movetype = MOVETYPE_NOCLIP;
+ self.draw = turret_draw;
+ self.entremove = turret_remove;
+ self.drawmask = MASK_NORMAL;
+ self.tur_head.drawmask = MASK_NORMAL;
+ self.anim_start_time = 0;
+ self.draw2d = turret_draw2d;
+ self.maxdistance = autocvar_g_waypointsprite_turrets_maxdist;
+ self.teamradar_color = '1 0 0';
+ self.alpha = 1;
+
+ TUR_ACTION(self.turretid, TR_SETUP);
+}
+
+entity turret_gibtoss(string _model, vector _from, vector _to, vector _cmod, float _explode);
+void turret_gibboom();
+void turret_gib_draw()
+{
+ Movetype_Physics_MatchTicrate(autocvar_cl_gibs_ticrate, autocvar_cl_gibs_sloppy);
+
+ self.drawmask = MASK_NORMAL;
+
+ if(self.cnt)
+ {
+ if(time >= self.nextthink)
+ {
+ turret_gibboom();
+ remove(self);
+ }
+ }
+ else
+ {
+ self.alpha = bound(0, self.nextthink - time, 1);
+ if(self.alpha < ALPHA_MIN_VISIBLE)
+ remove(self);
+ }
+}
+
+void turret_gibboom()
+{
+ float i;
+
+ sound (self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM);
+ pointparticles(particleeffectnum("rocket_explode"), self.origin, '0 0 0', 1);
+
+ for (i = 1; i < 5; i = i + 1)
+ turret_gibtoss(strcat("models/turrets/head-gib", ftos(i), ".md3"), self.origin + '0 0 2', self.velocity + randomvec() * 700, '0 0 0', false);
+}
+
+entity turret_gibtoss(string _model, vector _from, vector _to, vector _cmod, float _explode)
+{
+ entity gib;
+
+ traceline(_from, _to, MOVE_NOMONSTERS, world);
+ if(trace_startsolid)
+ return world;
+
+ gib = spawn();
+ setorigin(gib, _from);
+ setmodel(gib, _model);
+ gib.colormod = _cmod;
+ gib.solid = SOLID_CORPSE;
+ gib.draw = turret_gib_draw;
+ gib.cnt = _explode;
+ setsize(gib, '-1 -1 -1', '1 1 1');
+ if(_explode)
+ {
+ gib.nextthink = time + 0.2 * (autocvar_cl_gibs_lifetime * (1 + prandom() * 0.15));
+ gib.effects = EF_FLAME;
+ }
+ else
+ gib.nextthink = time + autocvar_cl_gibs_lifetime * (1 + prandom() * 0.15);
+
+ gib.gravity = 1;
+ gib.move_movetype = MOVETYPE_BOUNCE;
+ gib.move_origin = _from;
+ setorigin(gib, _from);
+ gib.move_velocity = _to;
+ gib.move_avelocity = prandomvec() * 32;
+ gib.move_time = time;
+ gib.damageforcescale = 1;
+ gib.classname = "turret_gib";
+
+ return gib;
+}
+
+void turret_die()
+{
+ sound (self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM);
+ pointparticles(particleeffectnum("rocket_explode"), self.origin, '0 0 0', 1);
+ if (!autocvar_cl_nogibs)
+ {
+ // Base
+ if(self.turretid == TUR_EWHEEL)
+ turret_gibtoss((get_turretinfo(self.turretid)).model, self.origin + '0 0 18', self.velocity + '0 0 400' + '0.1 0.1 1' * (random() * 400), '-1 -1 -1', true);
+ else if (self.turretid == TUR_WALKER)
+ turret_gibtoss((get_turretinfo(self.turretid)).model, self.origin + '0 0 18', self.velocity + '0 0 300' + '0.1 0.1 1' * (random() * 200), '-1 -1 -1', true);
+ else if (self.turretid == TUR_TESLA)
+ turret_gibtoss((get_turretinfo(self.turretid)).model, self.origin + '0 0 18', '0 0 200', '-1 -1 -1', false);
+ else
+ {
+ if (random() > 0.5)
+ {
+ turret_gibtoss("models/turrets/base-gib2.md3", self.origin + '0 0 8', '0 0 50' + randomvec() * 150, '0 0 0', false);
+ turret_gibtoss("models/turrets/base-gib3.md3", self.origin + '0 0 8', '0 0 50' + randomvec() * 150, '0 0 0', false);
+ turret_gibtoss("models/turrets/base-gib4.md3", self.origin + '0 0 8', '0 0 50' + randomvec() * 150, '0 0 0', false);
+ }
+ else
+ turret_gibtoss("models/turrets/base-gib1.md3", self.origin + '0 0 8', '0 0 0', '0 0 0', true);
+
+ entity headgib = turret_gibtoss((get_turretinfo(self.turretid)).head_model, self.origin + '0 0 32', '0 0 200' + randomvec() * 200, '-1 -1 -1', true);
+ if(headgib)
+ {
+ headgib.angles = headgib.move_angles = self.tur_head.angles;
+ headgib.avelocity = headgib.move_avelocity = self.tur_head.move_avelocity + randomvec() * 45;
+ headgib.avelocity_y = headgib.move_avelocity_y = headgib.move_avelocity_y * 5;
+ headgib.gravity = 0.5;
+ }
+ }
+ }
+
+ setmodel(self, "null");
+ setmodel(self.tur_head, "null");
+}
+
+void ent_turret()
+{
+ float sf;
+ sf = ReadByte();
+
+ if(sf & TNSF_SETUP)
+ {
+ self.turretid = ReadByte();
+
+ self.origin_x = ReadCoord();
+ self.origin_y = ReadCoord();
+ self.origin_z = ReadCoord();
+ setorigin(self, self.origin);
+
+ self.angles_x = ReadAngle();
+ self.angles_y = ReadAngle();
+
+ turret_construct();
+ self.colormap = 1024;
+ self.glowmod = '0 1 1';
+ self.tur_head.colormap = self.colormap;
+ self.tur_head.glowmod = self.glowmod;
+ }
+
+ if(sf & TNSF_ANG)
+ {
+ if(self.tur_head == world) // aparenly this can happpen before TNSF_SETUP. great.
+ self.tur_head = spawn();
+
+ self.tur_head.move_angles_x = ReadShort();
+ self.tur_head.move_angles_y = ReadShort();
+ //self.tur_head.angles = self.angles + self.tur_head.move_angles;
+ self.tur_head.angles = self.tur_head.move_angles;
+ }
+
+ if(sf & TNSF_AVEL)
+ {
+ if(self.tur_head == world) // aparenly this can happpen before TNSF_SETUP. great.
+ self.tur_head = spawn();
+
+ self.tur_head.move_avelocity_x = ReadShort();
+ self.tur_head.move_avelocity_y = ReadShort();
+ }
+
+ if(sf & TNSF_MOVE)
+ {
+ self.origin_x = ReadShort();
+ self.origin_y = ReadShort();
+ self.origin_z = ReadShort();
+ setorigin(self, self.origin);
+
+ self.velocity_x = ReadShort();
+ self.velocity_y = ReadShort();
+ self.velocity_z = ReadShort();
+
+ self.move_angles_y = ReadShort();
+
+ self.move_time = time;
+ self.move_velocity = self.velocity;
+ self.move_origin = self.origin;
+ }
+
+ if(sf & TNSF_ANIM)
+ {
+ self.frame1time = ReadCoord();
+ self.frame = ReadByte();
+ }
+
+ if(sf & TNSF_STATUS)
+ {
+ float _tmp;
+ _tmp = ReadByte();
+ if(_tmp != self.team)
+ {
+ self.team = _tmp;
+ turret_changeteam();
+ }
+
+ _tmp = ReadByte();
+ if(_tmp == 0 && self.health != 0)
+ turret_die();
+ else if(self.health && self.health != _tmp)
+ self.helpme = servertime + 10;
+
+ self.health = _tmp;
+ }
+ //self.enemy.health = self.health / 255;
+}
--- /dev/null
- void turret_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce)
+#ifdef SVQC
+#include "../../server/autocvars.qh"
+
+// Generic aiming
+vector turret_aim_generic()
+{
+
+ vector pre_pos, prep;
+ float distance, impact_time = 0, i, mintime;
+
+ turret_tag_fire_update();
+
+ if(self.aim_flags & TFL_AIM_SIMPLE)
+ return real_origin(self.enemy);
+
+ mintime = max(self.attack_finished_single - time,0) + sys_frametime;
+
+ // Baseline
+ pre_pos = real_origin(self.enemy);
+
+ // Lead?
+ if (self.aim_flags & TFL_AIM_LEAD)
+ {
+ if (self.aim_flags & TFL_AIM_SHOTTIMECOMPENSATE) // Need to conpensate for shot traveltime
+ {
+ prep = pre_pos;
+
+ distance = vlen(prep - self.tur_shotorg);
+ impact_time = distance / self.shot_speed;
+
+ prep = pre_pos + (self.enemy.velocity * (impact_time + mintime));
+
+ if(self.aim_flags & TFL_AIM_ZPREDICT)
+ if(!(self.enemy.flags & FL_ONGROUND))
+ if(self.enemy.movetype == MOVETYPE_WALK || self.enemy.movetype == MOVETYPE_TOSS || self.enemy.movetype == MOVETYPE_BOUNCE)
+ {
+ float vz;
+ prep_z = pre_pos_z;
+ vz = self.enemy.velocity_z;
+ for(i = 0; i < impact_time; i += sys_frametime)
+ {
+ vz = vz - (autocvar_sv_gravity * sys_frametime);
+ prep_z = prep_z + vz * sys_frametime;
+ }
+ }
+ pre_pos = prep;
+ }
+ else
+ pre_pos = pre_pos + self.enemy.velocity * mintime;
+ }
+
+ if(self.aim_flags & TFL_AIM_SPLASH)
+ {
+ //tracebox(pre_pos + '0 0 32',self.enemy.mins,self.enemy.maxs,pre_pos -'0 0 64',MOVE_WORLDONLY,self.enemy);
+ traceline(pre_pos + '0 0 32',pre_pos -'0 0 64',MOVE_WORLDONLY,self.enemy);
+ if(trace_fraction != 1.0)
+ pre_pos = trace_endpos;
+ }
+
+ return pre_pos;
+}
+
+float turret_targetscore_support(entity _turret,entity _target)
+{
+ float score; // Total score
+ float s_score = 0, d_score;
+
+ if (_turret.enemy == _target) s_score = 1;
+
+ d_score = min(_turret.target_range_optimal,tvt_dist) / max(_turret.target_range_optimal,tvt_dist);
+
+ score = (d_score * _turret.target_select_rangebias) +
+ (s_score * _turret.target_select_samebias);
+
+ return score;
+}
+
+/*
+* Generic bias aware score system.
+*/
+float turret_targetscore_generic(entity _turret, entity _target)
+{
+ float d_dist; // Defendmode Distance
+ float score; // Total score
+ float d_score; // Distance score
+ float a_score; // Angular score
+ float m_score = 0; // missile score
+ float p_score = 0; // player score
+ float ikr; // ideal kill range
+
+ if (_turret.tur_defend)
+ {
+ d_dist = vlen(real_origin(_target) - _turret.tur_defend.origin);
+ ikr = vlen(_turret.origin - _turret.tur_defend.origin);
+ d_score = 1 - d_dist / _turret.target_range;
+ }
+ else
+ {
+ // Make a normlized value base on the targets distance from our optimal killzone
+ ikr = _turret.target_range_optimal;
+ d_score = min(ikr, tvt_dist) / max(ikr, tvt_dist);
+ }
+
+ a_score = 1 - tvt_thadf / _turret.aim_maxrotate;
+
+ if ((_turret.target_select_missilebias > 0) && (_target.flags & FL_PROJECTILE))
+ m_score = 1;
+
+ if ((_turret.target_select_playerbias > 0) && IS_CLIENT(_target))
+ p_score = 1;
+
+ d_score = max(d_score, 0);
+ a_score = max(a_score, 0);
+ m_score = max(m_score, 0);
+ p_score = max(p_score, 0);
+
+ score = (d_score * _turret.target_select_rangebias) +
+ (a_score * _turret.target_select_anglebias) +
+ (m_score * _turret.target_select_missilebias) +
+ (p_score * _turret.target_select_playerbias);
+
+ if(_turret.target_range < vlen(_turret.tur_shotorg - real_origin(_target)))
+ {
+ //dprint("Wtf?\n");
+ score *= 0.001;
+ }
+
+#ifdef TURRET_DEBUG
+ string sd,sa,sm,sp,ss;
+ string sdt,sat,smt,spt;
+
+ sd = ftos(d_score);
+ d_score *= _turret.target_select_rangebias;
+ sdt = ftos(d_score);
+
+ //sv = ftos(v_score);
+ //v_score *= _turret.target_select_samebias;
+ //svt = ftos(v_score);
+
+ sa = ftos(a_score);
+ a_score *= _turret.target_select_anglebias;
+ sat = ftos(a_score);
+
+ sm = ftos(m_score);
+ m_score *= _turret.target_select_missilebias;
+ smt = ftos(m_score);
+
+ sp = ftos(p_score);
+ p_score *= _turret.target_select_playerbias;
+ spt = ftos(p_score);
+
+
+ ss = ftos(score);
+ bprint("^3Target scores^7 \[ ",_turret.netname, " \] ^3for^7 \[ ", _target.netname," \]\n");
+ bprint("^5Range:\[ ",sd, " \]^2+bias:\[ ",sdt," \]\n");
+ bprint("^5Angle:\[ ",sa, " \]^2+bias:\[ ",sat," \]\n");
+ bprint("^5Missile:\[ ",sm," \]^2+bias:\[ ",smt," \]\n");
+ bprint("^5Player:\[ ",sp, " \]^2+bias:\[ ",spt," \]\n");
+ bprint("^3Total (w/bias):\[^1",ss,"\]\n");
+
+#endif
+
+ return score;
+}
+
+// Generic damage handling
+void turret_hide()
+{
+ self.effects |= EF_NODRAW;
+ self.nextthink = time + self.respawntime - 0.2;
+ self.think = turret_respawn;
+}
+
+void turret_die()
+{
+ self.deadflag = DEAD_DEAD;
+ self.tur_head.deadflag = self.deadflag;
+
+// Unsolidify and hide real parts
+ self.solid = SOLID_NOT;
+ self.tur_head.solid = self.solid;
+
+ self.event_damage = func_null;
+ self.takedamage = DAMAGE_NO;
+
+ self.health = 0;
+
+// Go boom
+ //RadiusDamage (self,self, min(self.ammo,50),min(self.ammo,50) * 0.25,250,world,min(self.ammo,50)*5,DEATH_TURRET,world);
+
+ if(self.damage_flags & TFL_DMG_DEATH_NORESPAWN)
+ {
+ TUR_ACTION(self.turretid, TR_DEATH);
+
+ remove(self.tur_head);
+ remove(self);
+ }
+ else
+ {
+ // Setup respawn
+ self.SendFlags |= TNSF_STATUS;
+ self.nextthink = time + 0.2;
+ self.think = turret_hide;
+
+ TUR_ACTION(self.turretid, TR_DEATH);
+ }
+}
+
- void turret_projectile_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce)
++void turret_damage (entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector vforce)
+{
+ // Enough already!
+ if(self.deadflag == DEAD_DEAD)
+ return;
+
+ // Inactive turrets take no damage. (hm..)
+ if(!self.active)
+ return;
+
+ if(SAME_TEAM(self, attacker))
+ {
+ if(autocvar_g_friendlyfire)
+ damage = damage * autocvar_g_friendlyfire;
+ else
+ return;
+ }
+
+ self.health -= damage;
+
+ // thorw head slightly off aim when hit?
+ if (self.damage_flags & TFL_DMG_HEADSHAKE)
+ {
+ self.tur_head.angles_x = self.tur_head.angles_x + (-0.5 + random()) * damage;
+ self.tur_head.angles_y = self.tur_head.angles_y + (-0.5 + random()) * damage;
+
+ self.SendFlags |= TNSF_ANG;
+ }
+
+ if (self.turret_flags & TUR_FLAG_MOVE)
+ self.velocity = self.velocity + vforce;
+
+ if (self.health <= 0)
+ {
+ self.event_damage = func_null;
+ self.tur_head.event_damage = func_null;
+ self.takedamage = DAMAGE_NO;
+ self.nextthink = time;
+ self.think = turret_die;
+ }
+
+ self.SendFlags |= TNSF_STATUS;
+}
+
+void() turret_think;
+void turret_respawn()
+{
+ // Make sure all parts belong to the same team since
+ // this function doubles as "teamchange" function.
+ self.tur_head.team = self.team;
+ self.effects &= ~EF_NODRAW;
+ self.deadflag = DEAD_NO;
+ self.effects = EF_LOWPRECISION;
+ self.solid = SOLID_BBOX;
+ self.takedamage = DAMAGE_AIM;
+ self.event_damage = turret_damage;
+ self.avelocity = '0 0 0';
+ self.tur_head.avelocity = self.avelocity;
+ self.tur_head.angles = self.idle_aim;
+ self.health = self.max_health;
+ self.enemy = world;
+ self.volly_counter = self.shot_volly;
+ self.ammo = self.ammo_max;
+
+ self.nextthink = time + self.ticrate;
+ self.think = turret_think;
+
+ self.SendFlags = TNSF_FULL_UPDATE;
+
+ TUR_ACTION(self.turretid, TR_SETUP);
+}
+
+
+// Main functions
+#define cvar_base "g_turrets_unit_"
+.float clientframe;
+void turrets_setframe(float _frame, float client_only)
+{
+ if((client_only ? self.clientframe : self.frame ) != _frame)
+ {
+ self.SendFlags |= TNSF_ANIM;
+ self.anim_start_time = time;
+ }
+
+ if(client_only)
+ self.clientframe = _frame;
+ else
+ self.frame = _frame;
+
+}
+
+float turret_send(entity to, float sf)
+{
+
+ WriteByte(MSG_ENTITY, ENT_CLIENT_TURRET);
+ WriteByte(MSG_ENTITY, sf);
+ if(sf & TNSF_SETUP)
+ {
+ WriteByte(MSG_ENTITY, self.turretid);
+
+ WriteCoord(MSG_ENTITY, self.origin_x);
+ WriteCoord(MSG_ENTITY, self.origin_y);
+ WriteCoord(MSG_ENTITY, self.origin_z);
+
+ WriteAngle(MSG_ENTITY, self.angles_x);
+ WriteAngle(MSG_ENTITY, self.angles_y);
+ }
+
+ if(sf & TNSF_ANG)
+ {
+ WriteShort(MSG_ENTITY, rint(self.tur_head.angles_x));
+ WriteShort(MSG_ENTITY, rint(self.tur_head.angles_y));
+ }
+
+ if(sf & TNSF_AVEL)
+ {
+ WriteShort(MSG_ENTITY, rint(self.tur_head.avelocity_x));
+ WriteShort(MSG_ENTITY, rint(self.tur_head.avelocity_y));
+ }
+
+ if(sf & TNSF_MOVE)
+ {
+ WriteShort(MSG_ENTITY, rint(self.origin_x));
+ WriteShort(MSG_ENTITY, rint(self.origin_y));
+ WriteShort(MSG_ENTITY, rint(self.origin_z));
+
+ WriteShort(MSG_ENTITY, rint(self.velocity_x));
+ WriteShort(MSG_ENTITY, rint(self.velocity_y));
+ WriteShort(MSG_ENTITY, rint(self.velocity_z));
+
+ WriteShort(MSG_ENTITY, rint(self.angles_y));
+ }
+
+ if(sf & TNSF_ANIM)
+ {
+ WriteCoord(MSG_ENTITY, self.anim_start_time);
+ WriteByte(MSG_ENTITY, self.frame);
+ }
+
+ if(sf & TNSF_STATUS)
+ {
+ WriteByte(MSG_ENTITY, self.team);
+
+ if(self.health <= 0)
+ WriteByte(MSG_ENTITY, 0);
+ else
+ WriteByte(MSG_ENTITY, ceil((self.health / self.max_health) * 255));
+ }
+
+ return true;
+}
+
+void load_unit_settings(entity ent, string unitname, float is_reload)
+{
+ string sbase;
+
+ if (ent == world)
+ return;
+
+ if(!ent.turret_scale_damage) ent.turret_scale_damage = 1;
+ if(!ent.turret_scale_range) ent.turret_scale_range = 1;
+ if(!ent.turret_scale_refire) ent.turret_scale_refire = 1;
+ if(!ent.turret_scale_ammo) ent.turret_scale_ammo = 1;
+ if(!ent.turret_scale_aim) ent.turret_scale_aim = 1;
+ if(!ent.turret_scale_health) ent.turret_scale_health = 1;
+ if(!ent.turret_scale_respawn) ent.turret_scale_respawn = 1;
+
+ sbase = strcat(cvar_base,unitname);
+ if (is_reload)
+ {
+ ent.enemy = world;
+ ent.tur_head.avelocity = '0 0 0';
+
+ ent.tur_head.angles = '0 0 0';
+ }
+
+ ent.health = cvar(strcat(sbase,"_health")) * ent.turret_scale_health;
+ ent.respawntime = cvar(strcat(sbase,"_respawntime")) * ent.turret_scale_respawn;
+
+ ent.shot_dmg = cvar(strcat(sbase,"_shot_dmg")) * ent.turret_scale_damage;
+ ent.shot_refire = cvar(strcat(sbase,"_shot_refire")) * ent.turret_scale_refire;
+ ent.shot_radius = cvar(strcat(sbase,"_shot_radius")) * ent.turret_scale_damage;
+ ent.shot_speed = cvar(strcat(sbase,"_shot_speed"));
+ ent.shot_spread = cvar(strcat(sbase,"_shot_spread"));
+ ent.shot_force = cvar(strcat(sbase,"_shot_force")) * ent.turret_scale_damage;
+ ent.shot_volly = cvar(strcat(sbase,"_shot_volly"));
+ ent.shot_volly_refire = cvar(strcat(sbase,"_shot_volly_refire")) * ent.turret_scale_refire;
+
+ ent.target_range = cvar(strcat(sbase,"_target_range")) * ent.turret_scale_range;
+ ent.target_range_min = cvar(strcat(sbase,"_target_range_min")) * ent.turret_scale_range;
+ ent.target_range_optimal = cvar(strcat(sbase,"_target_range_optimal")) * ent.turret_scale_range;
+ //ent.target_range_fire = cvar(strcat(sbase,"_target_range_fire")) * ent.turret_scale_range;
+
+ ent.target_select_rangebias = cvar(strcat(sbase,"_target_select_rangebias"));
+ ent.target_select_samebias = cvar(strcat(sbase,"_target_select_samebias"));
+ ent.target_select_anglebias = cvar(strcat(sbase,"_target_select_anglebias"));
+ ent.target_select_playerbias = cvar(strcat(sbase,"_target_select_playerbias"));
+ //ent.target_select_fov = cvar(cvar_gets(sbase,"_target_select_fov"));
+
+ ent.ammo_max = cvar(strcat(sbase,"_ammo_max")) * ent.turret_scale_ammo;
+ ent.ammo_recharge = cvar(strcat(sbase,"_ammo_recharge")) * ent.turret_scale_ammo;
+
+ ent.aim_firetolerance_dist = cvar(strcat(sbase,"_aim_firetolerance_dist"));
+ ent.aim_speed = cvar(strcat(sbase,"_aim_speed")) * ent.turret_scale_aim;
+ ent.aim_maxrotate = cvar(strcat(sbase,"_aim_maxrot"));
+ ent.aim_maxpitch = cvar(strcat(sbase,"_aim_maxpitch"));
+
+ ent.track_type = cvar(strcat(sbase,"_track_type"));
+ ent.track_accel_pitch = cvar(strcat(sbase,"_track_accel_pitch"));
+ ent.track_accel_rotate = cvar(strcat(sbase,"_track_accel_rot"));
+ ent.track_blendrate = cvar(strcat(sbase,"_track_blendrate"));
+
+ if(is_reload)
+ TUR_ACTION(self.turretid, TR_SETUP);
+}
+
+void turret_projectile_explode()
+{
+
+ self.takedamage = DAMAGE_NO;
+ self.event_damage = func_null;
+#ifdef TURRET_DEBUG
+ float d;
+ d = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, self, world, self.owner.shot_force, self.totalfrags, world);
+ self.owner.tur_debug_dmg_t_h = self.owner.tur_debug_dmg_t_h + d;
+ self.owner.tur_debug_dmg_t_f = self.owner.tur_debug_dmg_t_f + self.owner.shot_dmg;
+#else
+ RadiusDamage (self, self.realowner, self.owner.shot_dmg, 0, self.owner.shot_radius, self, world, self.owner.shot_force, self.totalfrags, world);
+#endif
+ remove(self);
+}
+
+void turret_projectile_touch()
+{
+ PROJECTILE_TOUCH;
+ turret_projectile_explode();
+}
+
- if(e_target.vehicle_flags & VHF_ISVEHICLE)
++void turret_projectile_damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector vforce)
+{
+ self.velocity += vforce;
+ self.health -= damage;
+ //self.realowner = attacker; // Dont change realowner, it does not make much sense for turrets
+ if(self.health <= 0)
+ W_PrepareExplosionByDamage(self.owner, turret_projectile_explode);
+}
+
+entity turret_projectile(string _snd, float _size, float _health, float _death, float _proj_type, float _cull, float _cli_anim)
+{
+ entity proj;
+
+ sound (self, CH_WEAPON_A, _snd, VOL_BASE, ATTEN_NORM);
+ proj = spawn ();
+ setorigin(proj, self.tur_shotorg);
+ setsize(proj, '-0.5 -0.5 -0.5' * _size, '0.5 0.5 0.5' * _size);
+ proj.owner = self;
+ proj.realowner = self;
+ proj.bot_dodge = true;
+ proj.bot_dodgerating = self.shot_dmg;
+ proj.think = turret_projectile_explode;
+ proj.touch = turret_projectile_touch;
+ proj.nextthink = time + 9;
+ proj.movetype = MOVETYPE_FLYMISSILE;
+ proj.velocity = normalize(self.tur_shotdir_updated + randomvec() * self.shot_spread) * self.shot_speed;
+ proj.flags = FL_PROJECTILE;
+ proj.enemy = self.enemy;
+ proj.totalfrags = _death;
+ PROJECTILE_MAKETRIGGER(proj);
+ if(_health)
+ {
+ proj.health = _health;
+ proj.takedamage = DAMAGE_YES;
+ proj.event_damage = turret_projectile_damage;
+ }
+ else
+ proj.flags |= FL_NOTARGET;
+
+ CSQCProjectile(proj, _cli_anim, _proj_type, _cull);
+
+ return proj;
+}
+
+/**
+** updates enemy distances, predicted impact point/time
+** and updated aim<->predict impact distance.
+**/
+void turret_do_updates(entity t_turret)
+{
+ vector enemy_pos;
+ entity oldself;
+
+ oldself = self;
+ self = t_turret;
+
+ enemy_pos = real_origin(self.enemy);
+
+ turret_tag_fire_update();
+
+ self.tur_shotdir_updated = v_forward;
+ self.tur_dist_enemy = vlen(self.tur_shotorg - enemy_pos);
+ self.tur_dist_aimpos = vlen(self.tur_shotorg - self.tur_aimpos);
+
+ /*if((self.firecheck_flags & TFL_FIRECHECK_VERIFIED) && (self.enemy))
+ {
+ oldpos = self.enemy.origin;
+ setorigin(self.enemy, self.tur_aimpos);
+ tracebox(self.tur_shotorg, '-1 -1 -1', '1 1 1', self.tur_shotorg + (self.tur_shotdir_updated * self.tur_dist_aimpos), MOVE_NORMAL,self);
+ setorigin(self.enemy, oldpos);
+
+ if(trace_ent == self.enemy)
+ self.tur_dist_impact_to_aimpos = 0;
+ else
+ self.tur_dist_impact_to_aimpos = vlen(trace_endpos - self.tur_aimpos);
+ }
+ else*/
+ tracebox(self.tur_shotorg, '-1 -1 -1','1 1 1', self.tur_shotorg + (self.tur_shotdir_updated * self.tur_dist_aimpos), MOVE_NORMAL,self);
+
+ self.tur_dist_impact_to_aimpos = vlen(trace_endpos - self.tur_aimpos) - (vlen(self.enemy.maxs - self.enemy.mins) * 0.5);
+ self.tur_impactent = trace_ent;
+ self.tur_impacttime = vlen(self.tur_shotorg - trace_endpos) / self.shot_speed;
+
+ self = oldself;
+}
+
+/**
+** Handles head rotation according to
+** the units .track_type and .track_flags
+**/
+.float turret_framecounter;
+void turret_track()
+{
+ vector target_angle; // This is where we want to aim
+ vector move_angle; // This is where we can aim
+ float f_tmp;
+ vector v1, v2;
+ v1 = self.tur_head.angles;
+ v2 = self.tur_head.avelocity;
+
+ if (self.track_flags == TFL_TRACK_NO)
+ return;
+
+ if(!self.active)
+ target_angle = self.idle_aim - ('1 0 0' * self.aim_maxpitch);
+ else if (self.enemy == world)
+ {
+ if(time > self.lip)
+ target_angle = self.idle_aim + self.angles;
+ else
+ target_angle = vectoangles(normalize(self.tur_aimpos - self.tur_shotorg));
+ }
+ else
+ {
+ target_angle = vectoangles(normalize(self.tur_aimpos - self.tur_shotorg));
+ }
+
+ self.tur_head.angles_x = anglemods(self.tur_head.angles_x);
+ self.tur_head.angles_y = anglemods(self.tur_head.angles_y);
+
+ // Find the diffrence between where we currently aim and where we want to aim
+ //move_angle = target_angle - (self.angles + self.tur_head.angles);
+ //move_angle = shortangle_vxy(move_angle,(self.angles + self.tur_head.angles));
+
+ move_angle = AnglesTransform_ToAngles(AnglesTransform_LeftDivide(AnglesTransform_FromAngles(self.angles), AnglesTransform_FromAngles(target_angle))) - self.tur_head.angles;
+ move_angle = shortangle_vxy(move_angle, self.tur_head.angles);
+
+ switch(self.track_type)
+ {
+ case TFL_TRACKTYPE_STEPMOTOR:
+ f_tmp = self.aim_speed * self.ticrate; // dgr/sec -> dgr/tic
+ if (self.track_flags & TFL_TRACK_PITCH)
+ {
+ self.tur_head.angles_x += bound(-f_tmp,move_angle_x, f_tmp);
+ if(self.tur_head.angles_x > self.aim_maxpitch)
+ self.tur_head.angles_x = self.aim_maxpitch;
+
+ if(self.tur_head.angles_x < -self.aim_maxpitch)
+ self.tur_head.angles_x = self.aim_maxpitch;
+ }
+
+ if (self.track_flags & TFL_TRACK_ROTATE)
+ {
+ self.tur_head.angles_y += bound(-f_tmp, move_angle_y, f_tmp);
+ if(self.tur_head.angles_y > self.aim_maxrotate)
+ self.tur_head.angles_y = self.aim_maxrotate;
+
+ if(self.tur_head.angles_y < -self.aim_maxrotate)
+ self.tur_head.angles_y = self.aim_maxrotate;
+ }
+
+ // CSQC
+ self.SendFlags |= TNSF_ANG;
+
+ return;
+
+ case TFL_TRACKTYPE_FLUIDINERTIA:
+ f_tmp = self.aim_speed * self.ticrate; // dgr/sec -> dgr/tic
+ move_angle_x = bound(-self.aim_speed, move_angle_x * self.track_accel_pitch * f_tmp, self.aim_speed);
+ move_angle_y = bound(-self.aim_speed, move_angle_y * self.track_accel_rotate * f_tmp, self.aim_speed);
+ move_angle = (self.tur_head.avelocity * self.track_blendrate) + (move_angle * (1 - self.track_blendrate));
+ break;
+
+ case TFL_TRACKTYPE_FLUIDPRECISE:
+
+ move_angle_y = bound(-self.aim_speed, move_angle_y, self.aim_speed);
+ move_angle_x = bound(-self.aim_speed, move_angle_x, self.aim_speed);
+
+ break;
+ }
+
+ // pitch
+ if (self.track_flags & TFL_TRACK_PITCH)
+ {
+ self.tur_head.avelocity_x = move_angle_x;
+ if((self.tur_head.angles_x + self.tur_head.avelocity_x * self.ticrate) > self.aim_maxpitch)
+ {
+ self.tur_head.avelocity_x = 0;
+ self.tur_head.angles_x = self.aim_maxpitch;
+
+ self.SendFlags |= TNSF_ANG;
+ }
+
+ if((self.tur_head.angles_x + self.tur_head.avelocity_x * self.ticrate) < -self.aim_maxpitch)
+ {
+ self.tur_head.avelocity_x = 0;
+ self.tur_head.angles_x = -self.aim_maxpitch;
+
+ self.SendFlags |= TNSF_ANG;
+ }
+ }
+
+ // rot
+ if (self.track_flags & TFL_TRACK_ROTATE)
+ {
+ self.tur_head.avelocity_y = move_angle_y;
+
+ if((self.tur_head.angles_y + self.tur_head.avelocity_y * self.ticrate) > self.aim_maxrotate)
+ {
+ self.tur_head.avelocity_y = 0;
+ self.tur_head.angles_y = self.aim_maxrotate;
+
+ self.SendFlags |= TNSF_ANG;
+ }
+
+ if((self.tur_head.angles_y + self.tur_head.avelocity_y * self.ticrate) < -self.aim_maxrotate)
+ {
+ self.tur_head.avelocity_y = 0;
+ self.tur_head.angles_y = -self.aim_maxrotate;
+
+ self.SendFlags |= TNSF_ANG;
+ }
+ }
+
+ self.SendFlags |= TNSF_AVEL;
+
+ // Force a angle update every 10'th frame
+ self.turret_framecounter += 1;
+ if(self.turret_framecounter >= 10)
+ {
+ self.SendFlags |= TNSF_ANG;
+ self.turret_framecounter = 0;
+ }
+}
+
+/*
+ + TFL_TARGETSELECT_NO
+ + TFL_TARGETSELECT_LOS
+ + TFL_TARGETSELECT_PLAYERS
+ + TFL_TARGETSELECT_MISSILES
+ - TFL_TARGETSELECT_TRIGGERTARGET
+ + TFL_TARGETSELECT_ANGLELIMITS
+ + TFL_TARGETSELECT_RANGELIMITS
+ + TFL_TARGETSELECT_TEAMCHECK
+ - TFL_TARGETSELECT_NOBUILTIN
+ + TFL_TARGETSELECT_OWNTEAM
+*/
+
+/**
+** Evaluate a entity for target valitity based on validate_flags
+** NOTE: the caller must check takedamage before calling this, to inline this check.
+**/
+float turret_validate_target(entity e_turret, entity e_target, float validate_flags)
+{
+ vector v_tmp;
+
+ //if(!validate_flags & TFL_TARGETSELECT_NOBUILTIN)
+ // return -0.5;
+
+ if(!e_target)
+ return -2;
+
+ if(e_target.owner == e_turret)
+ return -0.5;
+
+ if(!checkpvs(e_target.origin, e_turret))
+ return -1;
+
+ if(e_target.alpha <= 0.3)
+ return -1;
+
+ if(g_onslaught)
+ if (substring(e_target.classname, 0, 10) == "onslaught_") // don't attack onslaught targets, that's the player's job!
+ return - 3;
+
+ if (validate_flags & TFL_TARGETSELECT_NO)
+ return -4;
+
+ // If only this was used more..
+ if (e_target.flags & FL_NOTARGET)
+ return -5;
+
+ // Cant touch this
- if (e.turret_flags & TUR_FLAG_ISTURRET)
++ if(IS_VEHICLE(e_target))
+ {
+ if (e_target.vehicle_health <= 0)
+ return -6;
+ }
+ else if (e_target.health <= 0)
+ return -6;
+ else if(e_target.frozen > 0)
+ return -6;
+
+ // player
+ if (IS_CLIENT(e_target))
+ {
+ if(!(validate_flags & TFL_TARGETSELECT_PLAYERS))
+ return -7;
+
+ if (e_target.deadflag != DEAD_NO)
+ return -8;
+ }
+
+ // enemy turrets
+ if(validate_flags & TFL_TARGETSELECT_NOTURRETS)
+ if(e_target.owner.tur_head == e_target)
+ if(e_target.team != e_turret.team) // Dont break support units.
+ return -9;
+
+ // Missile
+ if (e_target.flags & FL_PROJECTILE)
+ if(!(validate_flags & TFL_TARGETSELECT_MISSILES))
+ return -10;
+
+ if (validate_flags & TFL_TARGETSELECT_MISSILESONLY)
+ if(!(e_target.flags & FL_PROJECTILE))
+ return -10.5;
+
+ // Team check
+ if (validate_flags & TFL_TARGETSELECT_TEAMCHECK)
+ {
+ if (validate_flags & TFL_TARGETSELECT_OWNTEAM)
+ {
+ if (e_target.team != e_turret.team)
+ return -11;
+
+ if (e_turret.team != e_target.owner.team)
+ return -12;
+ }
+ else
+ {
+ if (e_target.team == e_turret.team)
+ return -13;
+
+ if (e_turret.team == e_target.owner.team)
+ return -14;
+ }
+ }
+
+ // Range limits?
+ tvt_dist = vlen(e_turret.origin - real_origin(e_target));
+ if (validate_flags & TFL_TARGETSELECT_RANGELIMITS)
+ {
+ if (tvt_dist < e_turret.target_range_min)
+ return -15;
+
+ if (tvt_dist > e_turret.target_range)
+ return -16;
+ }
+
+ // Can we even aim this thing?
+ tvt_thadv = angleofs3(e_turret.tur_head.origin, e_turret.angles + e_turret.tur_head.angles, e_target);
+ tvt_tadv = shortangle_vxy(angleofs(e_turret, e_target), e_turret.angles);
+ tvt_thadf = vlen(tvt_thadv);
+ tvt_tadf = vlen(tvt_tadv);
+
+ /*
+ if(validate_flags & TFL_TARGETSELECT_FOV)
+ {
+ if(e_turret.target_select_fov < tvt_thadf)
+ return -21;
+ }
+ */
+
+ if (validate_flags & TFL_TARGETSELECT_ANGLELIMITS)
+ {
+ if (fabs(tvt_tadv_x) > e_turret.aim_maxpitch)
+ return -17;
+
+ if (fabs(tvt_tadv_y) > e_turret.aim_maxrotate)
+ return -18;
+ }
+
+ // Line of sight?
+ if (validate_flags & TFL_TARGETSELECT_LOS)
+ {
+ v_tmp = real_origin(e_target) + ((e_target.mins + e_target.maxs) * 0.5);
+
+ traceline(e_turret.origin + '0 0 16', v_tmp, 0, e_turret);
+
+ if (e_turret.aim_firetolerance_dist < vlen(v_tmp - trace_endpos))
+ return -19;
+ }
+
+ if (e_target.classname == "grapplinghook")
+ return -20;
+
+ /*
+ if (e_target.classname == "func_button")
+ return -21;
+ */
+
+#ifdef TURRET_DEBUG_TARGETSELECT
+ dprint("Target:",e_target.netname," is a valid target for ",e_turret.netname,"\n");
+#endif
+
+ return 1;
+}
+
+entity turret_select_target()
+{
+ entity e; // target looper entity
+ float score; // target looper entity score
+ entity e_enemy; // currently best scoreing target
+ float m_score; // currently best scoreing target's score
+
+ m_score = 0;
+ if(self.enemy && self.enemy.takedamage && turret_validate_target(self,self.enemy,self.target_validate_flags) > 0)
+ {
+ e_enemy = self.enemy;
+ m_score = self.turret_score_target(self,e_enemy) * self.target_select_samebias;
+ }
+ else
+ e_enemy = self.enemy = world;
+
+ e = findradius(self.origin, self.target_range);
+
+ // Nothing to aim at?
+ if (!e)
+ return world;
+
+ while (e)
+ {
+ if(e.takedamage)
+ {
+ float f = turret_validate_target(self, e, self.target_select_flags);
+ //dprint("F is: ", ftos(f), "\n");
+ if ( f > 0)
+ {
+ score = self.turret_score_target(self,e);
+ if ((score > m_score) && (score > 0))
+ {
+ e_enemy = e;
+ m_score = score;
+ }
+ }
+ }
+ e = e.chain;
+ }
+
+ return e_enemy;
+}
+
+
+/*
+ + = implemented
+ - = not implemented
+
+ + TFL_FIRECHECK_NO
+ + TFL_FIRECHECK_WORLD
+ + TFL_FIRECHECK_DEAD
+ + TFL_FIRECHECK_DISTANCES
+ - TFL_FIRECHECK_LOS
+ + TFL_FIRECHECK_AIMDIST
+ + TFL_FIRECHECK_REALDIST
+ - TFL_FIRECHECK_ANGLEDIST
+ - TFL_FIRECHECK_TEAMCECK
+ + TFL_FIRECHECK_AFF
+ + TFL_FIRECHECK_AMMO_OWN
+ + TFL_FIRECHECK_AMMO_OTHER
+ + TFL_FIRECHECK_REFIRE
+*/
+
+/**
+** Preforms pre-fire checks based on the uints firecheck_flags
+**/
+float turret_firecheck()
+{
+ // This one just dont care =)
+ if (self.firecheck_flags & TFL_FIRECHECK_NO)
+ return 1;
+
+ if (self.enemy == world)
+ return 0;
+
+ // Ready?
+ if (self.firecheck_flags & TFL_FIRECHECK_REFIRE)
+ if (self.attack_finished_single > time) return 0;
+
+ // Special case: volly fire turret that has to fire a full volly if a shot was fired.
+ if (self.shoot_flags & TFL_SHOOT_VOLLYALWAYS)
+ if (self.volly_counter != self.shot_volly)
+ if(self.ammo >= self.shot_dmg)
+ return 1;
+
+ // Lack of zombies makes shooting dead things unnecessary :P
+ if (self.firecheck_flags & TFL_FIRECHECK_DEAD)
+ if (self.enemy.deadflag != DEAD_NO)
+ return 0;
+
+ // Own ammo?
+ if (self.firecheck_flags & TFL_FIRECHECK_AMMO_OWN)
+ if (self.ammo < self.shot_dmg)
+ return 0;
+
+ // Other's ammo? (support-supply units)
+ if (self.firecheck_flags & TFL_FIRECHECK_AMMO_OTHER)
+ if (self.enemy.ammo >= self.enemy.ammo_max)
+ return 0;
+
+ // Target of opertunity?
+ if(turret_validate_target(self, self.tur_impactent, self.target_validate_flags) > 0)
+ {
+ self.enemy = self.tur_impactent;
+ return 1;
+ }
+
+ if (self.firecheck_flags & TFL_FIRECHECK_DISTANCES)
+ {
+ // To close?
+ if (self.tur_dist_aimpos < self.target_range_min)
+ if(turret_validate_target(self, self.tur_impactent, self.target_validate_flags) > 0)
+ return 1; // Target of opertunity?
+ else
+ return 0;
+ }
+
+ // Try to avoid FF?
+ if (self.firecheck_flags & TFL_FIRECHECK_AFF)
+ if (self.tur_impactent.team == self.team)
+ return 0;
+
+ // aim<->predicted impact
+ if (self.firecheck_flags & TFL_FIRECHECK_AIMDIST)
+ if (self.tur_dist_impact_to_aimpos > self.aim_firetolerance_dist)
+ return 0;
+
+ // Volly status
+ if (self.shot_volly > 1)
+ if (self.volly_counter == self.shot_volly)
+ if (self.ammo < (self.shot_dmg * self.shot_volly))
+ return 0;
+
+ /*if(self.firecheck_flags & TFL_FIRECHECK_VERIFIED)
+ if(self.tur_impactent != self.enemy)
+ return 0;*/
+
+ return 1;
+}
+
+void turret_fire()
+{
+ if (autocvar_g_turrets_nofire != 0)
+ return;
+
+ TUR_ACTION(self.turretid, TR_ATTACK);
+
+ self.attack_finished_single = time + self.shot_refire;
+ self.ammo -= self.shot_dmg;
+ self.volly_counter = self.volly_counter - 1;
+
+ if (self.volly_counter <= 0)
+ {
+ self.volly_counter = self.shot_volly;
+
+ if (self.shoot_flags & TFL_SHOOT_CLEARTARGET)
+ self.enemy = world;
+
+ if (self.shot_volly > 1)
+ self.attack_finished_single = time + self.shot_volly_refire;
+ }
+
+#ifdef TURRET_DEBUG
+ if (self.enemy) paint_target3(self.tur_aimpos, 64, self.tur_debug_rvec, self.tur_impacttime + 0.25);
+#endif
+}
+
+void turret_think()
+{
+ entity e;
+
+ self.nextthink = time + self.ticrate;
+
+ // ONS uses somewhat backwards linking.
+ if (teamplay)
+ {
+ if (g_onslaught)
+ if (self.target)
+ {
+ e = find(world, targetname,self.target);
+ if (e != world)
+ self.team = e.team;
+ }
+
+ if (self.team != self.tur_head.team)
+ turret_respawn();
+ }
+
+#ifdef TURRET_DEBUG
+ if (self.tur_debug_tmr1 < time)
+ {
+ if (self.enemy) paint_target (self.enemy,128,self.tur_debug_rvec,0.9);
+ paint_target(self,256,self.tur_debug_rvec,0.9);
+ self.tur_debug_tmr1 = time + 1;
+ }
+#endif
+
+ // Handle ammo
+ if (!(self.spawnflags & TSF_NO_AMMO_REGEN))
+ if (self.ammo < self.ammo_max)
+ self.ammo = min(self.ammo + self.ammo_recharge, self.ammo_max);
+
+ // Inactive turrets needs to run the think loop,
+ // So they can handle animation and wake up if need be.
+ if(!self.active)
+ {
+ turret_track();
+ return;
+ }
+
+ // This is typicaly used for zaping every target in range
+ // turret_fusionreactor uses this to recharge friendlys.
+ if (self.shoot_flags & TFL_SHOOT_HITALLVALID)
+ {
+ // Do a self.turret_fire for every valid target.
+ e = findradius(self.origin,self.target_range);
+ while (e)
+ {
+ if(e.takedamage)
+ {
+ if (turret_validate_target(self,e,self.target_validate_flags))
+ {
+ self.enemy = e;
+
+ turret_do_updates(self);
+
+ if (self.turret_firecheckfunc())
+ turret_fire();
+ }
+ }
+
+ e = e.chain;
+ }
+ self.enemy = world;
+ }
+ else if(self.shoot_flags & TFL_SHOOT_CUSTOM)
+ {
+ // This one is doing something.. oddball. assume its handles what needs to be handled.
+
+ // Predict?
+ if(!(self.aim_flags & TFL_AIM_NO))
+ self.tur_aimpos = turret_aim_generic();
+
+ // Turn & pitch?
+ if(!(self.track_flags & TFL_TRACK_NO))
+ turret_track();
+
+ turret_do_updates(self);
+
+ // Fire?
+ if (self.turret_firecheckfunc())
+ turret_fire();
+ }
+ else
+ {
+ // Special case for volly always. if it fired once it must compleate the volly.
+ if(self.shoot_flags & TFL_SHOOT_VOLLYALWAYS)
+ if(self.volly_counter != self.shot_volly)
+ {
+ // Predict or whatnot
+ if(!(self.aim_flags & TFL_AIM_NO))
+ self.tur_aimpos = turret_aim_generic();
+
+ // Turn & pitch
+ if(!(self.track_flags & TFL_TRACK_NO))
+ turret_track();
+
+ turret_do_updates(self);
+
+ // Fire!
+ if (self.turret_firecheckfunc() != 0)
+ turret_fire();
+
+ TUR_ACTION(self.turretid, TR_THINK);
+
+ return;
+ }
+
+ // Check if we have a vailid enemy, and try to find one if we dont.
+
+ // g_turrets_targetscan_maxdelay forces a target re-scan at least this often
+ float do_target_scan = 0;
+ if((self.target_select_time + autocvar_g_turrets_targetscan_maxdelay) < time)
+ do_target_scan = 1;
+
+ // Old target (if any) invalid?
+ if(self.target_validate_time < time)
+ if (turret_validate_target(self, self.enemy, self.target_validate_flags) <= 0)
+ {
+ self.enemy = world;
+ self.target_validate_time = time + 0.5;
+ do_target_scan = 1;
+ }
+
+ // But never more often then g_turrets_targetscan_mindelay!
+ if (self.target_select_time + autocvar_g_turrets_targetscan_mindelay > time)
+ do_target_scan = 0;
+
+ if(do_target_scan)
+ {
+ self.enemy = turret_select_target();
+ self.target_select_time = time;
+ }
+
+ // No target, just go to idle, do any custom stuff and bail.
+ if (self.enemy == world)
+ {
+ // Turn & pitch
+ if(!(self.track_flags & TFL_TRACK_NO))
+ turret_track();
+
+ TUR_ACTION(self.turretid, TR_THINK);
+
+ // And bail.
+ return;
+ }
+ else
+ self.lip = time + autocvar_g_turrets_aimidle_delay; // Keep track of the last time we had a target.
+
+ // Predict?
+ if(!(self.aim_flags & TFL_AIM_NO))
+ self.tur_aimpos = turret_aim_generic();
+
+ // Turn & pitch?
+ if(!(self.track_flags & TFL_TRACK_NO))
+ turret_track();
+
+ turret_do_updates(self);
+
+ // Fire?
+ if (self.turret_firecheckfunc())
+ turret_fire();
+ }
+
+ TUR_ACTION(self.turretid, TR_THINK);
+}
+
+/*
+ When .used a turret switch team to activator.team.
+ If activator is world, the turret go inactive.
+*/
+void turret_use()
+{
+ dprint("Turret ",self.netname, " used by ", activator.classname, "\n");
+
+ self.team = activator.team;
+
+ if(self.team == 0)
+ self.active = ACTIVE_NOT;
+ else
+ self.active = ACTIVE_ACTIVE;
+
+}
+
+void turret_link()
+{
+ Net_LinkEntity(self, true, 0, turret_send);
+ self.think = turret_think;
+ self.nextthink = time;
+ self.tur_head.effects = EF_NODRAW;
+}
+
+void turrets_manager_think()
+{
+ self.nextthink = time + 1;
+
+ entity e;
+ if (autocvar_g_turrets_reloadcvars == 1)
+ {
+ e = nextent(world);
+ while (e)
+ {
- if(MUTATOR_CALLHOOK(TurretSpawn))
++ if (IS_TURRET(e))
+ {
+ load_unit_settings(e,e.cvar_basename,1);
+ TUR_ACTION(self.turretid, TR_THINK);
+ }
+
+ e = nextent(e);
+ }
+ cvar_set("g_turrets_reloadcvars","0");
+ }
+}
+
+float turret_initialize(float tur_id)
+{
+ if(!autocvar_g_turrets)
+ return false;
+
+ entity e;
+ entity tur = get_turretinfo(tur_id);
+ if(tur.turretid == 0)
+ return false; // invalid turret
+
+ if(!self.tur_head) { TUR_ACTION(tur_id, TR_PRECACHE); } // if tur_head exists, we can assume this turret re-spawned
+
+ e = find(world, classname, "turret_manager");
+ if(!e)
+ {
+ e = spawn();
+ e.classname = "turret_manager";
+ e.think = turrets_manager_think;
+ e.nextthink = time + 2;
+ }
+
+ if(!(self.spawnflags & TSF_SUSPENDED))
+ builtin_droptofloor();
+
+ self.cvar_basename = tur.cvar_basename;
+ load_unit_settings(self, self.cvar_basename, 0);
+
+ if(!self.team || !teamplay) { self.team = MAX_SHOT_DISTANCE; }
+ if(!self.ticrate) { self.ticrate = ((self.turret_flags & TUR_FLAG_SUPPORT) ? 0.2 : 0.1); }
+ if(!self.health) { self.health = 1000; }
+ if(!self.shot_refire) { self.shot_refire = 1; }
+ if(!self.tur_shotorg) { self.tur_shotorg = '50 0 50'; }
+ if(!self.turret_flags) { self.turret_flags = TUR_FLAG_SPLASH | TUR_FLAG_MEDPROJ | TUR_FLAG_PLAYER; }
+ if(!self.damage_flags) { self.damage_flags = TFL_DMG_YES | TFL_DMG_RETALIATE | TFL_DMG_AIMSHAKE; }
+ if(!self.aim_flags) { self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE; }
+ if(!self.track_type) { self.track_type = TFL_TRACKTYPE_STEPMOTOR; }
+ if(!self.track_flags) { self.track_flags = TFL_TRACK_PITCH | TFL_TRACK_ROTATE; }
+ if(!self.ammo_flags) { self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE; }
+ if(!self.target_select_flags) { self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_ANGLELIMITS; }
+ if(!self.firecheck_flags) { self.firecheck_flags = TFL_FIRECHECK_DEAD | TFL_FIRECHECK_DISTANCES | TFL_FIRECHECK_LOS
+ | TFL_FIRECHECK_AIMDIST | TFL_FIRECHECK_TEAMCHECK | TFL_FIRECHECK_AMMO_OWN | TFL_FIRECHECK_REFIRE; }
+
+ if(self.track_type != TFL_TRACKTYPE_STEPMOTOR)
+ {
+ // Fluid / Ineria mode. Looks mutch nicer.
+ // Can reduce aim preformance alot, needs a bit diffrent aimspeed
+
+ self.aim_speed = bound(0.1, ((!self.aim_speed) ? 180 : self.aim_speed), 1000);
+
+ if(!self.track_accel_pitch) { self.track_accel_pitch = 0.5; }
+ if(!self.track_accel_rotate) { self.track_accel_rotate = 0.5; }
+ if(!self.track_blendrate) { self.track_blendrate = 0.35; }
+ }
+
+ self.respawntime = max(-1, ((!self.respawntime) ? 60 : self.respawntime));
+ self.shot_refire = bound(0.01, ((!self.shot_refire) ? 1 : self.shot_refire), 9999);
+ self.shot_dmg = max(1, ((!self.shot_dmg) ? self.shot_refire * 50 : self.shot_dmg));
+ self.shot_radius = max(1, ((!self.shot_radius) ? self.shot_dmg * 0.5 : self.shot_radius));
+ self.shot_speed = max(1, ((!self.shot_speed) ? 2500 : self.shot_speed));
+ self.shot_spread = bound(0.0001, ((!self.shot_spread) ? 0.0125 : self.shot_spread), 500);
+ self.shot_force = bound(0.001, ((!self.shot_force) ? self.shot_dmg * 0.5 + self.shot_radius * 0.5 : self.shot_force), 5000);
+ self.shot_volly = bound(1, ((!self.shot_volly) ? 1 : self.shot_volly), floor(self.ammo_max / self.shot_dmg));
+ self.shot_volly_refire = bound(self.shot_refire, ((!self.shot_volly_refire) ? self.shot_refire * self.shot_volly : self.shot_volly_refire), 60);
+ self.target_range = bound(0, ((!self.target_range) ? self.shot_speed * 0.5 : self.target_range), MAX_SHOT_DISTANCE);
+ self.target_range_min = bound(0, ((!self.target_range_min) ? self.shot_radius * 2 : self.target_range_min), MAX_SHOT_DISTANCE);
+ self.target_range_optimal = bound(0, ((!self.target_range_optimal) ? self.target_range * 0.5 : self.target_range_optimal), MAX_SHOT_DISTANCE);
+ self.aim_maxrotate = bound(0, ((!self.aim_maxrotate) ? 90 : self.aim_maxrotate), 360);
+ self.aim_maxpitch = bound(0, ((!self.aim_maxpitch) ? 20 : self.aim_maxpitch), 90);
+ self.aim_speed = bound(0.1, ((!self.aim_speed) ? 36 : self.aim_speed), 1000);
+ self.aim_firetolerance_dist = bound(0.1, ((!self.aim_firetolerance_dist) ? 5 + (self.shot_radius * 2) : self.aim_firetolerance_dist), MAX_SHOT_DISTANCE);
+ self.target_select_rangebias = bound(-10, ((!self.target_select_rangebias) ? 1 : self.target_select_rangebias), 10);
+ self.target_select_samebias = bound(-10, ((!self.target_select_samebias) ? 1 : self.target_select_samebias), 10);
+ self.target_select_anglebias = bound(-10, ((!self.target_select_anglebias) ? 1 : self.target_select_anglebias), 10);
+ self.target_select_missilebias = bound(-10, ((!self.target_select_missilebias) ? 1 : self.target_select_missilebias), 10);
+ self.target_select_playerbias = bound(-10, ((!self.target_select_playerbias) ? 1 : self.target_select_playerbias), 10);
+ self.ammo_max = max(self.shot_dmg, ((!self.ammo_max) ? self.shot_dmg * 10 : self.ammo_max));
+ self.ammo_recharge = max(0, ((!self.ammo_recharge) ? self.shot_dmg * 0.5 : self.ammo_recharge));
+
+ self.turret_flags = TUR_FLAG_ISTURRET | (tur.spawnflags);
+
+ if(self.turret_flags & TUR_FLAG_SPLASH)
+ self.aim_flags |= TFL_AIM_SPLASH;
+
+ if(self.turret_flags & TUR_FLAG_MISSILE)
+ self.target_select_flags |= TFL_TARGETSELECT_MISSILES;
+
+ if(self.turret_flags & TUR_FLAG_PLAYER)
+ self.target_select_flags |= TFL_TARGETSELECT_PLAYERS;
+
+ if(self.spawnflags & TSL_NO_RESPAWN)
+ self.damage_flags |= TFL_DMG_DEATH_NORESPAWN;
+
+ if (self.turret_flags & TUR_FLAG_SUPPORT)
+ self.turret_score_target = turret_targetscore_support;
+ else
+ self.turret_score_target = turret_targetscore_generic;
+
+ ++turret_count;
+
+ setmodel(self, tur.model);
+ setsize(self, tur.mins, tur.maxs);
+
+ self.turretid = tur_id;
+ self.classname = "turret_main";
+ self.active = ACTIVE_ACTIVE;
+ self.effects = EF_NODRAW;
+ self.netname = TUR_NAME(tur_id);
+ self.ticrate = bound(sys_frametime, self.ticrate, 60);
+ self.max_health = self.health;
+ self.target_validate_flags = self.target_select_flags;
+ self.ammo = self.ammo_max;
+ self.ammo_recharge *= self.ticrate;
+ self.solid = SOLID_BBOX;
+ self.takedamage = DAMAGE_AIM;
+ self.movetype = MOVETYPE_NOCLIP;
+ self.view_ofs = '0 0 0';
+ self.turret_firecheckfunc = turret_firecheck;
+ self.event_damage = turret_damage;
+ self.use = turret_use;
+ self.bot_attack = true;
+ self.nextthink = time + 1;
+ self.nextthink += turret_count * sys_frametime;
+
+ self.tur_head = spawn();
+ setmodel(self.tur_head, tur.head_model);
+ setsize(self.tur_head, '0 0 0', '0 0 0');
+ setorigin(self.tur_head, '0 0 0');
+ setattachment(self.tur_head, self, "tag_head");
+
+ self.tur_head.netname = self.tur_head.classname = "turret_head";
+ self.tur_head.team = self.team;
+ self.tur_head.owner = self;
+ self.tur_head.takedamage = DAMAGE_NO;
+ self.tur_head.solid = SOLID_NOT;
+ self.tur_head.movetype = self.movetype;
+
+ if(!self.tur_defend)
+ if(self.target != "")
+ {
+ self.tur_defend = find(world, targetname, self.target);
+ if (self.tur_defend == world)
+ {
+ self.target = "";
+ dprint("Turret has invalid defendpoint!\n");
+ }
+ }
+
+ if (self.tur_defend)
+ self.idle_aim = self.tur_head.angles + angleofs(self.tur_head, self.tur_defend);
+ else
+ self.idle_aim = '0 0 0';
+
+#ifdef TURRET_DEBUG
+ self.tur_debug_start = self.nextthink;
+ while (vlen(self.tur_debug_rvec) < 2)
+ self.tur_debug_rvec = randomvec() * 4;
+
+ self.tur_debug_rvec_x = fabs(self.tur_debug_rvec_x);
+ self.tur_debug_rvec_y = fabs(self.tur_debug_rvec_y);
+ self.tur_debug_rvec_z = fabs(self.tur_debug_rvec_z);
+#endif
+
+ turret_link();
+ turret_respawn();
+ turret_tag_fire_update();
+
+ TUR_ACTION(tur_id, TR_SETUP);
+
++ if(MUTATOR_CALLHOOK(TurretSpawn, self))
+ return false;
+
+ return true;
+}
+#endif
--- /dev/null
+#ifndef SV_TURRETS_H
+#define SV_TURRETS_H
+
+// turret fields
+.float ticrate; // interal ai think rate
+.vector aim_idle; // where to aim while idle
+.entity tur_head; // top part of the turret
+.entity tur_defend; // defend this entity
+.vector tur_shotorg; // shot origin
+.vector tur_aimpos; // aiming location
+.float tur_impacttime; // predicted projectile impact time
+.entity tur_impactent; // entity the projectile hit
+.float tur_dist_enemy; // distance to enemy
+.float tur_dist_aimpos; // distance to aim location
+.float tur_dist_impact_to_aimpos; // distance impact<->aim
+.float volly_counter; // decrement counter from .shot_volly to 0
+
+.float shot_refire; // attack refire
+.float shot_speed; // projectile speed
+.float shot_spread; // inaccuracy
+.float shot_dmg; // core damage of projectile
+.float shot_radius; // projectile damage radius
+.float shot_force; // projectile damage force
+.float shot_volly; // smaller than 1 = shoot # times at target
+.float shot_volly_refire; // refire after completed volly
+
+.float target_range;
+.float target_range_min;
+.float target_range_optimal;
+
+.float target_select_rangebias;
+.float target_select_samebias;
+.float target_select_anglebias;
+.float target_select_missilebias;
+.float target_select_playerbias;
+.float target_select_time; // last time turret had a valid target
+.float target_validate_time; // throttle re-validation of current target
+
+.float aim_firetolerance_dist;
+.float aim_speed;
+.float aim_maxpitch;
+.float aim_maxrotate;
+
+.float ammo; // current ammo
+.float ammo_recharge; // recharge rate
+.float ammo_max; // maximum ammo
+
+.vector idle_aim;
+
+/// Map time control over pain inflicted
+.float turret_scale_damage;
+/// Map time control targetting range
+.float turret_scale_range;
+/// Map time control refire
+.float turret_scale_refire;
+/// Map time control ammo held and recharged
+.float turret_scale_ammo;
+/// Map time control aim speed
+.float turret_scale_aim;
+/// Map time control health
+.float turret_scale_health;
+/// Map time control respawn time
+.float turret_scale_respawn;
+
+// tracking type
+.float track_type;
+const float TFL_TRACKTYPE_STEPMOTOR = 1; // hard angle increments, ugly for fast turning with best accuracy
+const float TFL_TRACKTYPE_FLUIDPRECISE = 2; // smooth absolute movement, looks OK with fair accuracy
+const float TFL_TRACKTYPE_FLUIDINERTIA = 3; // simulated inertia ("wobbly" mode), worst accuracy, depends on below flags
+.float track_accel_pitch;
+.float track_accel_rotate;
+.float track_blendrate;
+
+void() turret_respawn;
+
+/// updates aim org, shot org, shot dir and enemy org for selected turret
+void turret_do_updates(entity e_turret);
+.vector tur_shotdir_updated;
+
+.float() turret_firecheckfunc; // TODO: deprecate!
+
++void turrets_setframe(float _frame, float client_only);
++
++float turret_initialize(float tur_id);
++
+/// Function to use for target evaluation. usualy turret_targetscore_generic
+.float(entity _turret, entity _target) turret_score_target;
+
+.float(entity e_target,entity e_sender) turret_addtarget;
+
+.entity pathcurrent;
+
+float turret_count;
+
+// debugging
+// Uncomment below to enable various debug output.
+//#define TURRET_DEBUG
+//#define TURRET_DEBUG_TARGETVALIDATE
+//#define TURRET_DEBUG_TARGETSELECT
+#ifdef TURRET_DEBUG
+.float tur_debug_dmg_t_h; // total damage that hit something (can be more than tur_debug_dmg_t_f since it should count radius damage)
+.float tur_debug_dmg_t_f; // total damage
+.float tur_debug_start; // turret initialization time
+.float tur_debug_tmr1; // random timer
+.float tur_debug_tmr2; // random timer
+.float tur_debug_tmr3; // random timer
+.vector tur_debug_rvec; // random vector
+#endif
+
+// aiming
+vector tvt_thadv; // turret head angle diff vector, updated by a successful call to turret_validate_target
+vector tvt_tadv; // turret angle diff vector, updated by a successful call to turret_validate_target
+float tvt_thadf; // turret head angle diff float, updated by a successful call to turret_validate_target
+float tvt_tadf; // turret angle diff float, updated by a successful call to turret_validate_target
+float tvt_dist; // turret distance, updated by a successful call to turret_validate_target
+
+#endif
--- /dev/null
- precache_model ("models/turrets/terrainbase.md3");
+#include "all.qh"
+
+// TURRET PLUGIN SYSTEM
+entity turret_info[TUR_MAXCOUNT];
+entity dummy_turret_info;
+
+void turrets_common_precache()
+{
+ precache_sound ("weapons/rocket_impact.wav");
+ precache_model ("models/turrets/base-gib1.md3");
+ precache_model ("models/turrets/base-gib2.md3");
+ precache_model ("models/turrets/base-gib3.md3");
+ precache_model ("models/turrets/base-gib4.md3");
+ precache_model ("models/turrets/head-gib1.md3");
+ precache_model ("models/turrets/head-gib2.md3");
+ precache_model ("models/turrets/head-gib3.md3");
+ precache_model ("models/turrets/head-gib4.md3");
+ precache_model ("models/turrets/base.md3");
+ precache_model ("models/turrets/rocket.md3");
+
+ precache_model ("models/turrets/c512.md3");
+ precache_model ("models/marker.md3");
+
+#ifdef TURRET_DEBUG
+ precache_model ("models/turrets/c512.md3");
+ precache_model ("models/pathlib/goodsquare.md3");
+ precache_model ("models/pathlib/badsquare.md3");
+ precache_model ("models/pathlib/square.md3");
+ precache_model ("models/pathlib/edge.md3");
+#endif
+}
+
+void register_turret(float id, float(float) func, float turretflags, vector min_s, vector max_s, string modelname, string headmodelname, string shortname, string mname)
+{
+ entity e;
+ turret_info[id - 1] = e = spawn();
+ e.classname = "turret_info";
+ e.turretid = id;
+ e.netname = shortname;
+ e.turret_name = mname;
+ e.turret_func = func;
+ e.mdl = modelname;
+ e.cvar_basename = shortname;
+ e.spawnflags = turretflags;
+ e.mins = min_s;
+ e.maxs = max_s;
+ e.model = strzone(strcat("models/turrets/", modelname));
+ e.head_model = strzone(strcat("models/turrets/", headmodelname));
+
+ #ifndef MENUQC
+ turrets_common_precache();
+ #endif
+}
+float t_null(float dummy) { return 0; }
+void register_turrets_done()
+{
+ dummy_turret_info = spawn();
+ dummy_turret_info.classname = "turret_info";
+ dummy_turret_info.turretid = 0; // you can recognize dummies by this
+ dummy_turret_info.netname = "";
+ dummy_turret_info.turret_name = "Turret";
+ dummy_turret_info.turret_func = t_null;
+ dummy_turret_info.mdl = "";
+ dummy_turret_info.mins = '-0 -0 -0';
+ dummy_turret_info.maxs = '0 0 0';
+ dummy_turret_info.model = "";
+}
+entity get_turretinfo(float id)
+{
+ entity m;
+ if(id < TUR_FIRST || id > TUR_LAST)
+ return dummy_turret_info;
+ m = turret_info[id - 1];
+ if(m)
+ return m;
+ return dummy_turret_info;
+}
--- /dev/null
- // Are we close enougth to a path node to switch to the next?
- if (vlen(self.origin - self.pathcurrent.origin) < 64)
- if (self.pathcurrent.path_next == world)
- {
- // Path endpoint reached
- pathlib_deletepath(self.pathcurrent.owner);
- self.pathcurrent = world;
-
- if (self.pathgoal)
- {
- if (self.pathgoal.use)
- self.pathgoal.use();
-
- if (self.pathgoal.enemy)
- {
- self.pathcurrent = pathlib_astar(self.pathgoal.origin,self.pathgoal.enemy.origin);
- self.pathgoal = self.pathgoal.enemy;
- }
- }
- else
- self.pathgoal = world;
- }
- else
- self.pathcurrent = self.pathcurrent.path_next;
+#ifdef REGISTER_TURRET
+REGISTER_TURRET(
+/* TUR_##id */ EWHEEL,
+/* function */ t_ewheel,
+/* spawnflags */ TUR_FLAG_PLAYER | TUR_FLAG_MOVE | TUR_FLAG_ROAM,
+/* mins,maxs */ '-32 -32 0', '32 32 48',
+/* model */ "ewheel-base2.md3",
+/* head_model */ "ewheel-gun1.md3",
+/* netname */ "ewheel",
+/* fullname */ _("eWheel Turret")
+);
+#else
+#ifdef SVQC
+float autocvar_g_turrets_unit_ewheel_speed_fast;
+float autocvar_g_turrets_unit_ewheel_speed_slow;
+float autocvar_g_turrets_unit_ewheel_speed_slower;
+float autocvar_g_turrets_unit_ewheel_speed_stop;
+float autocvar_g_turrets_unit_ewheel_turnrate;
+
+const float ewheel_anim_stop = 0;
+const float ewheel_anim_fwd_slow = 1;
+const float ewheel_anim_fwd_fast = 2;
+const float ewheel_anim_bck_slow = 3;
+const float ewheel_anim_bck_fast = 4;
+
+//#define EWHEEL_FANCYPATH
+void ewheel_move_path()
+{
+#ifdef EWHEEL_FANCYPATH
- if (vlen(self.origin - self.pathcurrent.origin) < 64)
- self.pathcurrent = self.pathcurrent.enemy;
++ // Are we close enougth to a path node to switch to the next?
++ if (vlen(self.origin - self.pathcurrent.origin) < 64)
++ if (self.pathcurrent.path_next == world)
++ {
++ // Path endpoint reached
++ pathlib_deletepath(self.pathcurrent.owner);
++ self.pathcurrent = world;
++
++ if (self.pathgoal)
++ {
++ if (self.pathgoal.use)
++ self.pathgoal.use();
++
++ if (self.pathgoal.enemy)
++ {
++ self.pathcurrent = pathlib_astar(self.pathgoal.origin,self.pathgoal.enemy.origin);
++ self.pathgoal = self.pathgoal.enemy;
++ }
++ }
++ else
++ self.pathgoal = world;
++ }
++ else
++ self.pathcurrent = self.pathcurrent.path_next;
+
+#else
- if (self.pathcurrent)
- {
++ if (vlen(self.origin - self.pathcurrent.origin) < 64)
++ self.pathcurrent = self.pathcurrent.enemy;
+#endif
+
- self.moveto = self.pathcurrent.origin;
- self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
++ if (self.pathcurrent)
++ {
+
- movelib_move_simple(v_forward, (autocvar_g_turrets_unit_ewheel_speed_fast), 0.4);
- }
++ self.moveto = self.pathcurrent.origin;
++ self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
+
- float newframe;
-
- self.steerto = steerlib_arrive(self.enemy.origin,self.target_range_optimal);
-
- self.moveto = self.origin + self.steerto * 128;
-
- if (self.tur_dist_enemy > self.target_range_optimal)
- {
- if ( self.tur_head.spawnshieldtime < 1 )
- {
- newframe = ewheel_anim_fwd_fast;
- movelib_move_simple(v_forward, (autocvar_g_turrets_unit_ewheel_speed_fast), 0.4);
- }
- else if (self.tur_head.spawnshieldtime < 2)
- {
-
- newframe = ewheel_anim_fwd_slow;
- movelib_move_simple(v_forward, (autocvar_g_turrets_unit_ewheel_speed_slow), 0.4);
- }
- else
- {
- newframe = ewheel_anim_fwd_slow;
- movelib_move_simple(v_forward, (autocvar_g_turrets_unit_ewheel_speed_slower), 0.4);
- }
- }
- else if (self.tur_dist_enemy < self.target_range_optimal * 0.5)
- {
- newframe = ewheel_anim_bck_slow;
- movelib_move_simple(v_forward * -1, (autocvar_g_turrets_unit_ewheel_speed_slow), 0.4);
- }
- else
- {
- newframe = ewheel_anim_stop;
- movelib_beak_simple((autocvar_g_turrets_unit_ewheel_speed_stop));
- }
-
- turrets_setframe(newframe, false);
++ movelib_move_simple(v_forward, (autocvar_g_turrets_unit_ewheel_speed_fast), 0.4);
++ }
+}
+
+void ewheel_move_enemy()
+{
- if(self.frame != 0)
- {
- self.SendFlags |= TNSF_ANIM;
- self.anim_start_time = time;
- }
-
- self.frame = 0;
- if (vlen(self.velocity))
- movelib_beak_simple((autocvar_g_turrets_unit_ewheel_speed_stop));
++ float newframe;
++
++ self.steerto = steerlib_arrive(self.enemy.origin,self.target_range_optimal);
++
++ self.moveto = self.origin + self.steerto * 128;
++
++ if (self.tur_dist_enemy > self.target_range_optimal)
++ {
++ if ( self.tur_head.spawnshieldtime < 1 )
++ {
++ newframe = ewheel_anim_fwd_fast;
++ movelib_move_simple(v_forward, (autocvar_g_turrets_unit_ewheel_speed_fast), 0.4);
++ }
++ else if (self.tur_head.spawnshieldtime < 2)
++ {
++
++ newframe = ewheel_anim_fwd_slow;
++ movelib_move_simple(v_forward, (autocvar_g_turrets_unit_ewheel_speed_slow), 0.4);
++ }
++ else
++ {
++ newframe = ewheel_anim_fwd_slow;
++ movelib_move_simple(v_forward, (autocvar_g_turrets_unit_ewheel_speed_slower), 0.4);
++ }
++ }
++ else if (self.tur_dist_enemy < self.target_range_optimal * 0.5)
++ {
++ newframe = ewheel_anim_bck_slow;
++ movelib_move_simple(v_forward * -1, (autocvar_g_turrets_unit_ewheel_speed_slow), 0.4);
++ }
++ else
++ {
++ newframe = ewheel_anim_stop;
++ movelib_beak_simple((autocvar_g_turrets_unit_ewheel_speed_stop));
++ }
++
++ turrets_setframe(newframe, false);
+}
+
+void ewheel_move_idle()
+{
- switch(req)
- {
- case TR_ATTACK:
- {
- float i;
- entity _mis;
-
- for (i = 0; i < 1; ++i)
- {
- turret_do_updates(self);
-
- _mis = turret_projectile("weapons/lasergun_fire.wav", 1, 0, DEATH_TURRET_EWHEEL, PROJECTILE_BLASTER, TRUE, TRUE);
- _mis.missile_flags = MIF_SPLASH;
-
- pointparticles(particleeffectnum("laser_muzzleflash"), self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
-
- self.tur_head.frame += 2;
-
- if (self.tur_head.frame > 3)
- self.tur_head.frame = 0;
- }
-
- return true;
- }
- case TR_THINK:
- {
- float vz;
- vector wish_angle, real_angle;
-
- vz = self.velocity_z;
-
- self.angles_x = anglemods(self.angles_x);
- self.angles_y = anglemods(self.angles_y);
-
- fixedmakevectors(self.angles);
-
- wish_angle = normalize(self.steerto);
- wish_angle = vectoangles(wish_angle);
- real_angle = wish_angle - self.angles;
- real_angle = shortangle_vxy(real_angle, self.tur_head.angles);
-
- self.tur_head.spawnshieldtime = fabs(real_angle_y);
- real_angle_y = bound(-self.tur_head.aim_speed, real_angle_y, self.tur_head.aim_speed);
- self.angles_y = (self.angles_y + real_angle_y);
-
- if(self.enemy)
- ewheel_move_enemy();
- else if(self.pathcurrent)
- ewheel_move_path();
- else
- ewheel_move_idle();
-
- self.velocity_z = vz;
-
- if(vlen(self.velocity))
- self.SendFlags |= TNSF_MOVE;
-
- return true;
- }
- case TR_DEATH:
- {
- self.velocity = '0 0 0';
++ if(self.frame != 0)
++ {
++ self.SendFlags |= TNSF_ANIM;
++ self.anim_start_time = time;
++ }
++
++ self.frame = 0;
++ if (vlen(self.velocity))
++ movelib_beak_simple((autocvar_g_turrets_unit_ewheel_speed_stop));
+}
+
+void spawnfunc_turret_ewheel() { if(!turret_initialize(TUR_EWHEEL)) remove(self); }
+
+float t_ewheel(float req)
+{
- if (self.pathcurrent)
- pathlib_deletepath(self.pathcurrent.owner);
++ switch(req)
++ {
++ case TR_ATTACK:
++ {
++ float i;
++ entity _mis;
++
++ for (i = 0; i < 1; ++i)
++ {
++ turret_do_updates(self);
++
++ _mis = turret_projectile("weapons/lasergun_fire.wav", 1, 0, DEATH_TURRET_EWHEEL, PROJECTILE_BLASTER, TRUE, TRUE);
++ _mis.missile_flags = MIF_SPLASH;
++
++ Send_Effect("laser_muzzleflash", self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
++
++ self.tur_head.frame += 2;
++
++ if (self.tur_head.frame > 3)
++ self.tur_head.frame = 0;
++ }
++
++ return true;
++ }
++ case TR_THINK:
++ {
++ float vz;
++ vector wish_angle, real_angle;
++
++ vz = self.velocity_z;
++
++ self.angles_x = anglemods(self.angles_x);
++ self.angles_y = anglemods(self.angles_y);
++
++ fixedmakevectors(self.angles);
++
++ wish_angle = normalize(self.steerto);
++ wish_angle = vectoangles(wish_angle);
++ real_angle = wish_angle - self.angles;
++ real_angle = shortangle_vxy(real_angle, self.tur_head.angles);
++
++ self.tur_head.spawnshieldtime = fabs(real_angle_y);
++ real_angle_y = bound(-self.tur_head.aim_speed, real_angle_y, self.tur_head.aim_speed);
++ self.angles_y = (self.angles_y + real_angle_y);
++
++ if(self.enemy)
++ ewheel_move_enemy();
++ else if(self.pathcurrent)
++ ewheel_move_path();
++ else
++ ewheel_move_idle();
++
++ self.velocity_z = vz;
++
++ if(vlen(self.velocity))
++ self.SendFlags |= TNSF_MOVE;
++
++ return true;
++ }
++ case TR_DEATH:
++ {
++ self.velocity = '0 0 0';
+
+#ifdef EWHEEL_FANCYPATH
- self.pathcurrent = world;
-
- return true;
- }
- case TR_SETUP:
- {
- entity e;
-
- if(self.movetype == MOVETYPE_WALK)
- {
- self.velocity = '0 0 0';
- self.enemy = world;
-
- setorigin(self, self.pos1);
-
- if (self.target != "")
- {
- e = find(world, targetname, self.target);
- if (!e)
- {
- dprint("Initital waypoint for ewheel does NOT exsist, fix your map!\n");
- self.target = "";
- }
-
- if (e.classname != "turret_checkpoint")
- dprint("Warning: not a turrret path\n");
- else
- {
++ if (self.pathcurrent)
++ pathlib_deletepath(self.pathcurrent.owner);
+#endif
- self.pathcurrent = WALKER_PATH(self.origin,e.origin);
- self.pathgoal = e;
++ self.pathcurrent = world;
++
++ return true;
++ }
++ case TR_SETUP:
++ {
++ entity e;
++
++ if(self.movetype == MOVETYPE_WALK)
++ {
++ self.velocity = '0 0 0';
++ self.enemy = world;
++
++ setorigin(self, self.pos1);
++
++ if (self.target != "")
++ {
++ e = find(world, targetname, self.target);
++ if (!e)
++ {
++ dprint("Initital waypoint for ewheel does NOT exsist, fix your map!\n");
++ self.target = "";
++ }
++
++ if (e.classname != "turret_checkpoint")
++ dprint("Warning: not a turrret path\n");
++ else
++ {
+
+#ifdef EWHEEL_FANCYPATH
- self.pathcurrent = e;
++ self.pathcurrent = WALKER_PATH(self.origin,e.origin);
++ self.pathgoal = e;
+#else
- }
- }
- }
-
- self.iscreature = true;
- self.teleportable = TELEPORT_NORMAL;
- self.damagedbycontents = true;
- self.movetype = MOVETYPE_WALK;
- self.solid = SOLID_SLIDEBOX;
- self.takedamage = DAMAGE_AIM;
- self.idle_aim = '0 0 0';
- self.pos1 = self.origin;
- self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
- self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
- self.frame = self.tur_head.frame = 1;
- self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
-
- // Convert from dgr / sec to dgr / tic
- self.tur_head.aim_speed = (autocvar_g_turrets_unit_ewheel_turnrate);
- self.tur_head.aim_speed = self.tur_head.aim_speed / (1 / self.ticrate);
-
- return true;
- }
- case TR_PRECACHE:
- {
- precache_model ("models/turrets/ewheel-base2.md3");
- precache_model ("models/turrets/ewheel-gun1.md3");
- return true;
- }
- }
-
- return true;
++ self.pathcurrent = e;
+#endif
- float dt;
++ }
++ }
++ }
++
++ self.iscreature = true;
++ self.teleportable = TELEPORT_NORMAL;
++ self.damagedbycontents = true;
++ self.movetype = MOVETYPE_WALK;
++ self.solid = SOLID_SLIDEBOX;
++ self.takedamage = DAMAGE_AIM;
++ self.idle_aim = '0 0 0';
++ self.pos1 = self.origin;
++ self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
++ self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
++ self.frame = self.tur_head.frame = 1;
++ self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
++
++ // Convert from dgr / sec to dgr / tic
++ self.tur_head.aim_speed = (autocvar_g_turrets_unit_ewheel_turnrate);
++ self.tur_head.aim_speed = self.tur_head.aim_speed / (1 / self.ticrate);
++
++ return true;
++ }
++ case TR_PRECACHE:
++ {
++ precache_model ("models/turrets/ewheel-base2.md3");
++ precache_model ("models/turrets/ewheel-gun1.md3");
++ return true;
++ }
++ }
++
++ return true;
+}
+
+#endif // SVQC
+#ifdef CSQC
+
+void ewheel_draw()
+{
- dt = time - self.move_time;
- self.move_time = time;
- if(dt <= 0)
- return;
++ float dt;
+
- fixedmakevectors(self.angles);
- setorigin(self, self.origin + self.velocity * dt);
- self.tur_head.angles += dt * self.tur_head.move_avelocity;
- self.angles_y = self.move_angles_y;
++ dt = time - self.move_time;
++ self.move_time = time;
++ if(dt <= 0)
++ return;
+
- if (self.health < 127)
- if(random() < 0.05)
- te_spark(self.origin + '0 0 40', randomvec() * 256 + '0 0 256', 16);
++ fixedmakevectors(self.angles);
++ setorigin(self, self.origin + self.velocity * dt);
++ self.tur_head.angles += dt * self.tur_head.move_avelocity;
++ self.angles_y = self.move_angles_y;
+
- switch(req)
- {
- case TR_SETUP:
- {
- self.gravity = 1;
- self.movetype = MOVETYPE_BOUNCE;
- self.move_movetype = MOVETYPE_BOUNCE;
- self.move_origin = self.origin;
- self.move_time = time;
- self.draw = ewheel_draw;
-
- return true;
- }
- case TR_PRECACHE:
- {
- return true;
- }
- }
-
- return true;
++ if (self.health < 127)
++ if(random() < 0.05)
++ te_spark(self.origin + '0 0 40', randomvec() * 256 + '0 0 256', 16);
+}
+
+float t_ewheel(float req)
+{
++ switch(req)
++ {
++ case TR_SETUP:
++ {
++ self.gravity = 1;
++ self.movetype = MOVETYPE_BOUNCE;
++ self.move_movetype = MOVETYPE_BOUNCE;
++ self.move_origin = self.origin;
++ self.move_time = time;
++ self.draw = ewheel_draw;
++
++ return true;
++ }
++ case TR_PRECACHE:
++ {
++ return true;
++ }
++ }
++
++ return true;
+}
+
+#endif // CSQC
+#endif // REGISTER_TURRET
--- /dev/null
- if(self.enemy != world)
- if(vlen(self.origin - self.enemy.origin) < self.owner.shot_radius * 3)
- setorigin(self,self.enemy.origin + randomvec() * self.owner.shot_radius);
+#ifdef REGISTER_TURRET
+REGISTER_TURRET(
+/* TUR_##id */ FLAC,
+/* function */ t_flac,
+/* spawnflags */ TUR_FLAG_SPLASH | TUR_FLAG_FASTPROJ | TUR_FLAG_MISSILE,
+/* mins,maxs */ '-32 -32 0', '32 32 64',
+/* model */ "base.md3",
+/* head_model */ "flac.md3",
+/* netname */ "flac",
+/* fullname */ _("FLAC Cannon")
+);
+#else
+#ifdef SVQC
+void turret_flac_projectile_think_explode()
+{
- float d;
- d = RadiusDamage (self, self.owner, self.owner.shot_dmg, self.owner.shot_dmg, self.owner.shot_radius, self, world, self.owner.shot_force, self.totalfrags, world);
- self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + d;
- self.owner.tur_dbg_dmg_t_f = self.owner.tur_dbg_dmg_t_f + self.owner.shot_dmg;
++ if(self.enemy != world)
++ if(vlen(self.origin - self.enemy.origin) < self.owner.shot_radius * 3)
++ setorigin(self,self.enemy.origin + randomvec() * self.owner.shot_radius);
+
+#ifdef TURRET_DEBUG
- RadiusDamage (self, self.realowner, self.owner.shot_dmg, self.owner.shot_dmg, self.owner.shot_radius, self, world, self.owner.shot_force, self.totalfrags, world);
++ float d;
++ d = RadiusDamage (self, self.owner, self.owner.shot_dmg, self.owner.shot_dmg, self.owner.shot_radius, self, world, self.owner.shot_force, self.totalfrags, world);
++ self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + d;
++ self.owner.tur_dbg_dmg_t_f = self.owner.tur_dbg_dmg_t_f + self.owner.shot_dmg;
+#else
- remove(self);
++ RadiusDamage (self, self.realowner, self.owner.shot_dmg, self.owner.shot_dmg, self.owner.shot_radius, self, world, self.owner.shot_force, self.totalfrags, world);
+#endif
- switch(req)
- {
- case TR_ATTACK:
- {
- entity proj;
++ remove(self);
+}
+
+void spawnfunc_turret_flac() { if(!turret_initialize(TUR_FLAC)) remove(self); }
+
+float t_flac(float req)
+{
- turret_tag_fire_update();
++ switch(req)
++ {
++ case TR_ATTACK:
++ {
++ entity proj;
+
- proj = turret_projectile("weapons/hagar_fire.wav", 5, 0, DEATH_TURRET_FLAC, PROJECTILE_HAGAR, TRUE, TRUE);
- pointparticles(particleeffectnum("laser_muzzleflash"), self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
- proj.think = turret_flac_projectile_think_explode;
- proj.nextthink = time + self.tur_impacttime + (random() * 0.01 - random() * 0.01);
- proj.missile_flags = MIF_SPLASH | MIF_PROXY;
++ turret_tag_fire_update();
+
- self.tur_head.frame = self.tur_head.frame + 1;
- if (self.tur_head.frame >= 4)
- self.tur_head.frame = 0;
-
- return true;
- }
- case TR_THINK:
- {
- return true;
- }
- case TR_DEATH:
- {
- return true;
- }
- case TR_SETUP:
- {
- self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
- self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
- self.damage_flags |= TFL_DMG_HEADSHAKE;
- self.target_select_flags |= TFL_TARGETSELECT_NOTURRETS | TFL_TARGETSELECT_MISSILESONLY;
-
- return true;
- }
- case TR_PRECACHE:
- {
- precache_model ("models/turrets/base.md3");
- precache_model ("models/turrets/flac.md3");
- return true;
- }
- }
++ proj = turret_projectile("weapons/hagar_fire.wav", 5, 0, DEATH_TURRET_FLAC, PROJECTILE_HAGAR, TRUE, TRUE);
++ Send_Effect("laser_muzzleflash", self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
++ proj.think = turret_flac_projectile_think_explode;
++ proj.nextthink = time + self.tur_impacttime + (random() * 0.01 - random() * 0.01);
++ proj.missile_flags = MIF_SPLASH | MIF_PROXY;
+
- return true;
++ self.tur_head.frame = self.tur_head.frame + 1;
++ if (self.tur_head.frame >= 4)
++ self.tur_head.frame = 0;
+
- switch(req)
- {
- case TR_SETUP:
- {
- return true;
- }
- case TR_PRECACHE:
- {
- return true;
- }
- }
++ return true;
++ }
++ case TR_THINK:
++ {
++ return true;
++ }
++ case TR_DEATH:
++ {
++ return true;
++ }
++ case TR_SETUP:
++ {
++ self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
++ self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
++ self.damage_flags |= TFL_DMG_HEADSHAKE;
++ self.target_select_flags |= TFL_TARGETSELECT_NOTURRETS | TFL_TARGETSELECT_MISSILESONLY;
++
++ return true;
++ }
++ case TR_PRECACHE:
++ {
++ precache_model ("models/turrets/base.md3");
++ precache_model ("models/turrets/flac.md3");
++ return true;
++ }
++ }
++
++ return true;
+}
+
+#endif // SVQC
+#ifdef CSQC
+float t_flac(float req)
+{
- return true;
++ switch(req)
++ {
++ case TR_SETUP:
++ {
++ return true;
++ }
++ case TR_PRECACHE:
++ {
++ return true;
++ }
++ }
+
++ return true;
+}
+
+#endif // CSQC
+#endif // REGISTER_TURRET
--- /dev/null
- if (self.attack_finished_single > time)
- return 0;
+#ifdef REGISTER_TURRET
+REGISTER_TURRET(
+/* TUR_##id */ FUSIONREACTOR,
+/* function */ t_fusionreactor,
+/* spawnflags */ TUR_FLAG_SUPPORT | TUR_FLAG_AMMOSOURCE,
+/* mins,maxs */ '-34 -34 0', '34 34 90',
+/* model */ "base.md3",
+/* head_model */ "reactor.md3",
+/* netname */ "fusionreactor",
+/* fullname */ _("Fusion Reactor")
+);
+#else
+#ifdef SVQC
+float turret_fusionreactor_firecheck()
+{
- if (self.enemy.deadflag != DEAD_NO)
- return 0;
++ if (self.attack_finished_single > time)
++ return 0;
+
- if (self.enemy == world)
- return 0;
++ if (self.enemy.deadflag != DEAD_NO)
++ return 0;
+
- if (self.ammo < self.shot_dmg)
- return 0;
++ if (self.enemy == world)
++ return 0;
+
- if (self.enemy.ammo >= self.enemy.ammo_max)
- return 0;
++ if (self.ammo < self.shot_dmg)
++ return 0;
+
- if (vlen(self.enemy.origin - self.origin) > self.target_range)
- return 0;
++ if (self.enemy.ammo >= self.enemy.ammo_max)
++ return 0;
+
- if(self.team != self.enemy.team)
- return 0;
++ if (vlen(self.enemy.origin - self.origin) > self.target_range)
++ return 0;
+
- if(!(self.enemy.ammo_flags & TFL_AMMO_ENERGY))
- return 0;
++ if(self.team != self.enemy.team)
++ return 0;
+
- return 1;
++ if(!(self.enemy.ammo_flags & TFL_AMMO_ENERGY))
++ return 0;
+
- switch(req)
- {
- case TR_ATTACK:
- {
- vector fl_org;
-
- self.enemy.ammo = min(self.enemy.ammo + self.shot_dmg,self.enemy.ammo_max);
- fl_org = 0.5 * (self.enemy.absmin + self.enemy.absmax);
- te_smallflash(fl_org);
-
- return true;
- }
- case TR_THINK:
- {
- self.tur_head.avelocity = '0 250 0' * (self.ammo / self.ammo_max);
-
- return true;
- }
- case TR_DEATH:
- {
- return true;
- }
- case TR_SETUP:
- {
- self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE;
- self.target_select_flags = TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_OWNTEAM | TFL_TARGETSELECT_RANGELIMITS;
- self.firecheck_flags = TFL_FIRECHECK_AMMO_OWN | TFL_FIRECHECK_AMMO_OTHER | TFL_FIRECHECK_DISTANCES | TFL_FIRECHECK_DEAD;
- self.shoot_flags = TFL_SHOOT_HITALLVALID;
- self.aim_flags = TFL_AIM_NO;
- self.track_flags = TFL_TRACK_NO;
-
- self.tur_head.scale = 0.75;
- self.tur_head.avelocity = '0 50 0';
-
- self.turret_firecheckfunc = turret_fusionreactor_firecheck;
-
- return true;
- }
- case TR_PRECACHE:
- {
- precache_model ("models/turrets/base.md3");
- precache_model ("models/turrets/reactor.md3");
- return true;
- }
- }
-
- return true;
++ return 1;
+}
+
+void spawnfunc_turret_fusionreactor() { if(!turret_initialize(TUR_FUSIONREACTOR)) remove(self); }
+
+float t_fusionreactor(float req)
+{
- switch(req)
- {
- case TR_SETUP:
- {
- return true;
- }
- case TR_PRECACHE:
- {
- return true;
- }
- }
-
- return true;
++ switch(req)
++ {
++ case TR_ATTACK:
++ {
++ vector fl_org;
++
++ self.enemy.ammo = min(self.enemy.ammo + self.shot_dmg,self.enemy.ammo_max);
++ fl_org = 0.5 * (self.enemy.absmin + self.enemy.absmax);
++ te_smallflash(fl_org);
++
++ return true;
++ }
++ case TR_THINK:
++ {
++ self.tur_head.avelocity = '0 250 0' * (self.ammo / self.ammo_max);
++
++ return true;
++ }
++ case TR_DEATH:
++ {
++ return true;
++ }
++ case TR_SETUP:
++ {
++ self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE;
++ self.target_select_flags = TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_OWNTEAM | TFL_TARGETSELECT_RANGELIMITS;
++ self.firecheck_flags = TFL_FIRECHECK_AMMO_OWN | TFL_FIRECHECK_AMMO_OTHER | TFL_FIRECHECK_DISTANCES | TFL_FIRECHECK_DEAD;
++ self.shoot_flags = TFL_SHOOT_HITALLVALID;
++ self.aim_flags = TFL_AIM_NO;
++ self.track_flags = TFL_TRACK_NO;
++
++ self.tur_head.scale = 0.75;
++ self.tur_head.avelocity = '0 50 0';
++
++ self.turret_firecheckfunc = turret_fusionreactor_firecheck;
++
++ return true;
++ }
++ case TR_PRECACHE:
++ {
++ precache_model ("models/turrets/base.md3");
++ precache_model ("models/turrets/reactor.md3");
++ return true;
++ }
++ }
++
++ return true;
+}
+
+#endif // SVQC
+#ifdef CSQC
+float t_fusionreactor(float req)
+{
++ switch(req)
++ {
++ case TR_SETUP:
++ {
++ return true;
++ }
++ case TR_PRECACHE:
++ {
++ return true;
++ }
++ }
++
++ return true;
+}
+
+#endif // CSQC
+#endif // REGISTER_TURRET
--- /dev/null
- vector olddir,newdir;
- vector pre_pos;
- float itime;
+#ifdef REGISTER_TURRET
+REGISTER_TURRET(
+/* TUR_##id */ HELLION,
+/* function */ t_hellion,
+/* spawnflags */ TUR_FLAG_SPLASH | TUR_FLAG_FASTPROJ | TUR_FLAG_PLAYER | TUR_FLAG_MISSILE,
+/* mins,maxs */ '-32 -32 0', '32 32 64',
+/* model */ "base.md3",
+/* head_model */ "hellion.md3",
+/* netname */ "hellion",
+/* fullname */ _("Hellion Missile Turret")
+);
+#else
+#ifdef SVQC
+float autocvar_g_turrets_unit_hellion_shot_speed_gain;
+float autocvar_g_turrets_unit_hellion_shot_speed_max;
+
+void turret_hellion_missile_think()
+{
- self.nextthink = time + 0.05;
++ vector olddir,newdir;
++ vector pre_pos;
++ float itime;
+
- olddir = normalize(self.velocity);
++ self.nextthink = time + 0.05;
+
- if(self.max_health < time)
- turret_projectile_explode();
++ olddir = normalize(self.velocity);
+
- // Enemy dead? just keep on the current heading then.
- if ((self.enemy == world) || (self.enemy.deadflag != DEAD_NO))
- {
++ if(self.max_health < time)
++ turret_projectile_explode();
+
- // Make sure we dont return to tracking a respawned player
- self.enemy = world;
++ // Enemy dead? just keep on the current heading then.
++ if ((self.enemy == world) || (self.enemy.deadflag != DEAD_NO))
++ {
+
- // Turn model
- self.angles = vectoangles(self.velocity);
++ // Make sure we dont return to tracking a respawned player
++ self.enemy = world;
+
- if ( (vlen(self.origin - self.owner.origin)) > (self.owner.shot_radius * 5) )
- turret_projectile_explode();
++ // Turn model
++ self.angles = vectoangles(self.velocity);
+
- // Accelerate
- self.velocity = olddir * min(vlen(self.velocity) * (autocvar_g_turrets_unit_hellion_shot_speed_gain), (autocvar_g_turrets_unit_hellion_shot_speed_max));
++ if ( (vlen(self.origin - self.owner.origin)) > (self.owner.shot_radius * 5) )
++ turret_projectile_explode();
+
- UpdateCSQCProjectile(self);
++ // Accelerate
++ self.velocity = olddir * min(vlen(self.velocity) * (autocvar_g_turrets_unit_hellion_shot_speed_gain), (autocvar_g_turrets_unit_hellion_shot_speed_max));
+
- return;
- }
++ UpdateCSQCProjectile(self);
+
- // Enemy in range?
- if (vlen(self.origin - self.enemy.origin) < self.owner.shot_radius * 0.2)
- turret_projectile_explode();
++ return;
++ }
+
- // Predict enemy position
- itime = vlen(self.enemy.origin - self.origin) / vlen(self.velocity);
- pre_pos = self.enemy.origin + self.enemy.velocity * itime;
++ // Enemy in range?
++ if (vlen(self.origin - self.enemy.origin) < self.owner.shot_radius * 0.2)
++ turret_projectile_explode();
+
- pre_pos = (pre_pos + self.enemy.origin) * 0.5;
++ // Predict enemy position
++ itime = vlen(self.enemy.origin - self.origin) / vlen(self.velocity);
++ pre_pos = self.enemy.origin + self.enemy.velocity * itime;
+
- // Find out the direction to that place
- newdir = normalize(pre_pos - self.origin);
++ pre_pos = (pre_pos + self.enemy.origin) * 0.5;
+
- // Turn
- newdir = normalize(olddir + newdir * 0.35);
++ // Find out the direction to that place
++ newdir = normalize(pre_pos - self.origin);
+
- // Turn model
- self.angles = vectoangles(self.velocity);
++ // Turn
++ newdir = normalize(olddir + newdir * 0.35);
+
- // Accelerate
- self.velocity = newdir * min(vlen(self.velocity) * (autocvar_g_turrets_unit_hellion_shot_speed_gain), (autocvar_g_turrets_unit_hellion_shot_speed_max));
++ // Turn model
++ self.angles = vectoangles(self.velocity);
+
- if (itime < 0.05)
- self.think = turret_projectile_explode;
++ // Accelerate
++ self.velocity = newdir * min(vlen(self.velocity) * (autocvar_g_turrets_unit_hellion_shot_speed_gain), (autocvar_g_turrets_unit_hellion_shot_speed_max));
+
- UpdateCSQCProjectile(self);
++ if (itime < 0.05)
++ self.think = turret_projectile_explode;
+
- switch(req)
- {
- case TR_ATTACK:
- {
- entity missile;
-
- if(self.tur_head.frame != 0)
- self.tur_shotorg = gettaginfo(self.tur_head, gettagindex(self.tur_head, "tag_fire"));
- else
- self.tur_shotorg = gettaginfo(self.tur_head, gettagindex(self.tur_head, "tag_fire2"));
-
- missile = turret_projectile("weapons/rocket_fire.wav", 6, 10, DEATH_TURRET_HELLION, PROJECTILE_ROCKET, FALSE, FALSE);
- te_explosion (missile.origin);
- missile.think = turret_hellion_missile_think;
- missile.nextthink = time;
- missile.flags = FL_PROJECTILE;
- missile.max_health = time + 9;
- missile.tur_aimpos = randomvec() * 128;
- missile.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_GUIDED_HEAT;
- self.tur_head.frame += 1;
-
- return true;
- }
- case TR_THINK:
- {
- if (self.tur_head.frame != 0)
- self.tur_head.frame += 1;
-
- if (self.tur_head.frame >= 7)
- self.tur_head.frame = 0;
-
- return true;
- }
- case TR_DEATH:
- {
- return true;
- }
- case TR_SETUP:
- {
- self.aim_flags = TFL_AIM_SIMPLE;
- self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK ;
- self.firecheck_flags = TFL_FIRECHECK_DEAD | TFL_FIRECHECK_DISTANCES | TFL_FIRECHECK_TEAMCHECK | TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AFF | TFL_FIRECHECK_AMMO_OWN;
- self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
-
- return true;
- }
- case TR_PRECACHE:
- {
- precache_model ("models/turrets/base.md3");
- precache_model ("models/turrets/hellion.md3");
- return true;
- }
- }
-
- return true;
++ UpdateCSQCProjectile(self);
+}
+
+void spawnfunc_turret_hellion() { if(!turret_initialize(TUR_HELLION)) remove(self); }
+
+float t_hellion(float req)
+{
- switch(req)
- {
- case TR_SETUP:
- {
- return true;
- }
- case TR_PRECACHE:
- {
- return true;
- }
- }
-
- return true;
++ switch(req)
++ {
++ case TR_ATTACK:
++ {
++ entity missile;
++
++ if(self.tur_head.frame != 0)
++ self.tur_shotorg = gettaginfo(self.tur_head, gettagindex(self.tur_head, "tag_fire"));
++ else
++ self.tur_shotorg = gettaginfo(self.tur_head, gettagindex(self.tur_head, "tag_fire2"));
++
++ missile = turret_projectile("weapons/rocket_fire.wav", 6, 10, DEATH_TURRET_HELLION, PROJECTILE_ROCKET, FALSE, FALSE);
++ te_explosion (missile.origin);
++ missile.think = turret_hellion_missile_think;
++ missile.nextthink = time;
++ missile.flags = FL_PROJECTILE;
++ missile.max_health = time + 9;
++ missile.tur_aimpos = randomvec() * 128;
++ missile.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_GUIDED_HEAT;
++ self.tur_head.frame += 1;
++
++ return true;
++ }
++ case TR_THINK:
++ {
++ if (self.tur_head.frame != 0)
++ self.tur_head.frame += 1;
++
++ if (self.tur_head.frame >= 7)
++ self.tur_head.frame = 0;
++
++ return true;
++ }
++ case TR_DEATH:
++ {
++ return true;
++ }
++ case TR_SETUP:
++ {
++ self.aim_flags = TFL_AIM_SIMPLE;
++ self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK ;
++ self.firecheck_flags = TFL_FIRECHECK_DEAD | TFL_FIRECHECK_DISTANCES | TFL_FIRECHECK_TEAMCHECK | TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AFF | TFL_FIRECHECK_AMMO_OWN;
++ self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
++
++ return true;
++ }
++ case TR_PRECACHE:
++ {
++ precache_model ("models/turrets/base.md3");
++ precache_model ("models/turrets/hellion.md3");
++ return true;
++ }
++ }
++
++ return true;
+}
+
+#endif // SVQC
+#ifdef CSQC
+float t_hellion(float req)
+{
++ switch(req)
++ {
++ case TR_SETUP:
++ {
++ return true;
++ }
++ case TR_PRECACHE:
++ {
++ return true;
++ }
++ }
++
++ return true;
+}
+
+#endif // CSQC
+#endif // REGISTER_TURRET
--- /dev/null
- if (e_target == world)
- return 0;
+#ifdef REGISTER_TURRET
+REGISTER_TURRET(
+/* TUR_##id */ HK,
+/* function */ t_hk,
+/* spawnflags */ TUR_FLAG_SPLASH | TUR_FLAG_MEDPROJ | TUR_FLAG_PLAYER | TUR_FLAG_RECIEVETARGETS,
+/* mins,maxs */ '-32 -32 0', '32 32 64',
+/* model */ "base.md3",
+/* head_model */ "hk.md3",
+/* netname */ "hk",
+/* fullname */ _("Hunter-Killer Turret")
+);
+#else
+#ifdef SVQC
+float autocvar_g_turrets_unit_hk_shot_speed;
+float autocvar_g_turrets_unit_hk_shot_speed_accel;
+float autocvar_g_turrets_unit_hk_shot_speed_accel2;
+float autocvar_g_turrets_unit_hk_shot_speed_decel;
+float autocvar_g_turrets_unit_hk_shot_speed_max;
+float autocvar_g_turrets_unit_hk_shot_speed_turnrate;
+
+//#define TURRET_DEBUG_HK
+
+#ifdef TURRET_DEBUG_HK
+.float atime;
+#endif
+
+float hk_is_valid_target(entity e_target)
+{
- // If only this was used more..
- if (e_target.flags & FL_NOTARGET)
- return 0;
++ if (e_target == world)
++ return 0;
+
- // Cant touch this
- if ((e_target.takedamage == DAMAGE_NO) || (e_target.health < 0))
- return 0;
++ // If only this was used more..
++ if (e_target.flags & FL_NOTARGET)
++ return 0;
+
- // player
- if (IS_CLIENT(e_target))
- {
- if (self.owner.target_select_playerbias < 0)
- return 0;
++ // Cant touch this
++ if ((e_target.takedamage == DAMAGE_NO) || (e_target.health < 0))
++ return 0;
+
- if (e_target.deadflag != DEAD_NO)
- return 0;
- }
++ // player
++ if (IS_CLIENT(e_target))
++ {
++ if (self.owner.target_select_playerbias < 0)
++ return 0;
+
- // Missile
- if ((e_target.flags & FL_PROJECTILE) && (self.owner.target_select_missilebias < 0))
- return 0;
++ if (e_target.deadflag != DEAD_NO)
++ return 0;
++ }
+
- // Team check
- if ((e_target.team == self.owner.team) || (self.owner.team == e_target.owner.team))
- return 0;
++ // Missile
++ if ((e_target.flags & FL_PROJECTILE) && (self.owner.target_select_missilebias < 0))
++ return 0;
+
- return 1;
++ // Team check
++ if ((e_target.team == self.owner.team) || (self.owner.team == e_target.owner.team))
++ return 0;
+
- vector vu, vd, vf, vl, vr, ve; // Vector (direction)
- float fu, fd, ff, fl, fr, fe; // Fraction to solid
- vector olddir,wishdir,newdir; // Final direction
- float lt_for; // Length of Trace FORwrad
- float lt_seek; // Length of Trace SEEK (left, right, up down)
- float pt_seek; // Pitch of Trace SEEK (How mutch to angele left, right up, down trace towards v_forward)
- vector pre_pos;
- float myspeed;
- entity e;
- float ad,edist;
-
- self.nextthink = time + self.ticrate;
-
- //if (self.cnt < time)
- // turret_hk_missile_explode();
-
- if (self.enemy.deadflag != DEAD_NO)
- self.enemy = world;
-
- // Pick the closest valid target.
- if (!self.enemy)
- {
- e = findradius(self.origin, 5000);
- while (e)
- {
- if (hk_is_valid_target(e))
- {
- if (!self.enemy)
- self.enemy = e;
- else
- if (vlen(self.origin - e.origin) < vlen(self.origin - self.enemy.origin))
- self.enemy = e;
- }
- e = e.chain;
- }
- }
-
- self.angles = vectoangles(self.velocity);
- self.angles_x = self.angles_x * -1;
- makevectors(self.angles);
- self.angles_x = self.angles_x * -1;
-
- if (self.enemy)
- {
- edist = vlen(self.origin - self.enemy.origin);
- // Close enougth to do decent damage?
- if ( edist <= (self.owner.shot_radius * 0.25) )
- {
- turret_projectile_explode();
- return;
- }
-
- // Get data on enemy position
- pre_pos = self.enemy.origin +
- self.enemy.velocity *
- min((vlen(self.enemy.origin - self.origin) / vlen(self.velocity)),0.5);
-
- traceline(self.origin, pre_pos,true,self.enemy);
- ve = normalize(pre_pos - self.origin);
- fe = trace_fraction;
-
- }
- else
- {
- edist = 0;
- ve = '0 0 0';
- fe = 0;
- }
-
- if ((fe != 1) || (self.enemy == world) || (edist > 1000))
- {
- myspeed = vlen(self.velocity);
-
- lt_for = myspeed * 3;
- lt_seek = myspeed * 2.95;
-
- // Trace forward
- traceline(self.origin, self.origin + v_forward * lt_for,false,self);
- vf = trace_endpos;
- ff = trace_fraction;
-
- // Find angular offset
- ad = vlen(vectoangles(normalize(self.enemy.origin - self.origin)) - self.angles);
-
- // To close to something, Slow down!
- if ( ((ff < 0.7) || (ad > 4)) && (myspeed > (autocvar_g_turrets_unit_hk_shot_speed)) )
- myspeed = max(myspeed * (autocvar_g_turrets_unit_hk_shot_speed_decel), (autocvar_g_turrets_unit_hk_shot_speed));
-
- // Failry clear, accelerate.
- if ( (ff > 0.7) && (myspeed < (autocvar_g_turrets_unit_hk_shot_speed_max)) )
- myspeed = min(myspeed * (autocvar_g_turrets_unit_hk_shot_speed_accel), (autocvar_g_turrets_unit_hk_shot_speed_max));
-
- // Setup trace pitch
- pt_seek = 1 - ff;
- pt_seek = bound(0.15,pt_seek,0.8);
- if (ff < 0.5) pt_seek = 1;
-
- // Trace left
- traceline(self.origin, self.origin + (-1 * (v_right * pt_seek) + (v_forward * ff)) * lt_seek,false,self);
- vl = trace_endpos;
- fl = trace_fraction;
-
- // Trace right
- traceline(self.origin, self.origin + ((v_right * pt_seek) + (v_forward * ff)) * lt_seek ,false,self);
- vr = trace_endpos;
- fr = trace_fraction;
-
- // Trace up
- traceline(self.origin, self.origin + ((v_up * pt_seek) + (v_forward * ff)) * lt_seek ,false,self);
- vu = trace_endpos;
- fu = trace_fraction;
-
- // Trace down
- traceline(self.origin, self.origin + (-1 * (v_up * pt_seek) + (v_forward * ff)) * lt_seek ,false,self);
- vd = trace_endpos;
- fd = trace_fraction;
-
- vl = normalize(vl - self.origin);
- vr = normalize(vr - self.origin);
- vu = normalize(vu - self.origin);
- vd = normalize(vd - self.origin);
-
- // Panic tresh passed, find a single direction and turn as hard as we can
- if (pt_seek == 1)
- {
- wishdir = v_right;
- if (fl > fr) wishdir = -1 * v_right;
- if (fu > fl) wishdir = v_up;
- if (fd > fu) wishdir = -1 * v_up;
- }
- else
- {
- // Normalize our trace vectors to make a smooth path
- wishdir = normalize( (vl * fl) + (vr * fr) + (vu * fu) + (vd * fd) );
- }
-
- if (self.enemy)
- {
- if (fe < 0.1) fe = 0.1; // Make sure we always try to move sligtly towards our target
- wishdir = (wishdir * (1 - fe)) + (ve * fe);
- }
- }
- else
- {
- // Got a clear path to target, speed up fast (if not at full speed) and go straight for it.
- myspeed = vlen(self.velocity);
- if (myspeed < (autocvar_g_turrets_unit_hk_shot_speed_max))
- myspeed = min(myspeed * (autocvar_g_turrets_unit_hk_shot_speed_accel2),(autocvar_g_turrets_unit_hk_shot_speed_max));
-
- wishdir = ve;
- }
-
- if ((myspeed > (autocvar_g_turrets_unit_hk_shot_speed)) && (self.cnt > time))
- myspeed = min(myspeed * (autocvar_g_turrets_unit_hk_shot_speed_accel2),(autocvar_g_turrets_unit_hk_shot_speed_max));
-
- // Ranoutagazfish?
- if (self.cnt < time)
- {
- self.cnt = time + 0.25;
- self.nextthink = 0;
- self.movetype = MOVETYPE_BOUNCE;
- return;
- }
-
- // Calculate new heading
- olddir = normalize(self.velocity);
- newdir = normalize(olddir + wishdir * (autocvar_g_turrets_unit_hk_shot_speed_turnrate));
-
- // Set heading & speed
- self.velocity = newdir * myspeed;
-
- // Align model with new heading
- self.angles = vectoangles(self.velocity);
++ return 1;
+}
+
+void turret_hk_missile_think()
+{
- //if(self.atime < time) {
- if ((fe <= 0.99)||(edist > 1000))
- {
- te_lightning2(world,self.origin, self.origin + vr * lt_seek);
- te_lightning2(world,self.origin, self.origin + vl * lt_seek);
- te_lightning2(world,self.origin, self.origin + vu * lt_seek);
- te_lightning2(world,self.origin, self.origin + vd * lt_seek);
- te_lightning2(world,self.origin, vf);
- }
- else
- {
- te_lightning2(world,self.origin, self.enemy.origin);
- }
- bprint("Speed: ", ftos(rint(myspeed)), "\n");
- bprint("Trace to solid: ", ftos(rint(ff * 100)), "%\n");
- bprint("Trace to target:", ftos(rint(fe * 100)), "%\n");
- self.atime = time + 0.2;
- //}
++ vector vu, vd, vf, vl, vr, ve; // Vector (direction)
++ float fu, fd, ff, fl, fr, fe; // Fraction to solid
++ vector olddir,wishdir,newdir; // Final direction
++ float lt_for; // Length of Trace FORwrad
++ float lt_seek; // Length of Trace SEEK (left, right, up down)
++ float pt_seek; // Pitch of Trace SEEK (How mutch to angele left, right up, down trace towards v_forward)
++ vector pre_pos;
++ float myspeed;
++ entity e;
++ float ad,edist;
++
++ self.nextthink = time + self.ticrate;
++
++ //if (self.cnt < time)
++ // turret_hk_missile_explode();
++
++ if (self.enemy.deadflag != DEAD_NO)
++ self.enemy = world;
++
++ // Pick the closest valid target.
++ if (!self.enemy)
++ {
++ e = findradius(self.origin, 5000);
++ while (e)
++ {
++ if (hk_is_valid_target(e))
++ {
++ if (!self.enemy)
++ self.enemy = e;
++ else
++ if (vlen(self.origin - e.origin) < vlen(self.origin - self.enemy.origin))
++ self.enemy = e;
++ }
++ e = e.chain;
++ }
++ }
++
++ self.angles = vectoangles(self.velocity);
++ self.angles_x = self.angles_x * -1;
++ makevectors(self.angles);
++ self.angles_x = self.angles_x * -1;
++
++ if (self.enemy)
++ {
++ edist = vlen(self.origin - self.enemy.origin);
++ // Close enougth to do decent damage?
++ if ( edist <= (self.owner.shot_radius * 0.25) )
++ {
++ turret_projectile_explode();
++ return;
++ }
++
++ // Get data on enemy position
++ pre_pos = self.enemy.origin +
++ self.enemy.velocity *
++ min((vlen(self.enemy.origin - self.origin) / vlen(self.velocity)),0.5);
++
++ traceline(self.origin, pre_pos,true,self.enemy);
++ ve = normalize(pre_pos - self.origin);
++ fe = trace_fraction;
++
++ }
++ else
++ {
++ edist = 0;
++ ve = '0 0 0';
++ fe = 0;
++ }
++
++ if ((fe != 1) || (self.enemy == world) || (edist > 1000))
++ {
++ myspeed = vlen(self.velocity);
++
++ lt_for = myspeed * 3;
++ lt_seek = myspeed * 2.95;
++
++ // Trace forward
++ traceline(self.origin, self.origin + v_forward * lt_for,false,self);
++ vf = trace_endpos;
++ ff = trace_fraction;
++
++ // Find angular offset
++ ad = vlen(vectoangles(normalize(self.enemy.origin - self.origin)) - self.angles);
++
++ // To close to something, Slow down!
++ if ( ((ff < 0.7) || (ad > 4)) && (myspeed > (autocvar_g_turrets_unit_hk_shot_speed)) )
++ myspeed = max(myspeed * (autocvar_g_turrets_unit_hk_shot_speed_decel), (autocvar_g_turrets_unit_hk_shot_speed));
++
++ // Failry clear, accelerate.
++ if ( (ff > 0.7) && (myspeed < (autocvar_g_turrets_unit_hk_shot_speed_max)) )
++ myspeed = min(myspeed * (autocvar_g_turrets_unit_hk_shot_speed_accel), (autocvar_g_turrets_unit_hk_shot_speed_max));
++
++ // Setup trace pitch
++ pt_seek = 1 - ff;
++ pt_seek = bound(0.15,pt_seek,0.8);
++ if (ff < 0.5) pt_seek = 1;
++
++ // Trace left
++ traceline(self.origin, self.origin + (-1 * (v_right * pt_seek) + (v_forward * ff)) * lt_seek,false,self);
++ vl = trace_endpos;
++ fl = trace_fraction;
++
++ // Trace right
++ traceline(self.origin, self.origin + ((v_right * pt_seek) + (v_forward * ff)) * lt_seek ,false,self);
++ vr = trace_endpos;
++ fr = trace_fraction;
++
++ // Trace up
++ traceline(self.origin, self.origin + ((v_up * pt_seek) + (v_forward * ff)) * lt_seek ,false,self);
++ vu = trace_endpos;
++ fu = trace_fraction;
++
++ // Trace down
++ traceline(self.origin, self.origin + (-1 * (v_up * pt_seek) + (v_forward * ff)) * lt_seek ,false,self);
++ vd = trace_endpos;
++ fd = trace_fraction;
++
++ vl = normalize(vl - self.origin);
++ vr = normalize(vr - self.origin);
++ vu = normalize(vu - self.origin);
++ vd = normalize(vd - self.origin);
++
++ // Panic tresh passed, find a single direction and turn as hard as we can
++ if (pt_seek == 1)
++ {
++ wishdir = v_right;
++ if (fl > fr) wishdir = -1 * v_right;
++ if (fu > fl) wishdir = v_up;
++ if (fd > fu) wishdir = -1 * v_up;
++ }
++ else
++ {
++ // Normalize our trace vectors to make a smooth path
++ wishdir = normalize( (vl * fl) + (vr * fr) + (vu * fu) + (vd * fd) );
++ }
++
++ if (self.enemy)
++ {
++ if (fe < 0.1) fe = 0.1; // Make sure we always try to move sligtly towards our target
++ wishdir = (wishdir * (1 - fe)) + (ve * fe);
++ }
++ }
++ else
++ {
++ // Got a clear path to target, speed up fast (if not at full speed) and go straight for it.
++ myspeed = vlen(self.velocity);
++ if (myspeed < (autocvar_g_turrets_unit_hk_shot_speed_max))
++ myspeed = min(myspeed * (autocvar_g_turrets_unit_hk_shot_speed_accel2),(autocvar_g_turrets_unit_hk_shot_speed_max));
++
++ wishdir = ve;
++ }
++
++ if ((myspeed > (autocvar_g_turrets_unit_hk_shot_speed)) && (self.cnt > time))
++ myspeed = min(myspeed * (autocvar_g_turrets_unit_hk_shot_speed_accel2),(autocvar_g_turrets_unit_hk_shot_speed_max));
++
++ // Ranoutagazfish?
++ if (self.cnt < time)
++ {
++ self.cnt = time + 0.25;
++ self.nextthink = 0;
++ self.movetype = MOVETYPE_BOUNCE;
++ return;
++ }
++
++ // Calculate new heading
++ olddir = normalize(self.velocity);
++ newdir = normalize(olddir + wishdir * (autocvar_g_turrets_unit_hk_shot_speed_turnrate));
++
++ // Set heading & speed
++ self.velocity = newdir * myspeed;
++
++ // Align model with new heading
++ self.angles = vectoangles(self.velocity);
+
+
+#ifdef TURRET_DEBUG_HK
- UpdateCSQCProjectile(self);
++ //if(self.atime < time) {
++ if ((fe <= 0.99)||(edist > 1000))
++ {
++ te_lightning2(world,self.origin, self.origin + vr * lt_seek);
++ te_lightning2(world,self.origin, self.origin + vl * lt_seek);
++ te_lightning2(world,self.origin, self.origin + vu * lt_seek);
++ te_lightning2(world,self.origin, self.origin + vd * lt_seek);
++ te_lightning2(world,self.origin, vf);
++ }
++ else
++ {
++ te_lightning2(world,self.origin, self.enemy.origin);
++ }
++ bprint("Speed: ", ftos(rint(myspeed)), "\n");
++ bprint("Trace to solid: ", ftos(rint(ff * 100)), "%\n");
++ bprint("Trace to target:", ftos(rint(fe * 100)), "%\n");
++ self.atime = time + 0.2;
++ //}
+#endif
+
- if (e_target)
- {
- if (turret_validate_target(self,e_target,self.target_validate_flags) > 0)
- {
- self.enemy = e_target;
- return 1;
- }
- }
-
- return 0;
++ UpdateCSQCProjectile(self);
+}
+
+float turret_hk_addtarget(entity e_target,entity e_sender)
+{
- switch(req)
- {
- case TR_ATTACK:
- {
- entity missile;
-
- missile = turret_projectile("weapons/rocket_fire.wav", 6, 10, DEATH_TURRET_HK, PROJECTILE_ROCKET, FALSE, FALSE);
- te_explosion (missile.origin);
-
- missile.think = turret_hk_missile_think;
- missile.nextthink = time + 0.25;
- missile.movetype = MOVETYPE_BOUNCEMISSILE;
- missile.velocity = self.tur_shotdir_updated * (self.shot_speed * 0.75);
- missile.angles = vectoangles(missile.velocity);
- missile.cnt = time + 30;
- missile.ticrate = max(autocvar_sys_ticrate, 0.05);
- missile.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_GUIDED_AI;
-
- if (self.tur_head.frame == 0)
- self.tur_head.frame = self.tur_head.frame + 1;
-
- return true;
- }
- case TR_THINK:
- {
- if (self.tur_head.frame != 0)
- self.tur_head.frame = self.tur_head.frame + 1;
-
- if (self.tur_head.frame > 5)
- self.tur_head.frame = 0;
-
- return true;
- }
- case TR_DEATH:
- {
- return true;
- }
- case TR_SETUP:
- {
- self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
- self.aim_flags = TFL_AIM_SIMPLE;
- self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_TRIGGERTARGET | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
- self.firecheck_flags = TFL_FIRECHECK_DEAD | TFL_FIRECHECK_TEAMCHECK | TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AFF;
- self.shoot_flags = TFL_SHOOT_CLEARTARGET;
- self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_TEAMCHECK;
-
- self.turret_addtarget = turret_hk_addtarget;
-
- return true;
- }
- case TR_PRECACHE:
- {
- precache_model ("models/turrets/base.md3");
- precache_model ("models/turrets/hk.md3");
- return true;
- }
- }
-
- return true;
++ if (e_target)
++ {
++ if (turret_validate_target(self,e_target,self.target_validate_flags) > 0)
++ {
++ self.enemy = e_target;
++ return 1;
++ }
++ }
++
++ return 0;
+}
+
+void spawnfunc_turret_hk() { if(!turret_initialize(TUR_HK)) remove(self); }
+
+float t_hk(float req)
+{
- switch(req)
- {
- case TR_SETUP:
- {
- return true;
- }
- case TR_PRECACHE:
- {
- return true;
- }
- }
-
- return true;
++ switch(req)
++ {
++ case TR_ATTACK:
++ {
++ entity missile;
++
++ missile = turret_projectile("weapons/rocket_fire.wav", 6, 10, DEATH_TURRET_HK, PROJECTILE_ROCKET, FALSE, FALSE);
++ te_explosion (missile.origin);
++
++ missile.think = turret_hk_missile_think;
++ missile.nextthink = time + 0.25;
++ missile.movetype = MOVETYPE_BOUNCEMISSILE;
++ missile.velocity = self.tur_shotdir_updated * (self.shot_speed * 0.75);
++ missile.angles = vectoangles(missile.velocity);
++ missile.cnt = time + 30;
++ missile.ticrate = max(autocvar_sys_ticrate, 0.05);
++ missile.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_GUIDED_AI;
++
++ if (self.tur_head.frame == 0)
++ self.tur_head.frame = self.tur_head.frame + 1;
++
++ return true;
++ }
++ case TR_THINK:
++ {
++ if (self.tur_head.frame != 0)
++ self.tur_head.frame = self.tur_head.frame + 1;
++
++ if (self.tur_head.frame > 5)
++ self.tur_head.frame = 0;
++
++ return true;
++ }
++ case TR_DEATH:
++ {
++ return true;
++ }
++ case TR_SETUP:
++ {
++ self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
++ self.aim_flags = TFL_AIM_SIMPLE;
++ self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_TRIGGERTARGET | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
++ self.firecheck_flags = TFL_FIRECHECK_DEAD | TFL_FIRECHECK_TEAMCHECK | TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AFF;
++ self.shoot_flags = TFL_SHOOT_CLEARTARGET;
++ self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_TEAMCHECK;
++
++ self.turret_addtarget = turret_hk_addtarget;
++
++ return true;
++ }
++ case TR_PRECACHE:
++ {
++ precache_model ("models/turrets/base.md3");
++ precache_model ("models/turrets/hk.md3");
++ return true;
++ }
++ }
++
++ return true;
+}
+
+#endif // SVQC
+#ifdef CSQC
+float t_hk(float req)
+{
++ switch(req)
++ {
++ case TR_SETUP:
++ {
++ return true;
++ }
++ case TR_PRECACHE:
++ {
++ return true;
++ }
++ }
++
++ return true;
+}
+
+#endif // CSQC
+#endif // REGISTER_TURRET
--- /dev/null
- switch(req)
- {
- case TR_ATTACK:
- {
- fireBullet (self.tur_shotorg, self.tur_shotdir_updated, self.shot_spread, 0, self.shot_dmg, self.shot_force, DEATH_TURRET_MACHINEGUN, 0);
+#ifdef REGISTER_TURRET
+REGISTER_TURRET(
+/* TUR_##id */ MACHINEGUN,
+/* function */ t_machinegun,
+/* spawnflags */ TUR_FLAG_PLAYER,
+/* mins,maxs */ '-32 -32 0', '32 32 64',
+/* model */ "base.md3",
+/* head_model */ "machinegun.md3",
+/* netname */ "machinegun",
+/* fullname */ _("Machinegun Turret")
+);
+#else
+#ifdef SVQC
+void spawnfunc_turret_machinegun() { if(!turret_initialize(TUR_MACHINEGUN)) remove(self); }
+
++void W_MachineGun_MuzzleFlash(void);
++
+float t_machinegun(float req)
+{
- W_MachineGun_MuzzleFlash();
- setattachment(self.muzzle_flash, self.tur_head, "tag_fire");
++ switch(req)
++ {
++ case TR_ATTACK:
++ {
++ fireBullet (self.tur_shotorg, self.tur_shotdir_updated, self.shot_spread, 0, self.shot_dmg, self.shot_force, DEATH_TURRET_MACHINEGUN, 0);
+
- return true;
- }
- case TR_THINK:
- {
- return true;
- }
- case TR_DEATH:
- {
- return true;
- }
- case TR_SETUP:
- {
- self.damage_flags |= TFL_DMG_HEADSHAKE;
- self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
- self.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
- self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
- self.turret_flags |= TUR_FLAG_HITSCAN;
++ W_MachineGun_MuzzleFlash();
++ setattachment(self.muzzle_flash, self.tur_head, "tag_fire");
+
- return true;
- }
- case TR_PRECACHE:
- {
- precache_model ("models/turrets/base.md3");
- precache_model ("models/turrets/machinegun.md3");
- precache_sound ("weapons/uzi_fire.wav");
- return true;
- }
- }
++ return true;
++ }
++ case TR_THINK:
++ {
++ return true;
++ }
++ case TR_DEATH:
++ {
++ return true;
++ }
++ case TR_SETUP:
++ {
++ self.damage_flags |= TFL_DMG_HEADSHAKE;
++ self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
++ self.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
++ self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
++ self.turret_flags |= TUR_FLAG_HITSCAN;
+
- return true;
++ return true;
++ }
++ case TR_PRECACHE:
++ {
++ precache_model ("models/turrets/base.md3");
++ precache_model ("models/turrets/machinegun.md3");
++ precache_sound ("weapons/uzi_fire.wav");
++ return true;
++ }
++ }
+
- switch(req)
- {
- case TR_SETUP:
- {
- return true;
- }
- case TR_PRECACHE:
- {
- return true;
- }
- }
++ return true;
+}
+
+#endif // SVQC
+#ifdef CSQC
+float t_machinegun(float req)
+{
- return true;
++ switch(req)
++ {
++ case TR_SETUP:
++ {
++ return true;
++ }
++ case TR_PRECACHE:
++ {
++ return true;
++ }
++ }
+
++ return true;
+}
+
+#endif // CSQC
+#endif // REGISTER_TURRET
--- /dev/null
- switch(req)
- {
- case TR_ATTACK:
- {
- entity missile;
+#ifdef REGISTER_TURRET
+REGISTER_TURRET(
+/* TUR_##id */ MLRS,
+/* function */ t_mlrs,
+/* spawnflags */ TUR_FLAG_SPLASH | TUR_FLAG_MEDPROJ | TUR_FLAG_PLAYER,
+/* mins,maxs */ '-32 -32 0', '32 32 64',
+/* model */ "base.md3",
+/* head_model */ "mlrs.md3",
+/* netname */ "mlrs",
+/* fullname */ _("MLRS Turret")
+);
+#else
+#ifdef SVQC
+void spawnfunc_turret_mlrs() { if(!turret_initialize(TUR_MLRS)) remove(self); }
+
+float t_mlrs(float req)
+{
- turret_tag_fire_update();
- missile = turret_projectile("weapons/rocket_fire.wav", 6, 10, DEATH_TURRET_MLRS, PROJECTILE_ROCKET, TRUE, TRUE);
- missile.nextthink = time + max(self.tur_impacttime,(self.shot_radius * 2) / self.shot_speed);
- missile.missile_flags = MIF_SPLASH;
- te_explosion (missile.origin);
++ switch(req)
++ {
++ case TR_ATTACK:
++ {
++ entity missile;
+
- return true;
- }
- case TR_THINK:
- {
- // 0 = full, 6 = empty
- self.tur_head.frame = bound(0, 6 - floor(0.1 + self.ammo / self.shot_dmg), 6);
- if(self.tur_head.frame < 0)
- {
- dprint("ammo:",ftos(self.ammo),"\n");
- dprint("shot_dmg:",ftos(self.shot_dmg),"\n");
- }
-
- return true;
- }
- case TR_DEATH:
- {
- return true;
- }
- case TR_SETUP:
- {
- self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
- self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
-
- self.damage_flags |= TFL_DMG_HEADSHAKE;
- self.shoot_flags |= TFL_SHOOT_VOLLYALWAYS;
- self.volly_counter = self.shot_volly;
++ turret_tag_fire_update();
++ missile = turret_projectile("weapons/rocket_fire.wav", 6, 10, DEATH_TURRET_MLRS, PROJECTILE_ROCKET, TRUE, TRUE);
++ missile.nextthink = time + max(self.tur_impacttime,(self.shot_radius * 2) / self.shot_speed);
++ missile.missile_flags = MIF_SPLASH;
++ te_explosion (missile.origin);
+
- return true;
- }
- case TR_PRECACHE:
- {
- precache_model ("models/turrets/base.md3");
- precache_model ("models/turrets/mlrs.md3");
- return true;
- }
- }
++ return true;
++ }
++ case TR_THINK:
++ {
++ // 0 = full, 6 = empty
++ self.tur_head.frame = bound(0, 6 - floor(0.1 + self.ammo / self.shot_dmg), 6);
++ if(self.tur_head.frame < 0)
++ {
++ dprint("ammo:",ftos(self.ammo),"\n");
++ dprint("shot_dmg:",ftos(self.shot_dmg),"\n");
++ }
+
- return true;
++ return true;
++ }
++ case TR_DEATH:
++ {
++ return true;
++ }
++ case TR_SETUP:
++ {
++ self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
++ self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
+
- switch(req)
- {
- case TR_SETUP:
- {
- return true;
- }
- case TR_PRECACHE:
- {
- return true;
- }
- }
++ self.damage_flags |= TFL_DMG_HEADSHAKE;
++ self.shoot_flags |= TFL_SHOOT_VOLLYALWAYS;
++ self.volly_counter = self.shot_volly;
++
++ return true;
++ }
++ case TR_PRECACHE:
++ {
++ precache_model ("models/turrets/base.md3");
++ precache_model ("models/turrets/mlrs.md3");
++ return true;
++ }
++ }
++
++ return true;
+}
+
+#endif // SVQC
+#ifdef CSQC
+float t_mlrs(float req)
+{
- return true;
++ switch(req)
++ {
++ case TR_SETUP:
++ {
++ return true;
++ }
++ case TR_PRECACHE:
++ {
++ return true;
++ }
++ }
+
++ return true;
+}
+
+#endif // CSQC
+#endif // REGISTER_TURRET
--- /dev/null
- if (self.fireflag != 0) return 0;
- return turret_firecheck();
+#ifdef REGISTER_TURRET
+REGISTER_TURRET(
+/* TUR_##id */ PHASER,
+/* function */ t_phaser,
+/* spawnflags */ TUR_FLAG_SNIPER | TUR_FLAG_HITSCAN | TUR_FLAG_PLAYER,
+/* mins,maxs */ '-32 -32 0', '32 32 64',
+/* model */ "base.md3",
+/* head_model */ "phaser.md3",
+/* netname */ "phaser",
+/* fullname */ _("Phaser Cannon")
+);
+#else
+#ifdef SVQC
+.float fireflag;
+
+float turret_phaser_firecheck()
+{
- if ((time > self.cnt) || (self.owner.deadflag != DEAD_NO))
- {
- self.owner.attack_finished_single = time + self.owner.shot_refire;
- self.owner.fireflag = 2;
- self.owner.tur_head.frame = 10;
- sound (self, CH_SHOTS_SINGLE, "misc/null.wav", VOL_BASE, ATTEN_NORM);
- remove(self);
- return;
- }
-
- turret_do_updates(self.owner);
-
- if (time - self.shot_spread > 0)
- {
- self.shot_spread = time + 2;
- sound (self, CH_SHOTS_SINGLE, "turrets/phaser.wav", VOL_BASE, ATTEN_NORM);
- }
-
-
- self.nextthink = time + self.ticrate;
-
- self.owner.attack_finished_single = time + frametime;
- entity oldself;
- oldself = self;
- self = self.owner;
- FireImoBeam ( self.tur_shotorg,
- self.tur_shotorg + self.tur_shotdir_updated * self.target_range,
- '-1 -1 -1' * self.shot_radius,
- '1 1 1' * self.shot_radius,
- self.shot_force,
- oldself.shot_dmg,
- 0.75,
- DEATH_TURRET_PHASER);
- self = oldself;
- self.scale = vlen(self.owner.tur_shotorg - trace_endpos) / 256;
++ if (self.fireflag != 0) return 0;
++ return turret_firecheck();
+}
+
+void beam_think()
+{
- switch(req)
- {
- case TR_ATTACK:
- {
- entity beam;
-
- beam = spawn();
- beam.ticrate = 0.1; //autocvar_sys_ticrate;
- setmodel(beam,"models/turrets/phaser_beam.md3");
- beam.effects = EF_LOWPRECISION;
- beam.solid = SOLID_NOT;
- beam.think = beam_think;
- beam.cnt = time + self.shot_speed;
- beam.shot_spread = time + 2;
- beam.nextthink = time;
- beam.owner = self;
- beam.shot_dmg = self.shot_dmg / (self.shot_speed / beam.ticrate);
- beam.scale = self.target_range / 256;
- beam.movetype = MOVETYPE_NONE;
- beam.enemy = self.enemy;
- beam.bot_dodge = true;
- beam.bot_dodgerating = beam.shot_dmg;
- sound (beam, CH_SHOTS_SINGLE, "turrets/phaser.wav", VOL_BASE, ATTEN_NORM);
- self.fireflag = 1;
-
- beam.attack_finished_single = self.attack_finished_single;
- self.attack_finished_single = time; // + autocvar_sys_ticrate;
-
- setattachment(beam,self.tur_head,"tag_fire");
-
- soundat (self, trace_endpos, CH_SHOTS, "weapons/neximpact.wav", VOL_BASE, ATTEN_NORM);
-
- if (self.tur_head.frame == 0)
- self.tur_head.frame = 1;
-
- return true;
- }
- case TR_THINK:
- {
- if (self.tur_head.frame != 0)
- {
- if (self.fireflag == 1)
- {
- if (self.tur_head.frame == 10)
- self.tur_head.frame = 1;
- else
- self.tur_head.frame = self.tur_head.frame +1;
- }
- else if (self.fireflag == 2 )
- {
- self.tur_head.frame = self.tur_head.frame +1;
- if (self.tur_head.frame == 15)
- {
- self.tur_head.frame = 0;
- self.fireflag = 0;
- }
- }
- }
-
- return true;
- }
- case TR_DEATH:
- {
- return true;
- }
- case TR_SETUP:
- {
- self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
- self.aim_flags = TFL_AIM_LEAD;
-
- self.turret_firecheckfunc = turret_phaser_firecheck;
-
- return true;
- }
- case TR_PRECACHE:
- {
- precache_model ("models/turrets/base.md3");
- precache_model ("models/turrets/phaser.md3");
- precache_model ("models/turrets/phaser_beam.md3");
- precache_sound ("turrets/phaser.wav");
- return true;
- }
- }
-
- return true;
++ if ((time > self.cnt) || (self.owner.deadflag != DEAD_NO))
++ {
++ self.owner.attack_finished_single = time + self.owner.shot_refire;
++ self.owner.fireflag = 2;
++ self.owner.tur_head.frame = 10;
++ sound (self, CH_SHOTS_SINGLE, "misc/null.wav", VOL_BASE, ATTEN_NORM);
++ remove(self);
++ return;
++ }
++
++ turret_do_updates(self.owner);
++
++ if (time - self.shot_spread > 0)
++ {
++ self.shot_spread = time + 2;
++ sound (self, CH_SHOTS_SINGLE, "turrets/phaser.wav", VOL_BASE, ATTEN_NORM);
++ }
++
++
++ self.nextthink = time + self.ticrate;
++
++ self.owner.attack_finished_single = time + frametime;
++ entity oldself;
++ oldself = self;
++ self = self.owner;
++ FireImoBeam ( self.tur_shotorg,
++ self.tur_shotorg + self.tur_shotdir_updated * self.target_range,
++ '-1 -1 -1' * self.shot_radius,
++ '1 1 1' * self.shot_radius,
++ self.shot_force,
++ oldself.shot_dmg,
++ 0.75,
++ DEATH_TURRET_PHASER);
++ self = oldself;
++ self.scale = vlen(self.owner.tur_shotorg - trace_endpos) / 256;
+
+}
+
+void spawnfunc_turret_phaser() { if(!turret_initialize(TUR_PHASER)) remove(self); }
+
+float t_phaser(float req)
+{
- switch(req)
- {
- case TR_SETUP:
- {
- return true;
- }
- case TR_PRECACHE:
- {
- return true;
- }
- }
-
- return true;
++ switch(req)
++ {
++ case TR_ATTACK:
++ {
++ entity beam;
++
++ beam = spawn();
++ beam.ticrate = 0.1; //autocvar_sys_ticrate;
++ setmodel(beam,"models/turrets/phaser_beam.md3");
++ beam.effects = EF_LOWPRECISION;
++ beam.solid = SOLID_NOT;
++ beam.think = beam_think;
++ beam.cnt = time + self.shot_speed;
++ beam.shot_spread = time + 2;
++ beam.nextthink = time;
++ beam.owner = self;
++ beam.shot_dmg = self.shot_dmg / (self.shot_speed / beam.ticrate);
++ beam.scale = self.target_range / 256;
++ beam.movetype = MOVETYPE_NONE;
++ beam.enemy = self.enemy;
++ beam.bot_dodge = true;
++ beam.bot_dodgerating = beam.shot_dmg;
++ sound (beam, CH_SHOTS_SINGLE, "turrets/phaser.wav", VOL_BASE, ATTEN_NORM);
++ self.fireflag = 1;
++
++ beam.attack_finished_single = self.attack_finished_single;
++ self.attack_finished_single = time; // + autocvar_sys_ticrate;
++
++ setattachment(beam,self.tur_head,"tag_fire");
++
++ soundat (self, trace_endpos, CH_SHOTS, "weapons/neximpact.wav", VOL_BASE, ATTEN_NORM);
++
++ if (self.tur_head.frame == 0)
++ self.tur_head.frame = 1;
++
++ return true;
++ }
++ case TR_THINK:
++ {
++ if (self.tur_head.frame != 0)
++ {
++ if (self.fireflag == 1)
++ {
++ if (self.tur_head.frame == 10)
++ self.tur_head.frame = 1;
++ else
++ self.tur_head.frame = self.tur_head.frame +1;
++ }
++ else if (self.fireflag == 2 )
++ {
++ self.tur_head.frame = self.tur_head.frame +1;
++ if (self.tur_head.frame == 15)
++ {
++ self.tur_head.frame = 0;
++ self.fireflag = 0;
++ }
++ }
++ }
++
++ return true;
++ }
++ case TR_DEATH:
++ {
++ return true;
++ }
++ case TR_SETUP:
++ {
++ self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
++ self.aim_flags = TFL_AIM_LEAD;
++
++ self.turret_firecheckfunc = turret_phaser_firecheck;
++
++ return true;
++ }
++ case TR_PRECACHE:
++ {
++ precache_model ("models/turrets/base.md3");
++ precache_model ("models/turrets/phaser.md3");
++ precache_model ("models/turrets/phaser_beam.md3");
++ precache_sound ("turrets/phaser.wav");
++ return true;
++ }
++ }
++
++ return true;
+}
+
+#endif // SVQC
+#ifdef CSQC
+float t_phaser(float req)
+{
++ switch(req)
++ {
++ case TR_SETUP:
++ {
++ return true;
++ }
++ case TR_PRECACHE:
++ {
++ return true;
++ }
++ }
++
++ return true;
+}
+
+#endif // CSQC
+#endif // REGISTER_TURRET
--- /dev/null
- switch(req)
- {
- case TR_ATTACK:
- {
- if(g_instagib)
- {
- float flying;
- flying = IsFlying(self); // do this BEFORE to make the trace values from FireRailgunBullet last
-
- FireRailgunBullet (self.tur_shotorg, self.tur_shotorg + self.tur_shotdir_updated * MAX_SHOT_DISTANCE, 10000000000,
- 800, 0, 0, 0, 0, DEATH_TURRET_PLASMA);
-
- pointparticles(particleeffectnum("nex_muzzleflash"), self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
-
- // teamcolor / hit beam effect
- vector v;
- string s;
- v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
- s = strcat("TE_TEI_G3", ((self.team) ? Static_Team_ColorName_Upper(self.team) : ""));
-
- WarpZone_TrailParticles(world, particleeffectnum(s), self.tur_shotorg, v);
-
- if (self.tur_head.frame == 0)
- self.tur_head.frame = 1;
- }
- else
- {
- entity missile = turret_projectile("weapons/hagar_fire.wav", 1, 0, DEATH_TURRET_PLASMA, PROJECTILE_ELECTRO_BEAM, TRUE, TRUE);
- missile.missile_flags = MIF_SPLASH;
-
- pointparticles(particleeffectnum("laser_muzzleflash"), self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
- if (self.tur_head.frame == 0)
- self.tur_head.frame = 1;
- }
-
- return true;
- }
- case TR_THINK:
- {
- if (self.tur_head.frame != 0)
- self.tur_head.frame = self.tur_head.frame + 1;
-
- if (self.tur_head.frame > 5)
- self.tur_head.frame = 0;
-
- return true;
- }
- case TR_DEATH:
- {
- return true;
- }
- case TR_SETUP:
- {
- self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
- self.damage_flags |= TFL_DMG_HEADSHAKE;
- self.firecheck_flags |= TFL_FIRECHECK_AFF;
- self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_SPLASH;
-
- turret_do_updates(self);
-
- return true;
- }
- case TR_PRECACHE:
- {
- precache_model ("models/turrets/base.md3");
- precache_model ("models/turrets/plasma.md3");
- return true;
- }
- }
-
- return true;
+#ifdef REGISTER_TURRET
+REGISTER_TURRET(
+/* TUR_##id */ PLASMA,
+/* function */ t_plasma,
+/* spawnflags */ TUR_FLAG_SPLASH | TUR_FLAG_MEDPROJ | TUR_FLAG_PLAYER,
+/* mins,maxs */ '-32 -32 0', '32 32 64',
+/* model */ "base.md3",
+/* head_model */ "plasma.md3",
+/* netname */ "plasma",
+/* fullname */ _("Plasma Cannon")
+);
+#else
+#ifdef SVQC
+void spawnfunc_turret_plasma() { if(!turret_initialize(TUR_PLASMA)) remove(self); }
+
+float t_plasma(float req)
+{
- switch(req)
- {
- case TR_SETUP:
- {
- return true;
- }
- case TR_PRECACHE:
- {
- return true;
- }
- }
-
- return true;
++ switch(req)
++ {
++ case TR_ATTACK:
++ {
++ if(g_instagib)
++ {
++ float flying;
++ flying = IsFlying(self); // do this BEFORE to make the trace values from FireRailgunBullet last
++
++ FireRailgunBullet (self.tur_shotorg, self.tur_shotorg + self.tur_shotdir_updated * MAX_SHOT_DISTANCE, 10000000000,
++ 800, 0, 0, 0, 0, DEATH_TURRET_PLASMA);
++
++ Send_Effect("nex_muzzleflash", self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
++
++ // teamcolor / hit beam effect
++ vector v;
++ string s;
++ v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
++ s = strcat("TE_TEI_G3", ((self.team) ? Static_Team_ColorName_Upper(self.team) : ""));
++
++ WarpZone_TrailParticles(world, particleeffectnum(s), self.tur_shotorg, v);
++
++ if (self.tur_head.frame == 0)
++ self.tur_head.frame = 1;
++ }
++ else
++ {
++ entity missile = turret_projectile("weapons/hagar_fire.wav", 1, 0, DEATH_TURRET_PLASMA, PROJECTILE_ELECTRO_BEAM, TRUE, TRUE);
++ missile.missile_flags = MIF_SPLASH;
++
++ Send_Effect("laser_muzzleflash", self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
++ if (self.tur_head.frame == 0)
++ self.tur_head.frame = 1;
++ }
++
++ return true;
++ }
++ case TR_THINK:
++ {
++ if (self.tur_head.frame != 0)
++ self.tur_head.frame = self.tur_head.frame + 1;
++
++ if (self.tur_head.frame > 5)
++ self.tur_head.frame = 0;
++
++ return true;
++ }
++ case TR_DEATH:
++ {
++ return true;
++ }
++ case TR_SETUP:
++ {
++ self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
++ self.damage_flags |= TFL_DMG_HEADSHAKE;
++ self.firecheck_flags |= TFL_FIRECHECK_AFF;
++ self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_SPLASH;
++
++ turret_do_updates(self);
++
++ return true;
++ }
++ case TR_PRECACHE:
++ {
++ precache_model ("models/turrets/base.md3");
++ precache_model ("models/turrets/plasma.md3");
++ return true;
++ }
++ }
++
++ return true;
+}
+
+#endif // SVQC
+#ifdef CSQC
+float t_plasma(float req)
+{
++ switch(req)
++ {
++ case TR_SETUP:
++ {
++ return true;
++ }
++ case TR_PRECACHE:
++ {
++ return true;
++ }
++ }
++
++ return true;
+}
+
+#endif // CSQC
+#endif // REGISTER_TURRET
--- /dev/null
- switch(req)
- {
- case TR_ATTACK:
- {
- if(g_instagib)
- {
- float flying;
- flying = IsFlying(self); // do this BEFORE to make the trace values from FireRailgunBullet last
-
- FireRailgunBullet (self.tur_shotorg, self.tur_shotorg + self.tur_shotdir_updated * MAX_SHOT_DISTANCE, 10000000000,
- 800, 0, 0, 0, 0, DEATH_TURRET_PLASMA);
-
-
- pointparticles(particleeffectnum("nex_muzzleflash"), self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
-
- // teamcolor / hit beam effect
- vector v;
- string s;
- v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
- s = strcat("TE_TEI_G3", ((self.team) ? Static_Team_ColorName_Upper(self.team) : ""));
-
- WarpZone_TrailParticles(world, particleeffectnum(s), self.tur_shotorg, v);
-
- self.tur_head.frame += 1;
- }
- else
- {
- entity missile = turret_projectile("weapons/hagar_fire.wav", 1, 0, DEATH_TURRET_PLASMA, PROJECTILE_ELECTRO_BEAM, TRUE, TRUE);
- missile.missile_flags = MIF_SPLASH;
- pointparticles(particleeffectnum("laser_muzzleflash"), self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
- self.tur_head.frame += 1;
- }
-
- return true;
- }
- case TR_THINK:
- {
- if ((self.tur_head.frame != 0) && (self.tur_head.frame != 3))
- self.tur_head.frame = self.tur_head.frame + 1;
-
- if (self.tur_head.frame > 6)
- self.tur_head.frame = 0;
-
- return true;
- }
- case TR_DEATH:
- {
- return true;
- }
- case TR_SETUP:
- {
- self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
- self.damage_flags |= TFL_DMG_HEADSHAKE;
- self.firecheck_flags |= TFL_FIRECHECK_AFF;
- self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_SPLASH;
-
- turret_do_updates(self);
-
- return true;
- }
- case TR_PRECACHE:
- {
- precache_model ("models/turrets/base.md3");
- precache_model ("models/turrets/plasmad.md3");
- return true;
- }
- }
-
- return true;
+#ifdef REGISTER_TURRET
+REGISTER_TURRET(
+/* TUR_##id */ PLASMA_DUAL,
+/* function */ t_plasma_dual,
+/* spawnflags */ TUR_FLAG_SPLASH | TUR_FLAG_MEDPROJ | TUR_FLAG_PLAYER,
+/* mins,maxs */ '-32 -32 0', '32 32 64',
+/* model */ "base.md3",
+/* head_model */ "plasmad.md3",
+/* netname */ "plasma_dual",
+/* fullname */ _("Dual Plasma Cannon")
+);
+#else
+#ifdef SVQC
+void spawnfunc_turret_plasma_dual() { if(!turret_initialize(TUR_PLASMA_DUAL)) remove(self); }
+
+float t_plasma_dual(float req)
+{
- switch(req)
- {
- case TR_SETUP:
- {
- return true;
- }
- case TR_PRECACHE:
- {
- return true;
- }
- }
-
- return true;
++ switch(req)
++ {
++ case TR_ATTACK:
++ {
++ if(g_instagib)
++ {
++ float flying;
++ flying = IsFlying(self); // do this BEFORE to make the trace values from FireRailgunBullet last
++
++ FireRailgunBullet (self.tur_shotorg, self.tur_shotorg + self.tur_shotdir_updated * MAX_SHOT_DISTANCE, 10000000000,
++ 800, 0, 0, 0, 0, DEATH_TURRET_PLASMA);
++
++
++ Send_Effect("nex_muzzleflash", self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
++
++ // teamcolor / hit beam effect
++ vector v;
++ string s;
++ v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
++ s = strcat("TE_TEI_G3", ((self.team) ? Static_Team_ColorName_Upper(self.team) : ""));
++
++ WarpZone_TrailParticles(world, particleeffectnum(s), self.tur_shotorg, v);
++
++ self.tur_head.frame += 1;
++ }
++ else
++ {
++ entity missile = turret_projectile("weapons/hagar_fire.wav", 1, 0, DEATH_TURRET_PLASMA, PROJECTILE_ELECTRO_BEAM, TRUE, TRUE);
++ missile.missile_flags = MIF_SPLASH;
++ Send_Effect("laser_muzzleflash", self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
++ self.tur_head.frame += 1;
++ }
++
++ return true;
++ }
++ case TR_THINK:
++ {
++ if ((self.tur_head.frame != 0) && (self.tur_head.frame != 3))
++ self.tur_head.frame = self.tur_head.frame + 1;
++
++ if (self.tur_head.frame > 6)
++ self.tur_head.frame = 0;
++
++ return true;
++ }
++ case TR_DEATH:
++ {
++ return true;
++ }
++ case TR_SETUP:
++ {
++ self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
++ self.damage_flags |= TFL_DMG_HEADSHAKE;
++ self.firecheck_flags |= TFL_FIRECHECK_AFF;
++ self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_SPLASH;
++
++ turret_do_updates(self);
++
++ return true;
++ }
++ case TR_PRECACHE:
++ {
++ precache_model ("models/turrets/base.md3");
++ precache_model ("models/turrets/plasmad.md3");
++ return true;
++ }
++ }
++
++ return true;
+}
+
+#endif // SVQC
+#ifdef CSQC
+float t_plasma_dual(float req)
+{
++ switch(req)
++ {
++ case TR_SETUP:
++ {
++ return true;
++ }
++ case TR_PRECACHE:
++ {
++ return true;
++ }
++ }
++
++ return true;
+}
+
+#endif // CSQC
+#endif // REGISTER_TURRET
--- /dev/null
- entity e;
- entity etarget = world;
- float d,dd;
- float r;
-
- dd = range + 1;
-
- e = findradius(from.origin,range);
- while (e)
- {
- if ((e.railgunhit != 1) && (e != from))
- {
- r = turret_validate_target(self,e,self.target_validate_flags);
- if (r > 0)
- {
- traceline(from.origin,0.5 * (e.absmin + e.absmax),MOVE_WORLDONLY,from);
- if (trace_fraction == 1.0)
- {
- d = vlen(e.origin - from.origin);
- if (d < dd)
- {
- dd = d;
- etarget = e;
- }
- }
- }
- }
- e = e.chain;
- }
-
- if (etarget)
- {
- te_csqc_lightningarc(from.origin,etarget.origin);
- Damage(etarget, self, self, damage, DEATH_TURRET_TESLA, etarget.origin, '0 0 0');
- etarget.railgunhit = 1;
- }
-
- return etarget;
+#ifdef REGISTER_TURRET
+REGISTER_TURRET(
+/* TUR_##id */ TESLA,
+/* function */ t_tesla,
+/* spawnflags */ TUR_FLAG_HITSCAN | TUR_FLAG_PLAYER | TUR_FLAG_MISSILE,
+/* mins,maxs */ '-60 -60 0', '60 60 128',
+/* model */ "tesla_base.md3",
+/* head_model */ "tesla_head.md3",
+/* netname */ "tesla",
+/* fullname */ _("Tesla Coil")
+);
+#else
+#ifdef SVQC
+entity toast(entity from, float range, float damage)
+{
- // g_turrets_targetscan_maxdelay forces a target re-scan at least this often
- float do_target_scan = 0;
-
- if((self.target_select_time + autocvar_g_turrets_targetscan_maxdelay) < time)
- do_target_scan = 1;
-
- // Old target (if any) invalid?
- if(self.target_validate_time < time)
- if (turret_validate_target(self, self.enemy, self.target_validate_flags) <= 0)
- {
- self.enemy = world;
- self.target_validate_time = time + 0.5;
- do_target_scan = 1;
- }
-
- // But never more often then g_turrets_targetscan_mindelay!
- if (self.target_select_time + autocvar_g_turrets_targetscan_mindelay > time)
- do_target_scan = 0;
-
- if(do_target_scan)
- {
- self.enemy = turret_select_target();
- self.target_select_time = time;
- }
-
- if(!turret_firecheck())
- return 0;
-
- if(self.enemy)
- return 1;
-
- return 0;
++ entity e;
++ entity etarget = world;
++ float d,dd;
++ float r;
++
++ dd = range + 1;
++
++ e = findradius(from.origin,range);
++ while (e)
++ {
++ if ((e.railgunhit != 1) && (e != from))
++ {
++ r = turret_validate_target(self,e,self.target_validate_flags);
++ if (r > 0)
++ {
++ traceline(from.origin,0.5 * (e.absmin + e.absmax),MOVE_WORLDONLY,from);
++ if (trace_fraction == 1.0)
++ {
++ d = vlen(e.origin - from.origin);
++ if (d < dd)
++ {
++ dd = d;
++ etarget = e;
++ }
++ }
++ }
++ }
++ e = e.chain;
++ }
++
++ if (etarget)
++ {
++ te_csqc_lightningarc(from.origin,etarget.origin);
++ Damage(etarget, self, self, damage, DEATH_TURRET_TESLA, etarget.origin, '0 0 0');
++ etarget.railgunhit = 1;
++ }
++
++ return etarget;
+}
+
+float turret_tesla_firecheck()
+{
- switch(req)
- {
- case TR_ATTACK:
- {
- entity e, t;
- float d, r, i;
-
- d = self.shot_dmg;
- r = self.target_range;
- e = spawn();
- setorigin(e,self.tur_shotorg);
-
- self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
-
- t = toast(e,r,d);
- remove(e);
-
- if (t == world) return true;
-
- self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES | TFL_TARGETSELECT_TEAMCHECK;
-
- self.attack_finished_single = time + self.shot_refire;
- for (i = 0; i < 10; ++i)
- {
- d *= 0.75;
- r *= 0.85;
- t = toast(t, r, d);
- if (t == world) break;
-
- }
-
- e = findchainfloat(railgunhit, 1);
- while (e)
- {
- e.railgunhit = 0;
- e = e.chain;
- }
-
- return true;
- }
- case TR_THINK:
- {
- if(!self.active)
- {
- self.tur_head.avelocity = '0 0 0';
- return true;
- }
-
- if(self.ammo < self.shot_dmg)
- {
- self.tur_head.avelocity = '0 45 0' * (self.ammo / self.shot_dmg);
- }
- else
- {
- self.tur_head.avelocity = '0 180 0' * (self.ammo / self.shot_dmg);
-
- if(self.attack_finished_single > time)
- return true;
-
- float f;
- f = (self.ammo / self.ammo_max);
- f = f * f;
- if(f > random())
- if(random() < 0.1)
- te_csqc_lightningarc(self.tur_shotorg,self.tur_shotorg + (randomvec() * 350));
- }
-
- return true;
- }
- case TR_DEATH:
- {
- return true;
- }
- case TR_SETUP:
- {
- self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
- TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
-
- self.turret_firecheckfunc = turret_tesla_firecheck;
- self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
- TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
-
- self.firecheck_flags = TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AMMO_OWN;
- self.shoot_flags = TFL_SHOOT_CUSTOM;
- self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
- self.aim_flags = TFL_AIM_NO;
- self.track_flags = TFL_TRACK_NO;
-
- return true;
- }
- case TR_PRECACHE:
- {
- precache_model ("models/turrets/tesla_base.md3");
- precache_model ("models/turrets/tesla_head.md3");
- return true;
- }
- }
-
- return true;
++ // g_turrets_targetscan_maxdelay forces a target re-scan at least this often
++ float do_target_scan = 0;
++
++ if((self.target_select_time + autocvar_g_turrets_targetscan_maxdelay) < time)
++ do_target_scan = 1;
++
++ // Old target (if any) invalid?
++ if(self.target_validate_time < time)
++ if (turret_validate_target(self, self.enemy, self.target_validate_flags) <= 0)
++ {
++ self.enemy = world;
++ self.target_validate_time = time + 0.5;
++ do_target_scan = 1;
++ }
++
++ // But never more often then g_turrets_targetscan_mindelay!
++ if (self.target_select_time + autocvar_g_turrets_targetscan_mindelay > time)
++ do_target_scan = 0;
++
++ if(do_target_scan)
++ {
++ self.enemy = turret_select_target();
++ self.target_select_time = time;
++ }
++
++ if(!turret_firecheck())
++ return 0;
++
++ if(self.enemy)
++ return 1;
++
++ return 0;
+}
+
+void spawnfunc_turret_tesla() { if(!turret_initialize(TUR_TESLA)) remove(self); }
+
+float t_tesla(float req)
+{
- switch(req)
- {
- case TR_SETUP:
- {
- return true;
- }
- case TR_PRECACHE:
- {
- return true;
- }
- }
-
- return true;
++ switch(req)
++ {
++ case TR_ATTACK:
++ {
++ entity e, t;
++ float d, r, i;
++
++ d = self.shot_dmg;
++ r = self.target_range;
++ e = spawn();
++ setorigin(e,self.tur_shotorg);
++
++ self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
++
++ t = toast(e,r,d);
++ remove(e);
++
++ if (t == world) return true;
++
++ self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES | TFL_TARGETSELECT_TEAMCHECK;
++
++ self.attack_finished_single = time + self.shot_refire;
++ for (i = 0; i < 10; ++i)
++ {
++ d *= 0.75;
++ r *= 0.85;
++ t = toast(t, r, d);
++ if (t == world) break;
++
++ }
++
++ e = findchainfloat(railgunhit, 1);
++ while (e)
++ {
++ e.railgunhit = 0;
++ e = e.chain;
++ }
++
++ return true;
++ }
++ case TR_THINK:
++ {
++ if(!self.active)
++ {
++ self.tur_head.avelocity = '0 0 0';
++ return true;
++ }
++
++ if(self.ammo < self.shot_dmg)
++ {
++ self.tur_head.avelocity = '0 45 0' * (self.ammo / self.shot_dmg);
++ }
++ else
++ {
++ self.tur_head.avelocity = '0 180 0' * (self.ammo / self.shot_dmg);
++
++ if(self.attack_finished_single > time)
++ return true;
++
++ float f;
++ f = (self.ammo / self.ammo_max);
++ f = f * f;
++ if(f > random())
++ if(random() < 0.1)
++ te_csqc_lightningarc(self.tur_shotorg,self.tur_shotorg + (randomvec() * 350));
++ }
++
++ return true;
++ }
++ case TR_DEATH:
++ {
++ return true;
++ }
++ case TR_SETUP:
++ {
++ self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
++ TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
++
++ self.turret_firecheckfunc = turret_tesla_firecheck;
++ self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
++ TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
++
++ self.firecheck_flags = TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AMMO_OWN;
++ self.shoot_flags = TFL_SHOOT_CUSTOM;
++ self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
++ self.aim_flags = TFL_AIM_NO;
++ self.track_flags = TFL_TRACK_NO;
++
++ return true;
++ }
++ case TR_PRECACHE:
++ {
++ precache_model ("models/turrets/tesla_base.md3");
++ precache_model ("models/turrets/tesla_head.md3");
++ return true;
++ }
++ }
++
++ return true;
+}
+
+#endif // SVQC
+#ifdef CSQC
+float t_tesla(float req)
+{
++ switch(req)
++ {
++ case TR_SETUP:
++ {
++ return true;
++ }
++ case TR_PRECACHE:
++ {
++ return true;
++ }
++ }
++
++ return true;
+}
+
+#endif // CSQC
+#endif // REGISTER_TURRET
--- /dev/null
- if (self.animflag == ANIM_MELEE)
- return 0;
+#ifdef REGISTER_TURRET
+REGISTER_TURRET(
+/* TUR_##id */ WALKER,
+/* function */ t_walker,
+/* spawnflags */ TUR_FLAG_PLAYER | TUR_FLAG_MOVE,
+/* mins,maxs */ '-70 -70 0', '70 70 95',
+/* model */ "walker_body.md3",
+/* head_model */ "walker_head_minigun.md3",
+/* netname */ "walker",
+/* fullname */ _("Walker Turret")
+);
+#else
+#ifdef SVQC
+float autocvar_g_turrets_unit_walker_melee_damage;
+float autocvar_g_turrets_unit_walker_melee_force;
+float autocvar_g_turrets_unit_walker_melee_range;
+float autocvar_g_turrets_unit_walker_rocket_damage;
+float autocvar_g_turrets_unit_walker_rocket_radius;
+float autocvar_g_turrets_unit_walker_rocket_force;
+float autocvar_g_turrets_unit_walker_rocket_speed;
+float autocvar_g_turrets_unit_walker_rocket_range;
+float autocvar_g_turrets_unit_walker_rocket_range_min;
+float autocvar_g_turrets_unit_walker_rocket_refire;
+float autocvar_g_turrets_unit_walker_rocket_turnrate;
+float autocvar_g_turrets_unit_walker_speed_stop;
+float autocvar_g_turrets_unit_walker_speed_walk;
+float autocvar_g_turrets_unit_walker_speed_run;
+float autocvar_g_turrets_unit_walker_speed_jump;
+float autocvar_g_turrets_unit_walker_speed_swim;
+float autocvar_g_turrets_unit_walker_speed_roam;
+float autocvar_g_turrets_unit_walker_turn;
+float autocvar_g_turrets_unit_walker_turn_walk;
+float autocvar_g_turrets_unit_walker_turn_strafe;
+float autocvar_g_turrets_unit_walker_turn_swim;
+float autocvar_g_turrets_unit_walker_turn_run;
+
+#define ANIM_NO 0
+#define ANIM_TURN 1
+#define ANIM_WALK 2
+#define ANIM_RUN 3
+#define ANIM_STRAFE_L 4
+#define ANIM_STRAFE_R 5
+#define ANIM_JUMP 6
+#define ANIM_LAND 7
+#define ANIM_PAIN 8
+#define ANIM_MELEE 9
+#define ANIM_SWIM 10
+#define ANIM_ROAM 11
+
+.float animflag;
+.float idletime;
+
+#define WALKER_PATH(s,e) pathlib_astar(s,e)
+
+float walker_firecheck()
+{
- return turret_firecheck();
++ if (self.animflag == ANIM_MELEE)
++ return 0;
+
- vector where;
- entity e;
++ return turret_firecheck();
+}
+
+void walker_melee_do_dmg()
+{
- makevectors(self.angles);
- where = self.origin + v_forward * 128;
++ vector where;
++ entity e;
+
- e = findradius(where,32);
- while (e)
- {
- if (turret_validate_target(self, e, self.target_validate_flags))
- if (e != self && e.owner != self)
- Damage(e, self, self, (autocvar_g_turrets_unit_walker_melee_damage), DEATH_TURRET_WALK_MELEE, '0 0 0', v_forward * (autocvar_g_turrets_unit_walker_melee_force));
++ makevectors(self.angles);
++ where = self.origin + v_forward * 128;
+
- e = e.chain;
- }
++ e = findradius(where,32);
++ while (e)
++ {
++ if (turret_validate_target(self, e, self.target_validate_flags))
++ if (e != self && e.owner != self)
++ Damage(e, self, self, (autocvar_g_turrets_unit_walker_melee_damage), DEATH_TURRET_WALK_MELEE, '0 0 0', v_forward * (autocvar_g_turrets_unit_walker_melee_force));
+
- turrets_setframe(ANIM_NO, false);
- self.animflag = self.frame;
++ e = e.chain;
++ }
+}
+
+void walker_setnoanim()
+{
- RadiusDamage (self, self.owner, (autocvar_g_turrets_unit_walker_rocket_damage), 0, (autocvar_g_turrets_unit_walker_rocket_radius), self, world, (autocvar_g_turrets_unit_walker_rocket_force), DEATH_TURRET_WALK_ROCKET, world);
- remove (self);
++ turrets_setframe(ANIM_NO, false);
++ self.animflag = self.frame;
+}
+void walker_rocket_explode()
+{
- self.health = self.health - damage;
- self.velocity = self.velocity + vforce;
++ RadiusDamage (self, self.owner, (autocvar_g_turrets_unit_walker_rocket_damage), 0, (autocvar_g_turrets_unit_walker_rocket_radius), self, world, (autocvar_g_turrets_unit_walker_rocket_force), DEATH_TURRET_WALK_ROCKET, world);
++ remove (self);
+}
+
+void walker_rocket_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce)
+{
- if (self.health <= 0)
- W_PrepareExplosionByDamage(self.owner, walker_rocket_explode);
++ self.health = self.health - damage;
++ self.velocity = self.velocity + vforce;
+
- vector newdir;
- float edist;
- float itime;
- float m_speed;
-
- self.nextthink = time;
-
- edist = vlen(self.enemy.origin - self.origin);
-
- // Simulate crude guidance
- if (self.cnt < time)
- {
- if (edist < 1000)
- self.tur_shotorg = randomvec() * min(edist, 64);
- else
- self.tur_shotorg = randomvec() * min(edist, 256);
-
- self.cnt = time + 0.5;
- }
-
- if (edist < 128)
- self.tur_shotorg = '0 0 0';
-
- if (self.max_health < time)
- {
- self.think = walker_rocket_explode;
- self.nextthink = time;
- return;
- }
-
- if (self.shot_dmg != 1337 && random() < 0.01)
- {
- walker_rocket_loop();
- return;
- }
-
- m_speed = vlen(self.velocity);
-
- // Enemy dead? just keep on the current heading then.
- if (self.enemy == world || self.enemy.deadflag != DEAD_NO)
- self.enemy = world;
-
- if (self.enemy)
- {
- itime = max(edist / m_speed, 1);
- newdir = steerlib_pull(self.enemy.origin + self.tur_shotorg);
- }
- else
- newdir = normalize(self.velocity);
-
- WALKER_ROCKET_MOVE;
++ if (self.health <= 0)
++ W_PrepareExplosionByDamage(self.owner, walker_rocket_explode);
+}
+
+#define WALKER_ROCKET_MOVE movelib_move_simple(newdir, (autocvar_g_turrets_unit_walker_rocket_speed), (autocvar_g_turrets_unit_walker_rocket_turnrate)); UpdateCSQCProjectile(self)
+void walker_rocket_loop();
+void walker_rocket_think()
+{
- vector newdir;
- self.nextthink = time;
++ vector newdir;
++ float edist;
++ float itime;
++ float m_speed;
++
++ self.nextthink = time;
++
++ edist = vlen(self.enemy.origin - self.origin);
++
++ // Simulate crude guidance
++ if (self.cnt < time)
++ {
++ if (edist < 1000)
++ self.tur_shotorg = randomvec() * min(edist, 64);
++ else
++ self.tur_shotorg = randomvec() * min(edist, 256);
++
++ self.cnt = time + 0.5;
++ }
++
++ if (edist < 128)
++ self.tur_shotorg = '0 0 0';
++
++ if (self.max_health < time)
++ {
++ self.think = walker_rocket_explode;
++ self.nextthink = time;
++ return;
++ }
++
++ if (self.shot_dmg != 1337 && random() < 0.01)
++ {
++ walker_rocket_loop();
++ return;
++ }
++
++ m_speed = vlen(self.velocity);
++
++ // Enemy dead? just keep on the current heading then.
++ if (self.enemy == world || self.enemy.deadflag != DEAD_NO)
++ self.enemy = world;
++
++ if (self.enemy)
++ {
++ itime = max(edist / m_speed, 1);
++ newdir = steerlib_pull(self.enemy.origin + self.tur_shotorg);
++ }
++ else
++ newdir = normalize(self.velocity);
++
++ WALKER_ROCKET_MOVE;
+}
+
+void walker_rocket_loop3()
+{
- if (self.max_health < time)
- {
- self.think = walker_rocket_explode;
- return;
- }
++ vector newdir;
++ self.nextthink = time;
+
- if (vlen(self.origin - self.tur_shotorg) < 100 )
- {
- self.think = walker_rocket_think;
- return;
- }
++ if (self.max_health < time)
++ {
++ self.think = walker_rocket_explode;
++ return;
++ }
+
- newdir = steerlib_pull(self.tur_shotorg);
- WALKER_ROCKET_MOVE;
++ if (vlen(self.origin - self.tur_shotorg) < 100 )
++ {
++ self.think = walker_rocket_think;
++ return;
++ }
+
- self.angles = vectoangles(self.velocity);
++ newdir = steerlib_pull(self.tur_shotorg);
++ WALKER_ROCKET_MOVE;
+
- vector newdir;
++ self.angles = vectoangles(self.velocity);
+}
+
+void walker_rocket_loop2()
+{
- self.nextthink = time;
++ vector newdir;
+
- if (self.max_health < time)
- {
- self.think = walker_rocket_explode;
- return;
- }
++ self.nextthink = time;
+
- if (vlen(self.origin - self.tur_shotorg) < 100 )
- {
- self.tur_shotorg = self.origin - '0 0 200';
- self.think = walker_rocket_loop3;
- return;
- }
++ if (self.max_health < time)
++ {
++ self.think = walker_rocket_explode;
++ return;
++ }
+
- newdir = steerlib_pull(self.tur_shotorg);
- WALKER_ROCKET_MOVE;
++ if (vlen(self.origin - self.tur_shotorg) < 100 )
++ {
++ self.tur_shotorg = self.origin - '0 0 200';
++ self.think = walker_rocket_loop3;
++ return;
++ }
+
- self.nextthink = time;
- self.tur_shotorg = self.origin + '0 0 300';
- self.think = walker_rocket_loop2;
- self.shot_dmg = 1337;
++ newdir = steerlib_pull(self.tur_shotorg);
++ WALKER_ROCKET_MOVE;
+}
+
+void walker_rocket_loop()
+{
- entity rocket;
-
- fixedmakevectors(self.angles);
-
- te_explosion (org);
-
- rocket = spawn ();
- setorigin(rocket, org);
-
- sound (self, CH_WEAPON_A, "weapons/hagar_fire.wav", VOL_BASE, ATTEN_NORM);
- setsize (rocket, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
-
- rocket.classname = "walker_rocket";
- rocket.owner = self;
- rocket.bot_dodge = true;
- rocket.bot_dodgerating = 50;
- rocket.takedamage = DAMAGE_YES;
- rocket.damageforcescale = 2;
- rocket.health = 25;
- rocket.tur_shotorg = randomvec() * 512;
- rocket.cnt = time + 1;
- rocket.enemy = self.enemy;
-
- if (random() < 0.01)
- rocket.think = walker_rocket_loop;
- else
- rocket.think = walker_rocket_think;
-
- rocket.event_damage = walker_rocket_damage;
-
- rocket.nextthink = time;
- rocket.movetype = MOVETYPE_FLY;
- rocket.velocity = normalize((v_forward + v_up * 0.5) + (randomvec() * 0.2)) * (autocvar_g_turrets_unit_walker_rocket_speed);
- rocket.angles = vectoangles(rocket.velocity);
- rocket.touch = walker_rocket_explode;
- rocket.flags = FL_PROJECTILE;
- rocket.solid = SOLID_BBOX;
- rocket.max_health = time + 9;
- rocket.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_GUIDED_HEAT;
-
- CSQCProjectile(rocket, false, PROJECTILE_ROCKET, false); // no culling, has fly sound
++ self.nextthink = time;
++ self.tur_shotorg = self.origin + '0 0 300';
++ self.think = walker_rocket_loop2;
++ self.shot_dmg = 1337;
+}
+
+void walker_fire_rocket(vector org)
+{
- switch (self.waterlevel)
- {
- case WATERLEVEL_NONE:
- if (_dist > 500)
- self.animflag = ANIM_RUN;
- else
- self.animflag = ANIM_WALK;
- case WATERLEVEL_WETFEET:
- case WATERLEVEL_SWIMMING:
- if (self.animflag != ANIM_SWIM)
- self.animflag = ANIM_WALK;
- else
- self.animflag = ANIM_SWIM;
- break;
- case WATERLEVEL_SUBMERGED:
- self.animflag = ANIM_SWIM;
- }
-
- self.moveto = _target;
- self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
-
- if(self.enemy)
- {
- self.enemy_last_loc = _target;
- self.enemy_last_time = time;
- }
++ entity rocket;
++
++ fixedmakevectors(self.angles);
++
++ te_explosion (org);
++
++ rocket = spawn ();
++ setorigin(rocket, org);
++
++ sound (self, CH_WEAPON_A, "weapons/hagar_fire.wav", VOL_BASE, ATTEN_NORM);
++ setsize (rocket, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
++
++ rocket.classname = "walker_rocket";
++ rocket.owner = self;
++ rocket.bot_dodge = true;
++ rocket.bot_dodgerating = 50;
++ rocket.takedamage = DAMAGE_YES;
++ rocket.damageforcescale = 2;
++ rocket.health = 25;
++ rocket.tur_shotorg = randomvec() * 512;
++ rocket.cnt = time + 1;
++ rocket.enemy = self.enemy;
++
++ if (random() < 0.01)
++ rocket.think = walker_rocket_loop;
++ else
++ rocket.think = walker_rocket_think;
++
++ rocket.event_damage = walker_rocket_damage;
++
++ rocket.nextthink = time;
++ rocket.movetype = MOVETYPE_FLY;
++ rocket.velocity = normalize((v_forward + v_up * 0.5) + (randomvec() * 0.2)) * (autocvar_g_turrets_unit_walker_rocket_speed);
++ rocket.angles = vectoangles(rocket.velocity);
++ rocket.touch = walker_rocket_explode;
++ rocket.flags = FL_PROJECTILE;
++ rocket.solid = SOLID_BBOX;
++ rocket.max_health = time + 9;
++ rocket.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_GUIDED_HEAT;
++
++ CSQCProjectile(rocket, false, PROJECTILE_ROCKET, false); // no culling, has fly sound
+}
+
+.vector enemy_last_loc;
+.float enemy_last_time;
+void walker_move_to(vector _target, float _dist)
+{
- // Are we close enougth to a path node to switch to the next?
- if (vlen(self.origin - self.pathcurrent.origin) < 64)
- if (self.pathcurrent.path_next == world)
- {
- // Path endpoint reached
- pathlib_deletepath(self.pathcurrent.owner);
- self.pathcurrent = world;
-
- if (self.pathgoal)
- {
- if (self.pathgoal.use)
- self.pathgoal.use();
-
- if (self.pathgoal.enemy)
- {
- self.pathcurrent = WALKER_PATH(self.pathgoal.origin,self.pathgoal.enemy.origin);
- self.pathgoal = self.pathgoal.enemy;
- }
- }
- else
- self.pathgoal = world;
- }
- else
- self.pathcurrent = self.pathcurrent.path_next;
-
- self.moveto = self.pathcurrent.origin;
- self.steerto = steerlib_attract2(self.moveto,0.5,500,0.95);
- walker_move_to(self.moveto, 0);
++ switch (self.waterlevel)
++ {
++ case WATERLEVEL_NONE:
++ if (_dist > 500)
++ self.animflag = ANIM_RUN;
++ else
++ self.animflag = ANIM_WALK;
++ case WATERLEVEL_WETFEET:
++ case WATERLEVEL_SWIMMING:
++ if (self.animflag != ANIM_SWIM)
++ self.animflag = ANIM_WALK;
++ else
++ self.animflag = ANIM_SWIM;
++ break;
++ case WATERLEVEL_SUBMERGED:
++ self.animflag = ANIM_SWIM;
++ }
++
++ self.moveto = _target;
++ self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
++
++ if(self.enemy)
++ {
++ self.enemy_last_loc = _target;
++ self.enemy_last_time = time;
++ }
+}
+
+//#define WALKER_FANCYPATHING
+
+void walker_move_path()
+{
+#ifdef WALKER_FANCYPATHING
- if (vlen(self.origin - self.pathcurrent.origin) < 64)
- self.pathcurrent = self.pathcurrent.enemy;
++ // Are we close enougth to a path node to switch to the next?
++ if (vlen(self.origin - self.pathcurrent.origin) < 64)
++ if (self.pathcurrent.path_next == world)
++ {
++ // Path endpoint reached
++ pathlib_deletepath(self.pathcurrent.owner);
++ self.pathcurrent = world;
++
++ if (self.pathgoal)
++ {
++ if (self.pathgoal.use)
++ self.pathgoal.use();
++
++ if (self.pathgoal.enemy)
++ {
++ self.pathcurrent = WALKER_PATH(self.pathgoal.origin,self.pathgoal.enemy.origin);
++ self.pathgoal = self.pathgoal.enemy;
++ }
++ }
++ else
++ self.pathgoal = world;
++ }
++ else
++ self.pathcurrent = self.pathcurrent.path_next;
++
++ self.moveto = self.pathcurrent.origin;
++ self.steerto = steerlib_attract2(self.moveto,0.5,500,0.95);
++ walker_move_to(self.moveto, 0);
+
+#else
- if(!self.pathcurrent)
- return;
++ if (vlen(self.origin - self.pathcurrent.origin) < 64)
++ self.pathcurrent = self.pathcurrent.enemy;
+
- self.moveto = self.pathcurrent.origin;
- self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
- walker_move_to(self.moveto, 0);
++ if(!self.pathcurrent)
++ return;
+
- switch(req)
- {
- case TR_ATTACK:
- {
- sound (self, CH_WEAPON_A, "weapons/uzi_fire.wav", VOL_BASE, ATTEN_NORM);
- fireBullet (self.tur_shotorg, self.tur_shotdir_updated, self.shot_spread, 0, self.shot_dmg, self.shot_force, DEATH_TURRET_WALK_GUN, 0);
- pointparticles(particleeffectnum("laser_muzzleflash"), self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
-
- return true;
- }
- case TR_THINK:
- {
- fixedmakevectors(self.angles);
-
- if (self.spawnflags & TSF_NO_PATHBREAK && self.pathcurrent)
- walker_move_path();
- else if (self.enemy == world)
- {
- if(self.pathcurrent)
- walker_move_path();
- else
- {
- if(self.enemy_last_time != 0)
- {
- if(vlen(self.origin - self.enemy_last_loc) < 128 || time - self.enemy_last_time > 10)
- self.enemy_last_time = 0;
- else
- walker_move_to(self.enemy_last_loc, 0);
- }
- else
- {
- if(self.animflag != ANIM_NO)
- {
- traceline(self.origin + '0 0 64', self.origin + '0 0 64' + v_forward * 128, MOVE_NORMAL, self);
-
- if(trace_fraction != 1.0)
- self.tur_head.idletime = -1337;
- else
- {
- traceline(trace_endpos, trace_endpos - '0 0 256', MOVE_NORMAL, self);
- if(trace_fraction == 1.0)
- self.tur_head.idletime = -1337;
- }
-
- if(self.tur_head.idletime == -1337)
- {
- self.moveto = self.origin + randomvec() * 256;
- self.tur_head.idletime = 0;
- }
-
- self.moveto = self.moveto * 0.9 + ((self.origin + v_forward * 500) + randomvec() * 400) * 0.1;
- self.moveto_z = self.origin_z + 64;
- walker_move_to(self.moveto, 0);
- }
-
- if(self.idletime < time)
- {
- if(random() < 0.5 || !(self.spawnflags & TSL_ROAM))
- {
- self.idletime = time + 1 + random() * 5;
- self.moveto = self.origin;
- self.animflag = ANIM_NO;
- }
- else
- {
- self.animflag = ANIM_WALK;
- self.idletime = time + 4 + random() * 2;
- self.moveto = self.origin + randomvec() * 256;
- self.tur_head.moveto = self.moveto;
- self.tur_head.idletime = 0;
- }
- }
- }
- }
- }
- else
- {
- if (self.tur_dist_enemy < (autocvar_g_turrets_unit_walker_melee_range) && self.animflag != ANIM_MELEE)
- {
- vector wish_angle;
-
- wish_angle = angleofs(self, self.enemy);
- if (self.animflag != ANIM_SWIM)
- if (fabs(wish_angle_y) < 15)
- {
- self.moveto = self.enemy.origin;
- self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
- self.animflag = ANIM_MELEE;
- }
- }
- else if (self.tur_head.attack_finished_single < time)
- {
- if(self.tur_head.shot_volly)
- {
- self.animflag = ANIM_NO;
-
- self.tur_head.shot_volly = self.tur_head.shot_volly -1;
- if(self.tur_head.shot_volly == 0)
- self.tur_head.attack_finished_single = time + (autocvar_g_turrets_unit_walker_rocket_refire);
- else
- self.tur_head.attack_finished_single = time + 0.2;
-
- if(self.tur_head.shot_volly > 1)
- walker_fire_rocket(gettaginfo(self, gettagindex(self, "tag_rocket01")));
- else
- walker_fire_rocket(gettaginfo(self, gettagindex(self, "tag_rocket02")));
- }
- else
- {
- if (self.tur_dist_enemy > (autocvar_g_turrets_unit_walker_rocket_range_min))
- if (self.tur_dist_enemy < (autocvar_g_turrets_unit_walker_rocket_range))
- self.tur_head.shot_volly = 4;
- }
- }
- else
- {
- if (self.animflag != ANIM_MELEE)
- walker_move_to(self.enemy.origin, self.tur_dist_enemy);
- }
- }
-
- {
- vector real_angle;
- float turny = 0, turnx = 0;
- float vz;
-
- real_angle = vectoangles(self.steerto) - self.angles;
- vz = self.velocity_z;
-
- switch (self.animflag)
- {
- case ANIM_NO:
- movelib_beak_simple((autocvar_g_turrets_unit_walker_speed_stop));
- break;
-
- case ANIM_TURN:
- turny = (autocvar_g_turrets_unit_walker_turn);
- movelib_beak_simple((autocvar_g_turrets_unit_walker_speed_stop));
- break;
-
- case ANIM_WALK:
- turny = (autocvar_g_turrets_unit_walker_turn_walk);
- movelib_move_simple(v_forward, (autocvar_g_turrets_unit_walker_speed_walk), 0.6);
- break;
-
- case ANIM_RUN:
- turny = (autocvar_g_turrets_unit_walker_turn_run);
- movelib_move_simple(v_forward, (autocvar_g_turrets_unit_walker_speed_run), 0.6);
- break;
-
- case ANIM_STRAFE_L:
- turny = (autocvar_g_turrets_unit_walker_turn_strafe);
- movelib_move_simple(v_right * -1, (autocvar_g_turrets_unit_walker_speed_walk), 0.8);
- break;
-
- case ANIM_STRAFE_R:
- turny = (autocvar_g_turrets_unit_walker_turn_strafe);
- movelib_move_simple(v_right, (autocvar_g_turrets_unit_walker_speed_walk), 0.8);
- break;
-
- case ANIM_JUMP:
- self.velocity += '0 0 1' * (autocvar_g_turrets_unit_walker_speed_jump);
- break;
-
- case ANIM_LAND:
- break;
-
- case ANIM_PAIN:
- if(self.frame != ANIM_PAIN)
- defer(0.25, walker_setnoanim);
-
- break;
-
- case ANIM_MELEE:
- if(self.frame != ANIM_MELEE)
- {
- defer(0.41, walker_setnoanim);
- defer(0.21, walker_melee_do_dmg);
- }
-
- movelib_beak_simple((autocvar_g_turrets_unit_walker_speed_stop));
- break;
-
- case ANIM_SWIM:
- turny = (autocvar_g_turrets_unit_walker_turn_swim);
- turnx = (autocvar_g_turrets_unit_walker_turn_swim);
-
- self.angles_x += bound(-10, shortangle_f(real_angle_x, self.angles_x), 10);
- movelib_move_simple(v_forward, (autocvar_g_turrets_unit_walker_speed_swim), 0.3);
- vz = self.velocity_z + sin(time * 4) * 8;
- break;
-
- case ANIM_ROAM:
- turny = (autocvar_g_turrets_unit_walker_turn_walk);
- movelib_move_simple(v_forward ,(autocvar_g_turrets_unit_walker_speed_roam), 0.5);
- break;
- }
-
- if(turny)
- {
- turny = bound( turny * -1, shortangle_f(real_angle_y, self.angles_y), turny );
- self.angles_y += turny;
- }
-
- if(turnx)
- {
- turnx = bound( turnx * -1, shortangle_f(real_angle_x, self.angles_x), turnx );
- self.angles_x += turnx;
- }
-
- self.velocity_z = vz;
- }
-
-
- if(self.origin != self.oldorigin)
- self.SendFlags |= TNSF_MOVE;
-
- self.oldorigin = self.origin;
- turrets_setframe(self.animflag, false);
-
- return true;
- }
- case TR_DEATH:
- {
++ self.moveto = self.pathcurrent.origin;
++ self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
++ walker_move_to(self.moveto, 0);
+#endif
+}
+
+void spawnfunc_turret_walker() { if(!turret_initialize(TUR_WALKER)) remove(self); }
+
+float t_walker(float req)
+{
- if (self.pathcurrent)
- pathlib_deletepath(self.pathcurrent.owner);
++ switch(req)
++ {
++ case TR_ATTACK:
++ {
++ sound (self, CH_WEAPON_A, "weapons/uzi_fire.wav", VOL_BASE, ATTEN_NORM);
++ fireBullet (self.tur_shotorg, self.tur_shotdir_updated, self.shot_spread, 0, self.shot_dmg, self.shot_force, DEATH_TURRET_WALK_GUN, 0);
++ Send_Effect("laser_muzzleflash", self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
++
++ return true;
++ }
++ case TR_THINK:
++ {
++ fixedmakevectors(self.angles);
++
++ if (self.spawnflags & TSF_NO_PATHBREAK && self.pathcurrent)
++ walker_move_path();
++ else if (self.enemy == world)
++ {
++ if(self.pathcurrent)
++ walker_move_path();
++ else
++ {
++ if(self.enemy_last_time != 0)
++ {
++ if(vlen(self.origin - self.enemy_last_loc) < 128 || time - self.enemy_last_time > 10)
++ self.enemy_last_time = 0;
++ else
++ walker_move_to(self.enemy_last_loc, 0);
++ }
++ else
++ {
++ if(self.animflag != ANIM_NO)
++ {
++ traceline(self.origin + '0 0 64', self.origin + '0 0 64' + v_forward * 128, MOVE_NORMAL, self);
++
++ if(trace_fraction != 1.0)
++ self.tur_head.idletime = -1337;
++ else
++ {
++ traceline(trace_endpos, trace_endpos - '0 0 256', MOVE_NORMAL, self);
++ if(trace_fraction == 1.0)
++ self.tur_head.idletime = -1337;
++ }
++
++ if(self.tur_head.idletime == -1337)
++ {
++ self.moveto = self.origin + randomvec() * 256;
++ self.tur_head.idletime = 0;
++ }
++
++ self.moveto = self.moveto * 0.9 + ((self.origin + v_forward * 500) + randomvec() * 400) * 0.1;
++ self.moveto_z = self.origin_z + 64;
++ walker_move_to(self.moveto, 0);
++ }
++
++ if(self.idletime < time)
++ {
++ if(random() < 0.5 || !(self.spawnflags & TSL_ROAM))
++ {
++ self.idletime = time + 1 + random() * 5;
++ self.moveto = self.origin;
++ self.animflag = ANIM_NO;
++ }
++ else
++ {
++ self.animflag = ANIM_WALK;
++ self.idletime = time + 4 + random() * 2;
++ self.moveto = self.origin + randomvec() * 256;
++ self.tur_head.moveto = self.moveto;
++ self.tur_head.idletime = 0;
++ }
++ }
++ }
++ }
++ }
++ else
++ {
++ if (self.tur_dist_enemy < (autocvar_g_turrets_unit_walker_melee_range) && self.animflag != ANIM_MELEE)
++ {
++ vector wish_angle;
++
++ wish_angle = angleofs(self, self.enemy);
++ if (self.animflag != ANIM_SWIM)
++ if (fabs(wish_angle_y) < 15)
++ {
++ self.moveto = self.enemy.origin;
++ self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
++ self.animflag = ANIM_MELEE;
++ }
++ }
++ else if (self.tur_head.attack_finished_single < time)
++ {
++ if(self.tur_head.shot_volly)
++ {
++ self.animflag = ANIM_NO;
++
++ self.tur_head.shot_volly = self.tur_head.shot_volly -1;
++ if(self.tur_head.shot_volly == 0)
++ self.tur_head.attack_finished_single = time + (autocvar_g_turrets_unit_walker_rocket_refire);
++ else
++ self.tur_head.attack_finished_single = time + 0.2;
++
++ if(self.tur_head.shot_volly > 1)
++ walker_fire_rocket(gettaginfo(self, gettagindex(self, "tag_rocket01")));
++ else
++ walker_fire_rocket(gettaginfo(self, gettagindex(self, "tag_rocket02")));
++ }
++ else
++ {
++ if (self.tur_dist_enemy > (autocvar_g_turrets_unit_walker_rocket_range_min))
++ if (self.tur_dist_enemy < (autocvar_g_turrets_unit_walker_rocket_range))
++ self.tur_head.shot_volly = 4;
++ }
++ }
++ else
++ {
++ if (self.animflag != ANIM_MELEE)
++ walker_move_to(self.enemy.origin, self.tur_dist_enemy);
++ }
++ }
++
++ {
++ vector real_angle;
++ float turny = 0, turnx = 0;
++ float vz;
++
++ real_angle = vectoangles(self.steerto) - self.angles;
++ vz = self.velocity_z;
++
++ switch (self.animflag)
++ {
++ case ANIM_NO:
++ movelib_beak_simple((autocvar_g_turrets_unit_walker_speed_stop));
++ break;
++
++ case ANIM_TURN:
++ turny = (autocvar_g_turrets_unit_walker_turn);
++ movelib_beak_simple((autocvar_g_turrets_unit_walker_speed_stop));
++ break;
++
++ case ANIM_WALK:
++ turny = (autocvar_g_turrets_unit_walker_turn_walk);
++ movelib_move_simple(v_forward, (autocvar_g_turrets_unit_walker_speed_walk), 0.6);
++ break;
++
++ case ANIM_RUN:
++ turny = (autocvar_g_turrets_unit_walker_turn_run);
++ movelib_move_simple(v_forward, (autocvar_g_turrets_unit_walker_speed_run), 0.6);
++ break;
++
++ case ANIM_STRAFE_L:
++ turny = (autocvar_g_turrets_unit_walker_turn_strafe);
++ movelib_move_simple(v_right * -1, (autocvar_g_turrets_unit_walker_speed_walk), 0.8);
++ break;
++
++ case ANIM_STRAFE_R:
++ turny = (autocvar_g_turrets_unit_walker_turn_strafe);
++ movelib_move_simple(v_right, (autocvar_g_turrets_unit_walker_speed_walk), 0.8);
++ break;
++
++ case ANIM_JUMP:
++ self.velocity += '0 0 1' * (autocvar_g_turrets_unit_walker_speed_jump);
++ break;
++
++ case ANIM_LAND:
++ break;
++
++ case ANIM_PAIN:
++ if(self.frame != ANIM_PAIN)
++ defer(0.25, walker_setnoanim);
++
++ break;
++
++ case ANIM_MELEE:
++ if(self.frame != ANIM_MELEE)
++ {
++ defer(0.41, walker_setnoanim);
++ defer(0.21, walker_melee_do_dmg);
++ }
++
++ movelib_beak_simple((autocvar_g_turrets_unit_walker_speed_stop));
++ break;
++
++ case ANIM_SWIM:
++ turny = (autocvar_g_turrets_unit_walker_turn_swim);
++ turnx = (autocvar_g_turrets_unit_walker_turn_swim);
++
++ self.angles_x += bound(-10, shortangle_f(real_angle_x, self.angles_x), 10);
++ movelib_move_simple(v_forward, (autocvar_g_turrets_unit_walker_speed_swim), 0.3);
++ vz = self.velocity_z + sin(time * 4) * 8;
++ break;
++
++ case ANIM_ROAM:
++ turny = (autocvar_g_turrets_unit_walker_turn_walk);
++ movelib_move_simple(v_forward ,(autocvar_g_turrets_unit_walker_speed_roam), 0.5);
++ break;
++ }
++
++ if(turny)
++ {
++ turny = bound( turny * -1, shortangle_f(real_angle_y, self.angles_y), turny );
++ self.angles_y += turny;
++ }
++
++ if(turnx)
++ {
++ turnx = bound( turnx * -1, shortangle_f(real_angle_x, self.angles_x), turnx );
++ self.angles_x += turnx;
++ }
++
++ self.velocity_z = vz;
++ }
++
++
++ if(self.origin != self.oldorigin)
++ self.SendFlags |= TNSF_MOVE;
++
++ self.oldorigin = self.origin;
++ turrets_setframe(self.animflag, false);
++
++ return true;
++ }
++ case TR_DEATH:
++ {
+#ifdef WALKER_FANCYPATHING
- self.pathcurrent = world;
-
- return true;
- }
- case TR_SETUP:
- {
- self.ticrate = 0.05;
-
- entity e;
-
- // Respawn is called & first spawn to, to set team. need to make sure we do not move the initial spawn.
- if(self.movetype == MOVETYPE_WALK)
- {
- if(self.pos1)
- setorigin(self, self.pos1);
- if(self.pos2)
- self.angles = self.pos2;
- }
-
- self.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
- self.aim_flags = TFL_AIM_LEAD;
- self.turret_flags |= TUR_FLAG_HITSCAN;
-
- self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
- self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
- self.iscreature = true;
- self.teleportable = TELEPORT_NORMAL;
- self.damagedbycontents = true;
- self.solid = SOLID_SLIDEBOX;
- self.takedamage = DAMAGE_AIM;
- if(self.movetype != MOVETYPE_WALK)
- {
- setorigin(self, self.origin);
- tracebox(self.origin + '0 0 128', self.mins, self.maxs, self.origin - '0 0 10000', MOVE_NORMAL, self);
- setorigin(self, trace_endpos + '0 0 4');
- self.pos1 = self.origin;
- self.pos2 = self.angles;
- }
- self.movetype = MOVETYPE_WALK;
- self.idle_aim = '0 0 0';
- self.turret_firecheckfunc = walker_firecheck;
-
- if (self.target != "")
- {
- e = find(world, targetname, self.target);
- if (!e)
- {
- dprint("Initital waypoint for walker does NOT exsist, fix your map!\n");
- self.target = "";
- }
-
- if (e.classname != "turret_checkpoint")
- dprint("Warning: not a turrret path\n");
- else
- {
++ if (self.pathcurrent)
++ pathlib_deletepath(self.pathcurrent.owner);
+#endif
- self.pathcurrent = WALKER_PATH(self.origin, e.origin);
- self.pathgoal = e;
++ self.pathcurrent = world;
++
++ return true;
++ }
++ case TR_SETUP:
++ {
++ self.ticrate = 0.05;
++
++ entity e;
++
++ // Respawn is called & first spawn to, to set team. need to make sure we do not move the initial spawn.
++ if(self.movetype == MOVETYPE_WALK)
++ {
++ if(self.pos1)
++ setorigin(self, self.pos1);
++ if(self.pos2)
++ self.angles = self.pos2;
++ }
++
++ self.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
++ self.aim_flags = TFL_AIM_LEAD;
++ self.turret_flags |= TUR_FLAG_HITSCAN;
++
++ self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
++ self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
++ self.iscreature = true;
++ self.teleportable = TELEPORT_NORMAL;
++ self.damagedbycontents = true;
++ self.solid = SOLID_SLIDEBOX;
++ self.takedamage = DAMAGE_AIM;
++ if(self.movetype != MOVETYPE_WALK)
++ {
++ setorigin(self, self.origin);
++ tracebox(self.origin + '0 0 128', self.mins, self.maxs, self.origin - '0 0 10000', MOVE_NORMAL, self);
++ setorigin(self, trace_endpos + '0 0 4');
++ self.pos1 = self.origin;
++ self.pos2 = self.angles;
++ }
++ self.movetype = MOVETYPE_WALK;
++ self.idle_aim = '0 0 0';
++ self.turret_firecheckfunc = walker_firecheck;
++
++ if (self.target != "")
++ {
++ e = find(world, targetname, self.target);
++ if (!e)
++ {
++ dprint("Initital waypoint for walker does NOT exsist, fix your map!\n");
++ self.target = "";
++ }
++
++ if (e.classname != "turret_checkpoint")
++ dprint("Warning: not a turrret path\n");
++ else
++ {
+#ifdef WALKER_FANCYPATHING
- self.pathcurrent = e;
++ self.pathcurrent = WALKER_PATH(self.origin, e.origin);
++ self.pathgoal = e;
+#else
- }
- }
-
- return true;
- }
- case TR_PRECACHE:
- {
- precache_model ("models/turrets/walker_body.md3");
- precache_model ("models/turrets/walker_head_minigun.md3");
- precache_model ("models/turrets/rocket.md3");
- precache_sound ("weapons/rocket_impact.wav");
- return true;
- }
- }
-
- return true;
++ self.pathcurrent = e;
+#endif
- float dt;
-
- dt = time - self.move_time;
- self.move_time = time;
- if(dt <= 0)
- return;
-
- fixedmakevectors(self.angles);
- movelib_groundalign4point(300, 100, 0.25, 45);
- setorigin(self, self.origin + self.velocity * dt);
- self.tur_head.angles += dt * self.tur_head.move_avelocity;
- self.angles_y = self.move_angles_y;
-
- if (self.health < 127)
- if(random() < 0.15)
- te_spark(self.origin + '0 0 40', randomvec() * 256 + '0 0 256', 16);
++ }
++ }
++
++ return true;
++ }
++ case TR_PRECACHE:
++ {
++ precache_model ("models/turrets/walker_body.md3");
++ precache_model ("models/turrets/walker_head_minigun.md3");
++ precache_model ("models/turrets/rocket.md3");
++ precache_sound ("weapons/rocket_impact.wav");
++ return true;
++ }
++ }
++
++ return true;
+}
+
+#endif // SVQC
+#ifdef CSQC
+
+#include "../../../server/movelib.qh"
+
+void walker_draw()
+{
- switch(req)
- {
- case TR_SETUP:
- {
- self.gravity = 1;
- self.movetype = MOVETYPE_BOUNCE;
- self.move_movetype = MOVETYPE_BOUNCE;
- self.move_origin = self.origin;
- self.move_time = time;
- self.draw = walker_draw;
-
- return true;
- }
- case TR_PRECACHE:
- {
- return true;
- }
- }
-
- return true;
++ float dt;
++
++ dt = time - self.move_time;
++ self.move_time = time;
++ if(dt <= 0)
++ return;
++
++ fixedmakevectors(self.angles);
++ movelib_groundalign4point(300, 100, 0.25, 45);
++ setorigin(self, self.origin + self.velocity * dt);
++ self.tur_head.angles += dt * self.tur_head.move_avelocity;
++ self.angles_y = self.move_angles_y;
++
++ if (self.health < 127)
++ if(random() < 0.15)
++ te_spark(self.origin + '0 0 40', randomvec() * 256 + '0 0 256', 16);
+}
+
+float t_walker(float req)
+{
++ switch(req)
++ {
++ case TR_SETUP:
++ {
++ self.gravity = 1;
++ self.movetype = MOVETYPE_BOUNCE;
++ self.move_movetype = MOVETYPE_BOUNCE;
++ self.move_origin = self.origin;
++ self.move_time = time;
++ self.draw = walker_draw;
++
++ return true;
++ }
++ case TR_PRECACHE:
++ {
++ return true;
++ }
++ }
++
++ return true;
+}
+
+#endif // CSQC
+#endif // REGISTER_TURRET
--- /dev/null
- float bforce, float f_dmg, float f_velfactor, float deathtype)
+/*
+* Return a angle within +/- 360.
+*/
+float anglemods(float v)
+{
+ v = v - 360 * floor(v / 360);
+
+ if(v >= 180)
+ return v - 360;
+ else if(v <= -180)
+ return v + 360;
+ else
+ return v;
+}
+
+/*
+* Return the short angle
+*/
+float shortangle_f(float ang1, float ang2)
+{
+ if(ang1 > ang2)
+ {
+ if(ang1 > 180)
+ return ang1 - 360;
+ }
+ else
+ {
+ if(ang1 < -180)
+ return ang1 + 360;
+ }
+
+ return ang1;
+}
+
+vector shortangle_v(vector ang1, vector ang2)
+{
+ vector vtmp;
+
+ vtmp_x = shortangle_f(ang1_x,ang2_x);
+ vtmp_y = shortangle_f(ang1_y,ang2_y);
+ vtmp_z = shortangle_f(ang1_z,ang2_z);
+
+ return vtmp;
+}
+
+vector shortangle_vxy(vector ang1, vector ang2)
+{
+ vector vtmp = '0 0 0';
+
+ vtmp_x = shortangle_f(ang1_x,ang2_x);
+ vtmp_y = shortangle_f(ang1_y,ang2_y);
+
+ return vtmp;
+}
+
+
+/*
+* Get "real" origin, in worldspace, even if ent is attached to something else.
+*/
+vector real_origin(entity ent)
+{
+ entity e;
+ vector v = ((ent.absmin + ent.absmax) * 0.5);
+
+ e = ent.tag_entity;
+ while(e)
+ {
+ v = v + ((e.absmin + e.absmax) * 0.5);
+ e = e.tag_entity;
+ }
+
+ return v;
+}
+
+/*
+* Return the angle between two enteties
+*/
+vector angleofs(entity from, entity to)
+{
+ vector v_res;
+
+ v_res = normalize(to.origin - from.origin);
+ v_res = vectoangles(v_res);
+ v_res = v_res - from.angles;
+
+ if (v_res_x < 0) v_res_x += 360;
+ if (v_res_x > 180) v_res_x -= 360;
+
+ if (v_res_y < 0) v_res_y += 360;
+ if (v_res_y > 180) v_res_y -= 360;
+
+ return v_res;
+}
+
+vector angleofs3(vector from, vector from_a, entity to)
+{
+ vector v_res;
+
+ v_res = normalize(to.origin - from);
+ v_res = vectoangles(v_res);
+ v_res = v_res - from_a;
+
+ if (v_res_x < 0) v_res_x += 360;
+ if (v_res_x > 180) v_res_x -= 360;
+
+ if (v_res_y < 0) v_res_y += 360;
+ if (v_res_y > 180) v_res_y -= 360;
+
+ return v_res;
+}
+
+/*
+* Update self.tur_shotorg by getting up2date bone info
+* NOTICE this func overwrites the global v_forward, v_right and v_up vectors.
+*/
+float turret_tag_fire_update()
+{
+ if(!self.tur_head)
+ {
+ error("Call to turret_tag_fire_update with self.tur_head missing!\n");
+ self.tur_shotorg = '0 0 0';
+ return false;
+ }
+
+ self.tur_shotorg = gettaginfo(self.tur_head, gettagindex(self.tur_head, "tag_fire"));
+ v_forward = normalize(v_forward);
+
+ return true;
+}
+
+/*
+* Railgun-like beam, but has thickness and suppots slowing of target
+*/
+void FireImoBeam (vector start, vector end, vector smin, vector smax,
++ float bforce, float f_dmg, float f_velfactor, int deathtype)
+
+{
+ vector hitloc, force, endpoint, dir;
+ entity ent;
+
+ dir = normalize(end - start);
+ force = dir * bforce;
+
+ // go a little bit into the wall because we need to hit this wall later
+ end = end + dir;
+
+ // trace multiple times until we hit a wall, each obstacle will be made unsolid.
+ // note down which entities were hit so we can damage them later
+ while (1)
+ {
+ tracebox(start, smin, smax, end, false, self);
+
+ // if it is world we can't hurt it so stop now
+ if (trace_ent == world || trace_fraction == 1)
+ break;
+
+ if (trace_ent.solid == SOLID_BSP)
+ break;
+
+ // make the entity non-solid so we can hit the next one
+ trace_ent.railgunhit = true;
+ trace_ent.railgunhitloc = end;
+ trace_ent.railgunhitsolidbackup = trace_ent.solid;
+
+ // stop if this is a wall
+
+ // make the entity non-solid
+ trace_ent.solid = SOLID_NOT;
+ }
+
+ endpoint = trace_endpos;
+
+ // find all the entities the railgun hit and restore their solid state
+ ent = findfloat(world, railgunhit, true);
+ while (ent)
+ {
+ // restore their solid type
+ ent.solid = ent.railgunhitsolidbackup;
+ ent = findfloat(ent, railgunhit, true);
+ }
+
+ // find all the entities the railgun hit and hurt them
+ ent = findfloat(world, railgunhit, true);
+ while (ent)
+ {
+ // get the details we need to call the damage function
+ hitloc = ent.railgunhitloc;
+ ent.railgunhitloc = '0 0 0';
+ ent.railgunhitsolidbackup = SOLID_NOT;
+ ent.railgunhit = false;
+
+ // apply the damage
+ if (ent.takedamage)
+ {
+ Damage (ent, self, self, f_dmg, deathtype, hitloc, force);
+ ent.velocity = ent.velocity * f_velfactor;
+ //ent.alpha = 0.25 + random() * 0.75;
+ }
+
+ // advance to the next entity
+ ent = findfloat(ent, railgunhit, true);
+ }
+ trace_endpos = endpoint;
+}
+
+#ifdef TURRET_DEBUG
+void SUB_Remove();
+void marker_think()
+{
+ if(self.cnt)
+ if(self.cnt < time)
+ {
+ self.think = SUB_Remove;
+ self.nextthink = time;
+ return;
+ }
+
+ self.frame += 1;
+ if(self.frame > 29)
+ self.frame = 0;
+
+ self.nextthink = time;
+}
+
+void mark_error(vector where,float lifetime)
+{
+ entity err;
+
+ err = spawn();
+ err.classname = "error_marker";
+ setmodel(err,"models/marker.md3");
+ setorigin(err,where);
+ err.movetype = MOVETYPE_NONE;
+ err.think = marker_think;
+ err.nextthink = time;
+ err.skin = 0;
+ if(lifetime)
+ err.cnt = lifetime + time;
+}
+
+void mark_info(vector where,float lifetime)
+{
+ entity err;
+
+ err = spawn();
+ err.classname = "info_marker";
+ setmodel(err,"models/marker.md3");
+ setorigin(err,where);
+ err.movetype = MOVETYPE_NONE;
+ err.think = marker_think;
+ err.nextthink = time;
+ err.skin = 1;
+ if(lifetime)
+ err.cnt = lifetime + time;
+}
+
+entity mark_misc(vector where,float lifetime)
+{
+ entity err;
+
+ err = spawn();
+ err.classname = "mark_misc";
+ setmodel(err,"models/marker.md3");
+ setorigin(err,where);
+ err.movetype = MOVETYPE_NONE;
+ err.think = marker_think;
+ err.nextthink = time;
+ err.skin = 3;
+ if(lifetime)
+ err.cnt = lifetime + time;
+ return err;
+}
+
+/*
+* Paint a v_color colord circle on target onwho
+* that fades away over f_time
+*/
+void paint_target(entity onwho, float f_size, vector v_color, float f_time)
+{
+ entity e;
+
+ e = spawn();
+ setmodel(e, "models/turrets/c512.md3"); // precision set above
+ e.scale = (f_size/512);
+ //setsize(e, '0 0 0', '0 0 0');
+ //setattachment(e,onwho,"");
+ setorigin(e,onwho.origin + '0 0 1');
+ e.alpha = 0.15;
+ e.movetype = MOVETYPE_FLY;
+
+ e.velocity = (v_color * 32); // + '0 0 1' * 64;
+
+ e.colormod = v_color;
+ SUB_SetFade(e,time,f_time);
+}
+
+void paint_target2(entity onwho, float f_size, vector v_color, float f_time)
+{
+ entity e;
+
+ e = spawn();
+ setmodel(e, "models/turrets/c512.md3"); // precision set above
+ e.scale = (f_size/512);
+ setsize(e, '0 0 0', '0 0 0');
+
+ setorigin(e,onwho.origin + '0 0 1');
+ e.alpha = 0.15;
+ e.movetype = MOVETYPE_FLY;
+
+ e.velocity = (v_color * 32); // + '0 0 1' * 64;
+ e.avelocity_x = -128;
+
+ e.colormod = v_color;
+ SUB_SetFade(e,time,f_time);
+}
+
+void paint_target3(vector where, float f_size, vector v_color, float f_time)
+{
+ entity e;
+ e = spawn();
+ setmodel(e, "models/turrets/c512.md3"); // precision set above
+ e.scale = (f_size/512);
+ setsize(e, '0 0 0', '0 0 0');
+ setorigin(e,where+ '0 0 1');
+ e.movetype = MOVETYPE_NONE;
+ e.velocity = '0 0 0';
+ e.colormod = v_color;
+ SUB_SetFade(e,time,f_time);
+}
+#endif
--- /dev/null
-#include "../server/tturrets/include/turrets_early.qh"
+ #ifndef VEHICLES_DEF_H
+ #define VEHICLES_DEF_H
+ #ifdef SVQC
+
++#include "../turrets/sv_turrets.qh"
+ #include "sv_vehicles.qh"
+
+ // #define VEHICLES_USE_ODE
+
+ // vehicle cvars
+ float autocvar_g_vehicles;
+ float autocvar_g_vehicles_enter;
+ float autocvar_g_vehicles_enter_radius;
+ float autocvar_g_vehicles_steal;
+ float autocvar_g_vehicles_steal_show_waypoint;
+ float autocvar_g_vehicles_crush_dmg;
+ float autocvar_g_vehicles_crush_force;
+ float autocvar_g_vehicles_delayspawn;
+ float autocvar_g_vehicles_delayspawn_jitter;
+ float autocvar_g_vehicles_allow_bots;
+ float autocvar_g_vehicles_teams;
+ float autocvar_g_vehicles_teleportable;
+ float autocvar_g_vehicles_vortex_damagerate = 0.5;
+ float autocvar_g_vehicles_machinegun_damagerate = 0.5;
+ float autocvar_g_vehicles_rifle_damagerate = 0.75;
+ float autocvar_g_vehicles_vaporizer_damagerate = 0.001;
+ float autocvar_g_vehicles_tag_damagerate = 5;
+ float autocvar_g_vehicles_weapon_damagerate = 1;
+
+ // flags:
+ .int vehicle_flags;
+
+ // vehicle definitions
+ .entity gun1;
+ .entity gun2;
+ .entity gun3;
+ .entity vehicle_shieldent; /// Entity to disply the shild effect on damage
+ .entity vehicle;
+ .entity vehicle_viewport;
+ .entity vehicle_hudmodel;
+ .entity vehicle_controller;
+
+ .entity gunner1;
+ .entity gunner2;
+
+ .float vehicle_health; /// If self is player this is 0..100 indicating precentage of health left on vehicle. If self is vehile, this is the real health value.
+ .float vehicle_energy; /// If self is player this is 0..100 indicating precentage of energy left on vehicle. If self is vehile, this is the real energy value.
+ .float vehicle_shield; /// If self is player this is 0..100 indicating precentage of shield left on vehicle. If self is vehile, this is the real shield value.
+
+ .float vehicle_ammo1; /// If self is player this is 0..100 indicating percentage of primary ammo left UNLESS value is already stored in vehicle_energy. If self is vehile, this is the real ammo1 value.
+ .float vehicle_reload1; /// If self is player this is 0..100 indicating percentage of primary reload status. If self is vehile, this is the real reload1 value.
+ .float vehicle_ammo2; /// If self is player this is 0..100 indicating percentage of secondary ammo left. If self is vehile, this is the real ammo2 value.
+ .float vehicle_reload2; /// If self is player this is 0..100 indicating percentage of secondary reload status. If self is vehile, this is the real reload2 value.
+
+ .float sound_nexttime;
+ const float VOL_VEHICLEENGINE = 1;
+
+ const float SVC_SETVIEWPORT = 5; // Net.Protocol 0x05
+ const float SVC_SETVIEWANGLES = 10; // Net.Protocol 0x0A
+ const float SVC_UPDATEENTITY = 128; // Net.Protocol 0x80
+
+ const float VHSF_NORMAL = 0;
+ const float VHSF_FACTORY = 2;
+
+ .int hud;
+ .float dmg_time;
+
+ .int volly_counter;
+
+ const int MAX_AXH = 4;
+ .entity AuxiliaryXhair[MAX_AXH];
+
+ .entity wps_intruder;
+
+ .entity lock_target;
+ .float lock_strength;
+ .float lock_time;
+ .float lock_soundtime;
+ const float DAMAGE_TARGETDRONE = 10;
+
+ // vehicle functions
+ .void(int _spawnflag) vehicle_spawn; /// Vehicles custom fucntion to be efecuted when vehicle (re)spawns
+ .bool(int _imp) vehicles_impulse;
+ .int vehicle_weapon2mode;
+ .void(int exit_flags) vehicle_exit;
+ .bool() vehicle_enter;
+ const int VHEF_NORMAL = 0; /// User pressed exit key
+ const int VHEF_EJECT = 1; /// User pressed exit key 3 times fast (not implemented) or vehile is dying
+ const int VHEF_RELEASE = 2; /// Release ownership, client possibly allready dissconnected / went spec / changed team / used "kill" (not implemented)
+
+ float force_fromtag_power;
+ float force_fromtag_normpower;
+ vector force_fromtag_origin;
+
+ float vehicles_exit_running;
+
+ // macros
+ #define VEHICLE_UPDATE_PLAYER(ply,fld,vhname) \
+ ply.vehicle_##fld = (self.vehicle_##fld / autocvar_g_vehicle_##vhname##_##fld) * 100
+
+ .float vehicle_enter_delay; // prevent players jumping to and from vehicles instantly
+
+ void vehicles_exit(float eject);
+ float vehicle_initialize(float vehicle_id, float nodrop);
+ bool vehicle_impulse(int imp);
+ bool vehicles_crushable(entity e);
+
+ #endif
+
+ #endif
float autocvar_g_balance_keyhunt_dropvelocity;
float autocvar_g_balance_keyhunt_maxdist;
float autocvar_g_balance_keyhunt_protecttime;
- float autocvar_g_balance_keyhunt_score_capture;
- float autocvar_g_balance_keyhunt_score_carrierfrag;
- float autocvar_g_balance_keyhunt_score_collect;
- float autocvar_g_balance_keyhunt_score_destroyed;
- float autocvar_g_balance_keyhunt_score_destroyed_ownfactor;
- float autocvar_g_balance_keyhunt_score_push;
+ int autocvar_g_balance_keyhunt_score_capture;
+ int autocvar_g_balance_keyhunt_score_carrierfrag;
+ int autocvar_g_balance_keyhunt_score_collect;
+ int autocvar_g_balance_keyhunt_score_destroyed;
+ int autocvar_g_balance_keyhunt_score_destroyed_ownfactor;
+ int autocvar_g_balance_keyhunt_score_push;
float autocvar_g_balance_keyhunt_throwvelocity;
float autocvar_g_balance_kill_delay;
float autocvar_g_balance_kill_antispam;
float autocvar_g_balance_nexball_secondary_lifetime;
float autocvar_g_balance_nexball_secondary_refire;
float autocvar_g_balance_nexball_secondary_speed;
- float autocvar_g_balance_nix_ammo_cells;
- float autocvar_g_balance_nix_ammo_plasma;
- float autocvar_g_balance_nix_ammo_fuel;
- float autocvar_g_balance_nix_ammo_nails;
- float autocvar_g_balance_nix_ammo_rockets;
- float autocvar_g_balance_nix_ammo_shells;
- float autocvar_g_balance_nix_ammoincr_cells;
- float autocvar_g_balance_nix_ammoincr_plasma;
- float autocvar_g_balance_nix_ammoincr_fuel;
- float autocvar_g_balance_nix_ammoincr_nails;
- float autocvar_g_balance_nix_ammoincr_rockets;
- float autocvar_g_balance_nix_ammoincr_shells;
+ int autocvar_g_balance_nix_ammo_cells;
+ int autocvar_g_balance_nix_ammo_plasma;
+ int autocvar_g_balance_nix_ammo_fuel;
+ int autocvar_g_balance_nix_ammo_nails;
+ int autocvar_g_balance_nix_ammo_rockets;
+ int autocvar_g_balance_nix_ammo_shells;
+ int autocvar_g_balance_nix_ammoincr_cells;
+ int autocvar_g_balance_nix_ammoincr_plasma;
+ int autocvar_g_balance_nix_ammoincr_fuel;
+ int autocvar_g_balance_nix_ammoincr_nails;
+ int autocvar_g_balance_nix_ammoincr_rockets;
+ int autocvar_g_balance_nix_ammoincr_shells;
float autocvar_g_balance_nix_incrtime;
float autocvar_g_balance_nix_roundtime;
float autocvar_g_balance_pause_armor_rot;
float autocvar_g_balance_powerup_strength_time;
float autocvar_g_balance_superweapons_time;
float autocvar_g_balance_selfdamagepercent;
- float autocvar_g_balance_teams;
- float autocvar_g_balance_teams_prevent_imbalance;
+ bool autocvar_g_balance_teams;
+ bool autocvar_g_balance_teams_prevent_imbalance;
float autocvar_g_balance_teams_scorefactor;
float autocvar_g_ballistics_density_corpse;
float autocvar_g_ballistics_density_player;
float autocvar_g_ban_sync_interval;
float autocvar_g_ban_sync_timeout;
string autocvar_g_ban_sync_trusted_servers;
- float autocvar_g_ban_sync_trusted_servers_verify;
+ bool autocvar_g_ban_sync_trusted_servers_verify;
string autocvar_g_ban_sync_uri;
string autocvar_g_banned_list;
- float autocvar_g_banned_list_idmode;
- float autocvar_g_bastet;
- float autocvar_g_botclip_collisions;
- float autocvar_g_bugrigs;
+ bool autocvar_g_banned_list_idmode;
+ bool autocvar_g_bastet;
+ bool autocvar_g_botclip_collisions;
+ bool autocvar_g_bugrigs;
float autocvar_g_ca_damage2score_multiplier;
- float autocvar_g_ca_point_leadlimit;
- float autocvar_g_ca_point_limit;
+ int autocvar_g_ca_point_leadlimit;
+ int autocvar_g_ca_point_limit;
float autocvar_g_ca_round_timelimit;
- float autocvar_g_ca_spectate_enemies;
- float autocvar_g_ca_teams;
- float autocvar_g_ca_teams_override;
- float autocvar_g_ca_team_spawns;
+ bool autocvar_g_ca_spectate_enemies;
+ int autocvar_g_ca_teams;
+ int autocvar_g_ca_teams_override;
+ bool autocvar_g_ca_team_spawns;
float autocvar_g_ca_warmup;
- float autocvar_g_campaign;
+ bool autocvar_g_campaign;
#define autocvar_g_campaign_forceteam cvar("g_campaign_forceteam")
- float autocvar_g_campaign_skill;
- float autocvar_g_casings;
- float autocvar_g_changeteam_banned;
+ int autocvar_g_campaign_skill;
+ int autocvar_g_casings;
+ bool autocvar_g_changeteam_banned;
float autocvar_g_chat_flood_burst;
float autocvar_g_chat_flood_burst_team;
float autocvar_g_chat_flood_burst_tell;
float autocvar_g_chat_flood_lmax;
float autocvar_g_chat_flood_lmax_team;
float autocvar_g_chat_flood_lmax_tell;
- float autocvar_g_chat_flood_notify_flooder;
+ bool autocvar_g_chat_flood_notify_flooder;
float autocvar_g_chat_flood_spl;
float autocvar_g_chat_flood_spl_team;
float autocvar_g_chat_flood_spl_tell;
- float autocvar_g_chat_nospectators;
- float autocvar_g_chat_teamcolors;
- float autocvar_g_chat_tellprivacy;
- float autocvar_g_ctf_allow_vehicle_carry;
- float autocvar_g_ctf_allow_vehicle_touch;
- float autocvar_g_ctf_allow_monster_touch;
- float autocvar_g_ctf_throw;
+ int autocvar_g_chat_nospectators;
+ bool autocvar_g_chat_teamcolors;
+ bool autocvar_g_chat_tellprivacy;
+ bool autocvar_g_ctf_allow_vehicle_carry;
+ bool autocvar_g_ctf_allow_vehicle_touch;
+ bool autocvar_g_ctf_allow_monster_touch;
+ bool autocvar_g_ctf_throw;
float autocvar_g_ctf_throw_angle_max;
float autocvar_g_ctf_throw_angle_min;
- float autocvar_g_ctf_throw_punish_count;
+ int autocvar_g_ctf_throw_punish_count;
float autocvar_g_ctf_throw_punish_delay;
float autocvar_g_ctf_throw_punish_time;
float autocvar_g_ctf_throw_strengthmultiplier;
float autocvar_g_ctf_throw_velocity_up;
float autocvar_g_ctf_drop_velocity_up;
float autocvar_g_ctf_drop_velocity_side;
- float autocvar_g_ctf_portalteleport;
- float autocvar_g_ctf_pass;
+ bool autocvar_g_ctf_oneflag_reverse;
+ bool autocvar_g_ctf_portalteleport;
+ bool autocvar_g_ctf_pass;
float autocvar_g_ctf_pass_arc;
float autocvar_g_ctf_pass_arc_max;
float autocvar_g_ctf_pass_directional_max;
float autocvar_g_ctf_pass_directional_min;
float autocvar_g_ctf_pass_radius;
float autocvar_g_ctf_pass_wait;
- float autocvar_g_ctf_pass_request;
+ bool autocvar_g_ctf_pass_request;
float autocvar_g_ctf_pass_turnrate;
float autocvar_g_ctf_pass_timelimit;
float autocvar_g_ctf_pass_velocity;
- float autocvar_g_ctf_dynamiclights;
- string autocvar_g_ctf_flag_blue_model;
- float autocvar_g_ctf_flag_blue_skin;
+ bool autocvar_g_ctf_dynamiclights;
float autocvar_g_ctf_flag_collect_delay;
float autocvar_g_ctf_flag_damageforcescale;
- float autocvar_g_ctf_flag_dropped_waypoint;
- float autocvar_g_ctf_flag_dropped_floatinwater;
- float autocvar_g_ctf_flag_glowtrails;
- float autocvar_g_ctf_flag_health;
- string autocvar_g_ctf_flag_red_model;
- float autocvar_g_ctf_flag_red_skin;
+ bool autocvar_g_ctf_flag_dropped_waypoint;
+ bool autocvar_g_ctf_flag_dropped_floatinwater;
+ bool autocvar_g_ctf_flag_glowtrails;
+ int autocvar_g_ctf_flag_health;
+ bool autocvar_g_ctf_flag_return;
+ float autocvar_g_ctf_flag_return_carried_radius;
float autocvar_g_ctf_flag_return_time;
- float autocvar_g_ctf_flag_return_when_unreachable;
+ bool autocvar_g_ctf_flag_return_when_unreachable;
float autocvar_g_ctf_flag_return_damage;
+ float autocvar_g_ctf_flag_return_damage_delay;
float autocvar_g_ctf_flag_return_dropped;
float autocvar_g_ctf_flagcarrier_auto_helpme_damage;
float autocvar_g_ctf_flagcarrier_auto_helpme_time;
float autocvar_g_ctf_flagcarrier_damagefactor;
float autocvar_g_ctf_flagcarrier_forcefactor;
//float autocvar_g_ctf_flagcarrier_waypointforenemy_spotting;
- float autocvar_g_ctf_fullbrightflags;
- float autocvar_g_ctf_ignore_frags;
- float autocvar_g_ctf_score_capture;
- float autocvar_g_ctf_score_capture_assist;
- float autocvar_g_ctf_score_kill;
- float autocvar_g_ctf_score_penalty_drop;
- //float autocvar_g_ctf_score_penalty_suicidedrop;
- float autocvar_g_ctf_score_penalty_returned;
- float autocvar_g_ctf_score_pickup_base;
- float autocvar_g_ctf_score_pickup_dropped_early;
- float autocvar_g_ctf_score_pickup_dropped_late;
- float autocvar_g_ctf_score_return;
+ bool autocvar_g_ctf_fullbrightflags;
+ bool autocvar_g_ctf_ignore_frags;
+ int autocvar_g_ctf_score_capture;
+ int autocvar_g_ctf_score_capture_assist;
+ int autocvar_g_ctf_score_kill;
+ int autocvar_g_ctf_score_penalty_drop;
+ int autocvar_g_ctf_score_penalty_returned;
+ int autocvar_g_ctf_score_pickup_base;
+ int autocvar_g_ctf_score_pickup_dropped_early;
+ int autocvar_g_ctf_score_pickup_dropped_late;
+ int autocvar_g_ctf_score_return;
float autocvar_g_ctf_shield_force;
float autocvar_g_ctf_shield_max_ratio;
- float autocvar_g_ctf_shield_min_negscore;
- float autocvar_g_ctf_stalemate;
- float autocvar_g_ctf_stalemate_endcondition;
+ int autocvar_g_ctf_shield_min_negscore;
+ bool autocvar_g_ctf_stalemate;
+ int autocvar_g_ctf_stalemate_endcondition;
float autocvar_g_ctf_stalemate_time;
- float autocvar_g_ctf_reverse;
+ bool autocvar_g_ctf_reverse;
float autocvar_g_ctf_dropped_capture_delay;
float autocvar_g_ctf_dropped_capture_radius;
float autocvar_g_cts_finish_kill_delay;
- float autocvar_g_cts_selfdamage;
- float autocvar_g_debug_bot_commands;
- float autocvar_g_domination_default_teams;
- float autocvar_g_domination_disable_frags;
- float autocvar_g_domination_point_amt;
- float autocvar_g_domination_point_fullbright;
- float autocvar_g_domination_point_leadlimit;
- float autocvar_g_domination_roundbased;
- float autocvar_g_domination_roundbased_point_limit;
+ bool autocvar_g_cts_selfdamage;
+ bool autocvar_g_debug_bot_commands;
+ int autocvar_g_domination_default_teams;
+ bool autocvar_g_domination_disable_frags;
+ int autocvar_g_domination_point_amt;
+ bool autocvar_g_domination_point_fullbright;
+ int autocvar_g_domination_point_leadlimit;
+ bool autocvar_g_domination_roundbased;
+ int autocvar_g_domination_roundbased_point_limit;
float autocvar_g_domination_round_timelimit;
float autocvar_g_domination_warmup;
#define autocvar_g_domination_point_limit cvar("g_domination_point_limit")
float autocvar_g_domination_point_rate;
- float autocvar_g_domination_teams_override;
- float autocvar_g_forced_respawn;
+ int autocvar_g_domination_teams_override;
+ bool autocvar_g_forced_respawn;
string autocvar_g_forced_team_blue;
string autocvar_g_forced_team_otherwise;
string autocvar_g_forced_team_pink;
string autocvar_g_forced_team_red;
string autocvar_g_forced_team_yellow;
- float autocvar_g_freezetag_frozen_damage_trigger;
+ bool autocvar_g_freezetag_frozen_damage_trigger;
float autocvar_g_freezetag_frozen_force;
float autocvar_g_freezetag_frozen_maxtime;
float autocvar_g_freezetag_revive_falldamage;
float autocvar_g_freezetag_revive_falldamage_health;
- float autocvar_g_freezetag_revive_nade;
+ bool autocvar_g_freezetag_revive_nade;
float autocvar_g_freezetag_revive_nade_health;
- float autocvar_g_freezetag_point_leadlimit;
- float autocvar_g_freezetag_point_limit;
+ int autocvar_g_freezetag_point_leadlimit;
+ int autocvar_g_freezetag_point_limit;
float autocvar_g_freezetag_revive_extra_size;
float autocvar_g_freezetag_revive_speed;
float autocvar_g_freezetag_revive_clearspeed;
float autocvar_g_freezetag_round_timelimit;
- float autocvar_g_freezetag_teams;
- float autocvar_g_freezetag_teams_override;
- float autocvar_g_freezetag_team_spawns;
+ int autocvar_g_freezetag_teams;
+ int autocvar_g_freezetag_teams_override;
+ bool autocvar_g_freezetag_team_spawns;
float autocvar_g_freezetag_warmup;
#define autocvar_g_friendlyfire cvar("g_friendlyfire")
#define autocvar_g_friendlyfire_virtual cvar("g_friendlyfire_virtual")
#define autocvar_g_friendlyfire_virtual_force cvar("g_friendlyfire_virtual_force")
- float autocvar_g_full_getstatus_responses;
- float autocvar_g_fullbrightitems;
- float autocvar_g_fullbrightplayers;
+ bool autocvar_g_full_getstatus_responses;
+ bool autocvar_g_fullbrightitems;
+ bool autocvar_g_fullbrightplayers;
#define autocvar_g_grappling_hook cvar("g_grappling_hook")
- float autocvar_g_grappling_hook_tarzan;
- float autocvar_g_hitplots;
+ int autocvar_g_grappling_hook_tarzan;
+ bool autocvar_g_hitplots;
string autocvar_g_hitplots_individuals;
float autocvar_g_jetpack_acceleration_side;
float autocvar_g_jetpack_acceleration_up;
float autocvar_g_jetpack_antigravity;
- float autocvar_g_jetpack_fuel;
+ int autocvar_g_jetpack_fuel;
float autocvar_g_jetpack_maxspeed_side;
float autocvar_g_jetpack_maxspeed_up;
- float autocvar_g_keepaway_ballcarrier_effects;
+ int autocvar_g_keepaway_ballcarrier_effects;
float autocvar_g_keepaway_ballcarrier_damage;
float autocvar_g_keepaway_ballcarrier_force;
float autocvar_g_keepaway_ballcarrier_highspeed;
float autocvar_g_keepaway_noncarrier_force;
float autocvar_g_keepaway_noncarrier_selfdamage;
float autocvar_g_keepaway_noncarrier_selfforce;
- float autocvar_g_keepaway_noncarrier_warn;
- float autocvar_g_keepaway_score_bckill;
- float autocvar_g_keepaway_score_killac;
- float autocvar_g_keepaway_score_timepoints;
+ bool autocvar_g_keepaway_noncarrier_warn;
+ int autocvar_g_keepaway_score_bckill;
+ int autocvar_g_keepaway_score_killac;
+ int autocvar_g_keepaway_score_timepoints;
float autocvar_g_keepaway_score_timeinterval;
float autocvar_g_keepawayball_damageforcescale;
- float autocvar_g_keepawayball_effects;
+ int autocvar_g_keepawayball_effects;
float autocvar_g_keepawayball_respawntime;
- float autocvar_g_keepawayball_trail_color;
- float autocvar_g_keyhunt_point_leadlimit;
+ int autocvar_g_keepawayball_trail_color;
+ int autocvar_g_keyhunt_point_leadlimit;
#define autocvar_g_keyhunt_point_limit cvar("g_keyhunt_point_limit")
- float autocvar_g_keyhunt_teams;
- float autocvar_g_keyhunt_teams_override;
- float autocvar_g_lms_extra_lives;
- float autocvar_g_lms_join_anytime;
- float autocvar_g_lms_last_join;
+ int autocvar_g_keyhunt_teams;
+ int autocvar_g_keyhunt_teams_override;
+ int autocvar_g_lms_extra_lives;
+ bool autocvar_g_lms_join_anytime;
+ int autocvar_g_lms_last_join;
#define autocvar_g_lms_lives_override cvar("g_lms_lives_override")
- float autocvar_g_lms_regenerate;
+ bool autocvar_g_lms_regenerate;
#define autocvar_g_maplist cvar_string("g_maplist")
- float autocvar_g_maplist_check_waypoints;
- float autocvar_g_maplist_index;
+ bool autocvar_g_maplist_check_waypoints;
+ int autocvar_g_maplist_index;
string autocvar_g_maplist_mostrecent;
- float autocvar_g_maplist_mostrecent_count;
- float autocvar_g_maplist_selectrandom;
+ int autocvar_g_maplist_mostrecent_count;
+ bool autocvar_g_maplist_selectrandom;
float autocvar_g_maplist_shuffle;
#define autocvar_g_maplist_votable cvar("g_maplist_votable")
- float autocvar_g_maplist_votable_abstain;
+ bool autocvar_g_maplist_votable_abstain;
float autocvar_g_maplist_votable_keeptwotime;
- float autocvar_g_maplist_votable_nodetail;
+ bool autocvar_g_maplist_votable_nodetail;
string autocvar_g_maplist_votable_screenshot_dir;
- float autocvar_g_maplist_votable_suggestions;
- float autocvar_g_maplist_votable_suggestions_override_mostrecent;
+ bool autocvar_g_maplist_votable_suggestions;
+ bool autocvar_g_maplist_votable_suggestions_override_mostrecent;
float autocvar_g_maplist_votable_timeout;
- float autocvar_g_maxplayers;
+ int autocvar_g_maxplayers;
float autocvar_g_maxplayers_spectator_blocktime;
float autocvar_g_maxpushtime;
float autocvar_g_maxspeed;
float autocvar_g_midair_shieldtime;
#define autocvar_g_instagib cvar("g_instagib")
- float autocvar_g_instagib_ammo_drop;
- float autocvar_g_instagib_extralives;
+ int autocvar_g_instagib_ammo_drop;
+ int autocvar_g_instagib_extralives;
float autocvar_g_instagib_speed_highspeed;
float autocvar_g_instagib_invis_alpha;
#define autocvar_g_mirrordamage cvar("g_mirrordamage")
#define autocvar_g_mirrordamage_virtual cvar("g_mirrordamage_virtual")
float autocvar_g_movement_highspeed = 1;
- float autocvar_g_multijump;
+ int autocvar_g_multijump;
float autocvar_g_multijump_add;
float autocvar_g_multijump_speed;
string autocvar_g_mutatormsg;
float autocvar_g_nexball_basketball_bouncefactor;
float autocvar_g_nexball_basketball_bouncestop;
float autocvar_g_nexball_basketball_carrier_highspeed;
- float autocvar_g_nexball_basketball_meter;
+ bool autocvar_g_nexball_basketball_meter;
float autocvar_g_nexball_basketball_meter_maxpower;
float autocvar_g_nexball_basketball_meter_minpower;
float autocvar_g_nexball_delay_collect;
float autocvar_g_nexball_delay_start;
float autocvar_g_nexball_football_bouncefactor;
float autocvar_g_nexball_football_bouncestop;
- float autocvar_g_nexball_goalleadlimit;
+ int autocvar_g_nexball_goalleadlimit;
#define autocvar_g_nexball_goallimit cvar("g_nexball_goallimit")
- float autocvar_g_nexball_radar_showallplayers;
- float autocvar_g_nexball_sound_bounce;
- float autocvar_g_nexball_trail_color;
+ bool autocvar_g_nexball_radar_showallplayers;
+ bool autocvar_g_nexball_sound_bounce;
+ int autocvar_g_nexball_trail_color;
//float autocvar_g_nick_flood_penalty;
- float autocvar_g_nick_flood_penalty_red;
- float autocvar_g_nick_flood_penalty_yellow;
+ int autocvar_g_nick_flood_penalty_red;
+ int autocvar_g_nick_flood_penalty_yellow;
//float autocvar_g_nick_flood_timeout;
- float autocvar_g_nix_with_healtharmor;
- float autocvar_g_nix_with_blaster;
- float autocvar_g_nix_with_powerups;
- float autocvar_g_nodepthtestitems;
- float autocvar_g_nodepthtestplayers;
- float autocvar_g_norecoil;
+ bool autocvar_g_nix_with_healtharmor;
+ bool autocvar_g_nix_with_blaster;
+ bool autocvar_g_nix_with_powerups;
+ bool autocvar_g_nodepthtestitems;
+ bool autocvar_g_nodepthtestplayers;
+ bool autocvar_g_norecoil;
float autocvar_g_onslaught_cp_buildhealth;
float autocvar_g_onslaught_cp_buildtime;
float autocvar_g_onslaught_cp_health;
float autocvar_g_onslaught_cp_regen;
float autocvar_g_onslaught_gen_health;
- float autocvar_g_pickup_cells_max;
- float autocvar_g_pickup_plasma_max;
- float autocvar_g_pickup_fuel_max;
- float autocvar_g_pickup_items;
- float autocvar_g_pickup_nails_max;
- float autocvar_g_pickup_rockets_max;
- float autocvar_g_pickup_shells_max;
+ int autocvar_g_pickup_cells_max;
+ int autocvar_g_pickup_plasma_max;
+ int autocvar_g_pickup_fuel_max;
+ int autocvar_g_pickup_items;
+ int autocvar_g_pickup_nails_max;
+ int autocvar_g_pickup_rockets_max;
+ int autocvar_g_pickup_shells_max;
float autocvar_g_player_alpha;
float autocvar_g_player_brightness;
- float autocvar_g_playerclip_collisions;
- float autocvar_g_powerups;
- float autocvar_g_projectiles_damage;
- float autocvar_g_projectiles_keep_owner;
- float autocvar_g_projectiles_newton_style;
+ bool autocvar_g_playerclip_collisions;
+ int autocvar_g_powerups;
+ int autocvar_g_projectiles_damage;
+ bool autocvar_g_projectiles_keep_owner;
+ int autocvar_g_projectiles_newton_style;
float autocvar_g_projectiles_newton_style_2_maxfactor;
float autocvar_g_projectiles_newton_style_2_minfactor;
- float autocvar_g_projectiles_spread_style;
+ int autocvar_g_projectiles_spread_style;
#define autocvar_g_race_laps_limit cvar("g_race_laps_limit")
float autocvar_g_race_qualifying_timelimit;
float autocvar_g_race_qualifying_timelimit_override;
- float autocvar_g_race_teams;
+ int autocvar_g_race_teams;
float autocvar_g_respawn_delay_small;
- float autocvar_g_respawn_delay_small_count;
+ int autocvar_g_respawn_delay_small_count;
float autocvar_g_respawn_delay_large;
- float autocvar_g_respawn_delay_large_count;
+ int autocvar_g_respawn_delay_large_count;
float autocvar_g_respawn_delay_max;
- float autocvar_g_respawn_ghosts;
+ bool autocvar_g_respawn_ghosts;
float autocvar_g_respawn_ghosts_maxtime;
float autocvar_g_respawn_ghosts_speed;
- float autocvar_g_respawn_waves;
- float autocvar_g_running_guns;
- float autocvar_g_shootfromcenter;
- float autocvar_g_shootfromclient;
- float autocvar_g_shootfromeye;
+ int autocvar_g_respawn_waves;
+ bool autocvar_g_running_guns;
+ bool autocvar_g_shootfromcenter;
+ int autocvar_g_shootfromclient;
+ bool autocvar_g_shootfromeye;
string autocvar_g_shootfromfixedorigin;
- float autocvar_g_showweaponspawns;
- float autocvar_g_spawn_alloweffects;
+ int autocvar_g_showweaponspawns;
+ bool autocvar_g_spawn_alloweffects;
float autocvar_g_spawn_furthest;
- float autocvar_g_spawn_useallspawns;
- float autocvar_g_spawnpoints_auto_move_out_of_solid;
+ bool autocvar_g_spawn_useallspawns;
+ bool autocvar_g_spawnpoints_auto_move_out_of_solid;
#define autocvar_g_spawnshieldtime cvar("g_spawnshieldtime")
- float autocvar_g_tdm_team_spawns;
- float autocvar_g_tdm_point_limit;
- float autocvar_g_tdm_point_leadlimit;
- float autocvar_g_tdm_teams;
- float autocvar_g_tdm_teams_override;
+ bool autocvar_g_tdm_team_spawns;
+ int autocvar_g_tdm_point_limit;
+ int autocvar_g_tdm_point_leadlimit;
+ int autocvar_g_tdm_teams;
+ int autocvar_g_tdm_teams_override;
float autocvar_g_teamdamage_resetspeed;
float autocvar_g_teamdamage_threshold;
- float autocvar_g_telefrags;
- float autocvar_g_telefrags_avoid;
- float autocvar_g_telefrags_teamplay;
+ bool autocvar_g_telefrags;
+ bool autocvar_g_telefrags_avoid;
+ bool autocvar_g_telefrags_teamplay;
float autocvar_g_teleport_maxspeed;
- float autocvar_g_throughfloor_debug;
+ bool autocvar_g_throughfloor_debug;
float autocvar_g_throughfloor_damage;
float autocvar_g_throughfloor_force;
float autocvar_g_throughfloor_damage_max_stddev;
float autocvar_g_triggerimpulse_accel_power;
float autocvar_g_triggerimpulse_directional_multiplier;
float autocvar_g_triggerimpulse_radial_multiplier;
- float autocvar_g_turrets;
+ bool autocvar_g_turrets;
float autocvar_g_turrets_aimidle_delay;
- float autocvar_g_turrets_nofire;
- float autocvar_g_turrets_reloadcvars;
+ bool autocvar_g_turrets_nofire;
+ bool autocvar_g_turrets_reloadcvars;
float autocvar_g_turrets_targetscan_maxdelay;
float autocvar_g_turrets_targetscan_mindelay;
- float autocvar_g_use_ammunition;
- float autocvar_g_waypointeditor;
- float autocvar_g_waypointeditor_auto;
- float autocvar_g_waypoints_for_items;
-float autocvar_g_turrets_unit_ewheel_speed_fast;
-float autocvar_g_turrets_unit_ewheel_speed_slow;
-float autocvar_g_turrets_unit_ewheel_speed_slower;
-float autocvar_g_turrets_unit_ewheel_speed_stop;
-float autocvar_g_turrets_unit_ewheel_turnrate;
-float autocvar_g_turrets_unit_hellion_std_shot_speed_gain;
-float autocvar_g_turrets_unit_hellion_std_shot_speed_max;
-float autocvar_g_turrets_unit_hk_std_shot_speed;
-float autocvar_g_turrets_unit_hk_std_shot_speed_accel;
-float autocvar_g_turrets_unit_hk_std_shot_speed_accel2;
-float autocvar_g_turrets_unit_hk_std_shot_speed_decel;
-float autocvar_g_turrets_unit_hk_std_shot_speed_max;
-float autocvar_g_turrets_unit_hk_std_shot_speed_turnrate;
-float autocvar_g_turrets_unit_walker_speed_jump;
-float autocvar_g_turrets_unit_walker_speed_roam;
-float autocvar_g_turrets_unit_walker_speed_run;
-float autocvar_g_turrets_unit_walker_speed_stop;
-float autocvar_g_turrets_unit_walker_speed_swim;
-float autocvar_g_turrets_unit_walker_speed_walk;
-float autocvar_g_turrets_unit_walker_std_meele_dmg;
-float autocvar_g_turrets_unit_walker_std_meele_force;
-float autocvar_g_turrets_unit_walker_std_meele_range;
-float autocvar_g_turrets_unit_walker_std_rocket_dmg;
-float autocvar_g_turrets_unit_walker_std_rocket_force;
-float autocvar_g_turrets_unit_walker_std_rocket_radius;
-float autocvar_g_turrets_unit_walker_std_rocket_refire;
-float autocvar_g_turrets_unit_walker_std_rocket_speed;
-float autocvar_g_turrets_unit_walker_std_rocket_turnrate;
-float autocvar_g_turrets_unit_walker_std_rockets_range;
-float autocvar_g_turrets_unit_walker_std_rockets_range_min;
-float autocvar_g_turrets_unit_walker_turn;
-float autocvar_g_turrets_unit_walker_turn_walk;
-float autocvar_g_turrets_unit_walker_turn_run;
-float autocvar_g_turrets_unit_walker_turn_strafe;
-float autocvar_g_turrets_unit_walker_turn_swim;
+ bool autocvar_g_use_ammunition;
+ bool autocvar_g_waypointeditor;
+ int autocvar_g_waypointeditor_auto;
-int autocvar_g_waypoints_for_items;
++bool autocvar_g_waypoints_for_items;
float autocvar_g_weapon_charge_colormod_blue_full;
float autocvar_g_weapon_charge_colormod_blue_half;
float autocvar_g_weapon_charge_colormod_green_full;
float autocvar_g_weapon_charge_colormod_red_full;
float autocvar_g_weapon_charge_colormod_red_half;
#define autocvar_g_weapon_stay cvar("g_weapon_stay")
- float autocvar_g_weapon_throwable;
+ bool autocvar_g_weapon_throwable;
#define autocvar_g_weaponarena cvar_string("g_weaponarena")
string autocvar_g_xonoticversion;
float autocvar_gameversion;
float autocvar_gameversion_min;
float autocvar_gameversion_max;
string autocvar_hostname;
- float autocvar_lastlevel;
- float autocvar_leadlimit;
- float autocvar_leadlimit_and_fraglimit;
- float autocvar_leadlimit_override;
- float autocvar_loddebug;
- float autocvar_minplayers;
+ bool autocvar_lastlevel;
+ int autocvar_leadlimit;
+ int autocvar_leadlimit_and_fraglimit;
+ int autocvar_leadlimit_override;
+ int autocvar_loddebug;
+ int autocvar_minplayers;
string autocvar_nextmap;
- float autocvar_prvm_backtraceforwarnings;
+ bool autocvar_prvm_backtraceforwarnings;
string autocvar_quit_and_redirect;
float autocvar_quit_and_redirect_timer;
- float autocvar_quit_when_empty;
+ bool autocvar_quit_when_empty;
float autocvar_r_showbboxes;
- float autocvar_rescan_pending;
- float autocvar_samelevel;
+ int autocvar_rescan_pending;
+ bool autocvar_samelevel;
string autocvar_sessionid;
#define autocvar_skill cvar("skill")
float autocvar_skill_auto;
#define autocvar_slowmo cvar("slowmo")
float autocvar_snd_soundradius;
- float autocvar_spawn_debug;
- float autocvar_speedmeter;
- float autocvar_sv_accelerate;
+ int autocvar_spawn_debug;
+ bool autocvar_speedmeter;
float autocvar_sv_accuracy_data_share = 1;
string autocvar_sv_adminnick;
- float autocvar_sv_airaccel_qw;
- float autocvar_sv_airaccel_qw_stretchfactor;
- float autocvar_sv_airaccel_sideways_friction;
- float autocvar_sv_airaccelerate;
- float autocvar_sv_aircontrol;
- float autocvar_sv_aircontrol_penalty;
- float autocvar_sv_aircontrol_power;
- float autocvar_sv_airspeedlimit_nonqw;
- float autocvar_sv_airstopaccelerate;
- float autocvar_sv_airstrafeaccel_qw;
- float autocvar_sv_airstrafeaccelerate;
- float autocvar_sv_autoscreenshot;
- float autocvar_sv_cheats;
+ bool autocvar_sv_autoscreenshot;
+ int autocvar_sv_cheats;
float autocvar_sv_clientcommand_antispam_time;
- float autocvar_sv_clientcommand_antispam_count;
- float autocvar_sv_curl_serverpackages_auto;
- float autocvar_sv_db_saveasdump;
- float autocvar_sv_defaultcharacter;
+ int autocvar_sv_clientcommand_antispam_count;
+ bool autocvar_sv_curl_serverpackages_auto;
+ bool autocvar_sv_db_saveasdump;
+ bool autocvar_sv_defaultcharacter;
string autocvar_sv_defaultplayercolors;
string autocvar_sv_defaultplayermodel;
string autocvar_sv_defaultplayermodel_blue;
string autocvar_sv_defaultplayermodel_pink;
string autocvar_sv_defaultplayermodel_red;
string autocvar_sv_defaultplayermodel_yellow;
- float autocvar_sv_defaultplayerskin;
+ int autocvar_sv_defaultplayerskin;
float autocvar_sv_dodging_delay;
float autocvar_sv_dodging_height_threshold;
float autocvar_sv_dodging_horiz_speed;
float autocvar_sv_dodging_horiz_speed_frozen;
float autocvar_sv_dodging_ramp_time;
- float autocvar_sv_dodging_sound;
+ bool autocvar_sv_dodging_sound;
float autocvar_sv_dodging_up_speed;
float autocvar_sv_dodging_wall_distance_threshold;
- float autocvar_sv_dodging_wall_dodging;
- float autocvar_sv_dodging_frozen;
- float autocvar_sv_dodging_frozen_doubletap;
- float autocvar_sv_doublejump;
- float autocvar_sv_eventlog;
- float autocvar_sv_eventlog_console;
- float autocvar_sv_eventlog_files;
- float autocvar_sv_eventlog_files_counter;
+ bool autocvar_sv_dodging_wall_dodging;
+ bool autocvar_sv_dodging_frozen;
+ bool autocvar_sv_dodging_frozen_doubletap;
+ bool autocvar_sv_doublejump;
+ bool autocvar_sv_eventlog;
+ bool autocvar_sv_eventlog_console;
+ bool autocvar_sv_eventlog_files;
+ int autocvar_sv_eventlog_files_counter;
string autocvar_sv_eventlog_files_nameprefix;
string autocvar_sv_eventlog_files_namesuffix;
- float autocvar_sv_eventlog_files_timestamps;
- float autocvar_sv_friction;
+ bool autocvar_sv_eventlog_files_timestamps;
float autocvar_sv_friction_on_land;
+ var float autocvar_sv_friction_slick = 0.5;
float autocvar_sv_gameplayfix_q2airaccelerate;
- float autocvar_sv_gentle;
+ int autocvar_sv_gentle;
#define autocvar_sv_gravity cvar("sv_gravity")
string autocvar_sv_intermission_cdtrack;
+ float autocvar_sv_itemstime;
string autocvar_sv_jumpspeedcap_max;
float autocvar_sv_jumpspeedcap_max_disable_on_ramps;
string autocvar_sv_jumpspeedcap_min;
float autocvar_sv_jumpvelocity;
- float autocvar_sv_logscores_bots;
- float autocvar_sv_logscores_console;
- float autocvar_sv_logscores_file;
+ bool autocvar_sv_logscores_bots;
+ bool autocvar_sv_logscores_console;
+ bool autocvar_sv_logscores_file;
string autocvar_sv_logscores_filename;
float autocvar_sv_mapchange_delay;
float autocvar_sv_maxairspeed;
- float autocvar_sv_maxairstrafespeed;
float autocvar_sv_maxspeed;
string autocvar_sv_motd;
- float autocvar_sv_precacheplayermodels;
+ bool autocvar_sv_precacheplayermodels;
//float autocvar_sv_precacheweapons; // WEAPONTODO?
- float autocvar_sv_q3acompat_machineshotgunswap;
- float autocvar_sv_ready_restart;
- float autocvar_sv_ready_restart_after_countdown;
- float autocvar_sv_ready_restart_repeatable;
- float autocvar_sv_servermodelsonly;
- float autocvar_sv_spectate;
+ bool autocvar_sv_q3acompat_machineshotgunswap;
+ bool autocvar_sv_ready_restart;
+ bool autocvar_sv_ready_restart_after_countdown;
+ bool autocvar_sv_ready_restart_repeatable;
+ bool autocvar_sv_servermodelsonly;
+ int autocvar_sv_spectate;
float autocvar_sv_spectator_speed_multiplier;
- float autocvar_sv_status_privacy;
+ bool autocvar_sv_status_privacy;
float autocvar_sv_stepheight;
- float autocvar_sv_stopspeed;
float autocvar_sv_strengthsound_antispam_refire_threshold;
float autocvar_sv_strengthsound_antispam_time;
- float autocvar_sv_teamnagger;
- float autocvar_sv_timeout;
+ bool autocvar_sv_teamnagger;
+ bool autocvar_sv_timeout;
float autocvar_sv_timeout_leadtime;
float autocvar_sv_timeout_length;
- float autocvar_sv_timeout_number;
+ int autocvar_sv_timeout_number;
float autocvar_sv_timeout_resumetime;
- float autocvar_sv_vote_call;
- float autocvar_sv_vote_change;
+ bool autocvar_sv_vote_call;
+ bool autocvar_sv_vote_change;
string autocvar_sv_vote_commands;
- float autocvar_sv_vote_gametype;
+ bool autocvar_sv_vote_gametype;
float autocvar_sv_vote_gametype_timeout;
string autocvar_sv_vote_gametype_options;
float autocvar_sv_vote_gametype_keeptwotime;
- float autocvar_sv_vote_gametype_default_current;
- float autocvar_sv_vote_limit;
+ bool autocvar_sv_vote_gametype_default_current;
+ int autocvar_sv_vote_limit;
float autocvar_sv_vote_majority_factor;
float autocvar_sv_vote_majority_factor_of_voted;
- float autocvar_sv_vote_master;
- float autocvar_sv_vote_master_callable;
+ bool autocvar_sv_vote_master;
+ bool autocvar_sv_vote_master_callable;
string autocvar_sv_vote_master_commands;
string autocvar_sv_vote_master_password;
- float autocvar_sv_vote_master_playerlimit;
- float autocvar_sv_vote_no_stops_vote;
- float autocvar_sv_vote_nospectators;
+ int autocvar_sv_vote_master_playerlimit;
+ bool autocvar_sv_vote_no_stops_vote;
+ int autocvar_sv_vote_nospectators;
//string autocvar_sv_vote_only_commands;
- float autocvar_sv_vote_override_mostrecent;
- float autocvar_sv_vote_singlecount;
+ bool autocvar_sv_vote_override_mostrecent;
+ bool autocvar_sv_vote_singlecount;
float autocvar_sv_vote_stop;
float autocvar_sv_vote_timeout;
float autocvar_sv_vote_wait;
- float autocvar_sv_vote_gamestart;
- float autocvar_sv_warsowbunny_accel;
- float autocvar_sv_warsowbunny_airforwardaccel;
- float autocvar_sv_warsowbunny_backtosideratio;
- float autocvar_sv_warsowbunny_topspeed;
- float autocvar_sv_warsowbunny_turnaccel;
+ bool autocvar_sv_vote_gamestart;
float autocvar_sv_waypointsprite_deadlifetime;
float autocvar_sv_waypointsprite_deployed_lifetime;
float autocvar_sv_waypointsprite_limitedrange;
string autocvar_sv_weaponstats_file;
float autocvar_sv_gibhealth;
float autocvar_sys_ticrate;
- float autocvar_teamplay_lockonrestart;
- float autocvar_teamplay_mode;
+ bool autocvar_teamplay_lockonrestart;
+ int autocvar_teamplay_mode;
#define autocvar_timelimit cvar("timelimit")
#define autocvar_timelimit_override cvar("timelimit_override")
float autocvar_timelimit_increment;
float autocvar_timelimit_min;
float autocvar_timelimit_max;
float autocvar_timelimit_overtime;
- float autocvar_timelimit_overtimes;
+ int autocvar_timelimit_overtimes;
float autocvar_timelimit_suddendeath;
#define autocvar_utf8_enable cvar("utf8_enable")
- float autocvar_waypoint_benchmark;
+ bool autocvar_waypoint_benchmark;
float autocvar_sv_gameplayfix_gravityunaffectedbyticrate;
+ bool autocvar_sv_gameplayfix_upwardvelocityclearsongroundflag;
float autocvar_g_trueaim_minrange;
- float autocvar_g_debug_defaultsounds;
+ bool autocvar_g_debug_defaultsounds;
float autocvar_g_grab_range;
- float autocvar_g_sandbox_info;
- float autocvar_g_sandbox_readonly;
+ int autocvar_g_sandbox_info;
+ bool autocvar_g_sandbox_readonly;
string autocvar_g_sandbox_storage_name;
float autocvar_g_sandbox_storage_autosave;
- float autocvar_g_sandbox_storage_autoload;
+ bool autocvar_g_sandbox_storage_autoload;
float autocvar_g_sandbox_editor_flood;
- float autocvar_g_sandbox_editor_maxobjects;
- float autocvar_g_sandbox_editor_free;
+ int autocvar_g_sandbox_editor_maxobjects;
+ int autocvar_g_sandbox_editor_free;
float autocvar_g_sandbox_editor_distance_spawn;
float autocvar_g_sandbox_editor_distance_edit;
float autocvar_g_sandbox_object_scale_min;
float autocvar_g_sandbox_object_scale_max;
float autocvar_g_sandbox_object_material_velocity_min;
float autocvar_g_sandbox_object_material_velocity_factor;
- float autocvar_g_max_info_autoscreenshot;
- float autocvar_physics_ode;
- float autocvar_g_physical_items;
+ int autocvar_g_max_info_autoscreenshot;
+ bool autocvar_physics_ode;
+ int autocvar_g_physical_items;
float autocvar_g_physical_items_damageforcescale;
float autocvar_g_physical_items_reset;
float autocvar_g_monsters;
- float autocvar_g_monsters_edit;
- float autocvar_g_monsters_sounds;
+ bool autocvar_g_monsters_edit;
+ bool autocvar_g_monsters_sounds;
float autocvar_g_monsters_think_delay;
- float autocvar_g_monsters_max;
- float autocvar_g_monsters_max_perplayer;
+ int autocvar_g_monsters_max;
+ int autocvar_g_monsters_max_perplayer;
float autocvar_g_monsters_target_range;
- float autocvar_g_monsters_target_infront;
+ bool autocvar_g_monsters_target_infront;
float autocvar_g_monsters_attack_range;
- float autocvar_g_monsters_score_kill;
- float autocvar_g_monsters_score_spawned;
- float autocvar_g_monsters_typefrag;
- float autocvar_g_monsters_owners;
+ int autocvar_g_monsters_score_kill;
+ int autocvar_g_monsters_score_spawned;
+ bool autocvar_g_monsters_typefrag;
+ bool autocvar_g_monsters_owners;
float autocvar_g_monsters_miniboss_chance;
float autocvar_g_monsters_miniboss_healthboost;
float autocvar_g_monsters_drop_time;
float autocvar_g_monsters_spawnshieldtime;
- float autocvar_g_monsters_teams;
+ bool autocvar_g_monsters_teams;
float autocvar_g_monsters_respawn_delay;
- float autocvar_g_monsters_respawn;
+ bool autocvar_g_monsters_respawn;
float autocvar_g_monsters_armor_blockpercent;
float autocvar_g_touchexplode_radius;
float autocvar_g_touchexplode_damage;
float autocvar_g_touchexplode_edgedamage;
float autocvar_g_touchexplode_force;
float autocvar_g_invasion_round_timelimit;
- float autocvar_g_invasion_teams;
- float autocvar_g_invasion_team_spawns;
+ int autocvar_g_invasion_teams;
+ bool autocvar_g_invasion_team_spawns;
float autocvar_g_invasion_spawnpoint_spawn_delay;
#define autocvar_g_invasion_point_limit cvar("g_invasion_point_limit")
float autocvar_g_invasion_warmup;
- float autocvar_g_invasion_monster_count;
- float autocvar_g_invasion_zombies_only;
+ int autocvar_g_invasion_monster_count;
+ bool autocvar_g_invasion_zombies_only;
float autocvar_g_invasion_spawn_delay;
#define autocvar_g_bloodloss cvar("g_bloodloss")
float autocvar_g_random_gravity_negative_chance;
float autocvar_g_random_gravity_positive;
float autocvar_g_random_gravity_negative;
float autocvar_g_random_gravity_delay;
- float autocvar_g_nades;
+ bool autocvar_g_nades;
vector autocvar_g_nades_throw_offset;
- float autocvar_g_nades_spawn;
- float autocvar_g_nades_spawn_count;
- float autocvar_g_nades_client_select;
+ bool autocvar_g_nades_spawn;
+ int autocvar_g_nades_spawn_count;
+ bool autocvar_g_nades_client_select;
float autocvar_g_nades_nade_lifetime;
float autocvar_g_nades_nade_minforce;
float autocvar_g_nades_nade_maxforce;
float autocvar_g_nades_nade_edgedamage;
float autocvar_g_nades_nade_radius;
float autocvar_g_nades_nade_force;
- float autocvar_g_nades_nade_newton_style;
+ int autocvar_g_nades_nade_newton_style;
int autocvar_g_nades_napalm_ball_count;
float autocvar_g_nades_napalm_ball_spread;
float autocvar_g_nades_napalm_ball_damage;
float autocvar_g_nades_napalm_ball_damageforcescale;
float autocvar_g_nades_napalm_ball_lifetime;
float autocvar_g_nades_napalm_ball_radius;
- float autocvar_g_nades_napalm_blast;
+ bool autocvar_g_nades_napalm_blast;
float autocvar_g_nades_napalm_fountain_lifetime;
float autocvar_g_nades_napalm_fountain_delay;
float autocvar_g_nades_napalm_fountain_radius;
float autocvar_g_nades_napalm_fountain_damage;
float autocvar_g_nades_napalm_fountain_edgedamage;
float autocvar_g_nades_napalm_burntime;
- float autocvar_g_nades_napalm_selfdamage;
- float autocvar_g_nades_nade_type;
- float autocvar_g_nades_bonus_type;
- float autocvar_g_nades_bonus;
- float autocvar_g_nades_bonus_onstrength;
- float autocvar_g_nades_bonus_client_select;
- float autocvar_g_nades_bonus_max;
- float autocvar_g_nades_bonus_score_max;
- float autocvar_g_nades_bonus_score_time;
- float autocvar_g_nades_bonus_score_time_flagcarrier;
- float autocvar_g_nades_bonus_score_minor;
- float autocvar_g_nades_bonus_score_low;
- float autocvar_g_nades_bonus_score_high;
- float autocvar_g_nades_bonus_score_medium;
- float autocvar_g_nades_bonus_score_spree;
+ bool autocvar_g_nades_napalm_selfdamage;
+ int autocvar_g_nades_nade_type;
+ int autocvar_g_nades_bonus_type;
+ bool autocvar_g_nades_bonus;
+ bool autocvar_g_nades_bonus_onstrength;
+ bool autocvar_g_nades_bonus_client_select;
+ int autocvar_g_nades_bonus_max;
+ int autocvar_g_nades_bonus_score_max;
+ int autocvar_g_nades_bonus_score_time;
+ int autocvar_g_nades_bonus_score_time_flagcarrier;
+ int autocvar_g_nades_bonus_score_minor;
+ int autocvar_g_nades_bonus_score_low;
+ int autocvar_g_nades_bonus_score_high;
+ int autocvar_g_nades_bonus_score_medium;
+ int autocvar_g_nades_bonus_score_spree;
float autocvar_g_nades_ice_freeze_time;
float autocvar_g_nades_ice_health;
- float autocvar_g_nades_ice_explode;
- float autocvar_g_nades_ice_teamcheck;
+ bool autocvar_g_nades_ice_explode;
+ bool autocvar_g_nades_ice_teamcheck;
float autocvar_g_nades_heal_time;
float autocvar_g_nades_heal_rate;
float autocvar_g_nades_heal_friend;
float autocvar_g_campcheck_damage;
float autocvar_g_campcheck_distance;
float autocvar_g_campcheck_interval;
- float autocvar_g_jump_grunt;
- float autocvar_g_overkill_powerups_replace;
+ bool autocvar_g_jump_grunt;
+ bool autocvar_g_overkill_powerups_replace;
float autocvar_g_overkill_superguns_respawn_time;
- float autocvar_g_overkill_100h_anyway;
- float autocvar_g_overkill_100a_anyway;
- float autocvar_g_overkill_ammo_charge;
+ bool autocvar_g_overkill_100h_anyway;
+ bool autocvar_g_overkill_100a_anyway;
+ bool autocvar_g_overkill_ammo_charge;
float autocvar_g_overkill_ammo_charge_notice;
float autocvar_g_overkill_ammo_charge_limit;
float autocvar_g_spawn_near_teammate_distance;
- float autocvar_g_spawn_near_teammate_ignore_spawnpoint;
+ bool autocvar_g_spawn_near_teammate_ignore_spawnpoint;
float autocvar_g_spawn_near_teammate_ignore_spawnpoint_delay;
float autocvar_g_spawn_near_teammate_ignore_spawnpoint_delay_death;
- float autocvar_g_spawn_near_teammate_ignore_spawnpoint_check_health;
- float autocvar_g_spawn_near_teammate_ignore_spawnpoint_closetodeath;
+ int autocvar_g_spawn_near_teammate_ignore_spawnpoint_check_health;
+ bool autocvar_g_spawn_near_teammate_ignore_spawnpoint_closetodeath;
+ bool autocvar_g_physics_clientselect;
+ string autocvar_g_physics_clientselect_options;
+ string autocvar_g_physics_clientselect_default;
+ bool autocvar_g_buffs_effects;
float autocvar_g_buffs_waypoint_distance;
- float autocvar_g_buffs_randomize;
+ bool autocvar_g_buffs_randomize;
float autocvar_g_buffs_random_lifetime;
- float autocvar_g_buffs_random_location;
- float autocvar_g_buffs_random_location_attempts;
- float autocvar_g_buffs_spawn_count;
- float autocvar_g_buffs_replace_powerups;
+ bool autocvar_g_buffs_random_location;
+ int autocvar_g_buffs_random_location_attempts;
+ int autocvar_g_buffs_spawn_count;
+ bool autocvar_g_buffs_replace_powerups;
float autocvar_g_buffs_cooldown_activate;
float autocvar_g_buffs_cooldown_respawn;
float autocvar_g_buffs_resistance_blockpercent;
float autocvar_g_buffs_vengeance_damage_multiplier;
float autocvar_g_buffs_bash_force;
float autocvar_g_buffs_bash_force_self;
- float autocvar_g_buffs_disability_time;
+ float autocvar_g_buffs_disability_slowtime;
float autocvar_g_buffs_disability_speed;
float autocvar_g_buffs_disability_rate;
+ float autocvar_g_buffs_disability_weaponspeed;
float autocvar_g_buffs_speed_speed;
float autocvar_g_buffs_speed_rate;
+ float autocvar_g_buffs_speed_weaponspeed;
float autocvar_g_buffs_speed_damage_take;
float autocvar_g_buffs_speed_regen;
float autocvar_g_buffs_vampire_damage_steal;
float autocvar_g_buffs_invisible_alpha;
float autocvar_g_buffs_flight_gravity;
float autocvar_g_buffs_jump_height;
+ float autocvar_g_buffs_inferno_burntime_factor;
+ float autocvar_g_buffs_inferno_burntime_min_time;
+ float autocvar_g_buffs_inferno_burntime_target_damage;
+ float autocvar_g_buffs_inferno_burntime_target_time;
+ float autocvar_g_buffs_inferno_damagemultiplier;
+ float autocvar_g_buffs_swapper_range;
+ float autocvar_g_buffs_magnet_range_item;
+ float autocvar_sv_player_scale;
#endif
#include "g_damage.qh"
-
- #if defined(CSQC)
- #elif defined(MENUQC)
- #elif defined(SVQC)
- #include "../warpzonelib/common.qh"
- #include "../common/constants.qh"
- #include "../common/teams.qh"
- #include "../common/util.qh"
- #include "../common/weapons/weapons.qh"
- #include "weapons/accuracy.qh"
- #include "weapons/csqcprojectile.qh"
- #include "weapons/selection.qh"
- #include "t_items.qh"
- #include "autocvars.qh"
- #include "constants.qh"
- #include "defs.qh"
- #include "../common/notifications.qh"
- #include "../common/deathtypes.qh"
- #include "mutators/mutators_include.qh"
- #include "../common/turrets/turrets.qh"
- #include "../common/turrets/sv_turrets.qh"
- #include "vehicles/vehicles_def.qh"
- #include "../csqcmodellib/sv_model.qh"
- #include "../common/playerstats.qh"
- #include "g_hook.qh"
- #include "scores.qh"
- #include "spawnpoints.qh"
- #endif
-
- float Damage_DamageInfo_SendEntity(entity to, float sf)
+ #include "_all.qh"
+
+ #include "g_hook.qh"
+ #include "mutators/mutators_include.qh"
+ #include "scores.qh"
+ #include "waypointsprites.qh"
+ #include "spawnpoints.qh"
-#include "tturrets/include/turrets_early.qh"
+ #include "t_items.qh"
+ #include "../common/vehicles/sv_vehicles.qh"
+ #include "weapons/accuracy.qh"
+ #include "weapons/csqcprojectile.qh"
+ #include "weapons/selection.qh"
+ #include "../common/buffs.qh"
+ #include "../common/constants.qh"
+ #include "../common/deathtypes.qh"
+ #include "../common/notifications.qh"
+ #include "../common/movetypes/movetypes.qh"
+ #include "../common/playerstats.qh"
+ #include "../common/teams.qh"
+ #include "../common/util.qh"
+ #include "../common/weapons/all.qh"
+ #include "../csqcmodellib/sv_model.qh"
+ #include "../warpzonelib/common.qh"
+
+ float Damage_DamageInfo_SendEntity(entity to, int sf)
{
WriteByte(MSG_ENTITY, ENT_CLIENT_DAMAGEINFO);
WriteShort(MSG_ENTITY, self.projectiledeathtype);
return true;
}
- void Damage_DamageInfo(vector org, float coredamage, float edgedamage, float rad, vector force, float deathtype, float bloodtype, entity dmgowner)
+ void Damage_DamageInfo(vector org, float coredamage, float edgedamage, float rad, vector force, int deathtype, float bloodtype, entity dmgowner)
{
// TODO maybe call this from non-edgedamage too?
// TODO maybe make the client do the particle effects for the weapons and the impact sounds using this info?
Net_LinkEntity(e, false, 0.2, Damage_DamageInfo_SendEntity);
}
- float IsFlying(entity a)
- {
- if(a.flags & FL_ONGROUND)
- return 0;
- if(a.waterlevel >= WATERLEVEL_SWIMMING)
- return 0;
- traceline(a.origin, a.origin - '0 0 48', MOVE_NORMAL, a);
- if(trace_fraction < 1)
- return 0;
- return 1;
- }
-
void UpdateFrags(entity player, float f)
{
PlayerTeamScore_AddScore(player, f);
}
- void GiveFrags (entity attacker, entity targ, float f, float deathtype)
+ void GiveFrags (entity attacker, entity targ, float f, int deathtype)
{
// TODO route through PlayerScores instead
if(gameover) return;
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
}
entity oldself;
oldself = self;
self = attacker;
- frag_attacker = attacker;
- frag_target = targ;
- frag_score = f;
- if(MUTATOR_CALLHOOK(GiveFragsForKill))
+ if(MUTATOR_CALLHOOK(GiveFragsForKill, attacker, targ, f))
{
f = frag_score;
self = oldself;
return s;
}
- void LogDeath(string mode, float deathtype, entity killer, entity killed)
+ void LogDeath(string mode, int deathtype, entity killer, entity killed)
{
string s;
if(!autocvar_sv_eventlog)
void Obituary_SpecialDeath(
entity notif_target,
float murder,
- float deathtype,
+ int deathtype,
string s1, string s2, string s3,
float f1, float f2, float f3)
{
float Obituary_WeaponDeath(
entity notif_target,
float murder,
- float deathtype,
+ int deathtype,
string s1, string s2, string s3,
float f1, float f2)
{
if(death_weapon)
{
w_deathtype = deathtype;
- float death_message = WEP_ACTION(death_weapon, ((murder) ? WR_KILLMESSAGE : WR_SUICIDEMESSAGE));
+ int death_message = WEP_ACTION(death_weapon, ((murder) ? WR_KILLMESSAGE : WR_SUICIDEMESSAGE));
w_deathtype = false;
- if(death_message)
+ if (death_message)
{
Send_Notification_WOCOVA(
NOTIF_ONE,
return false;
}
- void Obituary(entity attacker, entity inflictor, entity targ, float deathtype)
+ void Obituary(entity attacker, entity inflictor, entity targ, int deathtype)
{
// Sanity check
if (!IS_PLAYER(targ)) { backtrace("Obituary called on non-player?!\n"); return; }
);
}
+ float f3 = 0;
+ if(deathtype == DEATH_BUFF)
+ f3 = attacker.buffs;
+
if (!Obituary_WeaponDeath(targ, true, deathtype, targ.netname, attacker.netname, deathlocation, targ.killcount, kill_count_to_attacker))
- Obituary_SpecialDeath(targ, true, deathtype, targ.netname, attacker.netname, deathlocation, targ.killcount, kill_count_to_attacker, 0);
+ Obituary_SpecialDeath(targ, true, deathtype, targ.netname, attacker.netname, deathlocation, targ.killcount, kill_count_to_attacker, f3);
}
}
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.iceblock = world;
}
- void Damage (entity targ, entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
+ void Damage (entity targ, entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
{
float mirrordamage;
float mirrorforce;
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
}
// should this be changed at all? If so, in what way?
- frag_attacker = attacker;
- frag_target = targ;
- frag_damage = damage;
- frag_force = force;
- frag_deathtype = deathtype;
- frag_mirrordamage = mirrordamage;
- MUTATOR_CALLHOOK(PlayerDamage_Calculate);
+ MUTATOR_CALLHOOK(PlayerDamage_Calculate, attacker, targ, deathtype, damage, mirrordamage, force);
damage = frag_damage;
mirrordamage = frag_mirrordamage;
force = frag_force;
{
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;
}
// count the damage
if(attacker)
if(!targ.deadflag)
- if(deathtype != DEATH_BUFF_VENGEANCE)
+ if(deathtype != DEATH_BUFF)
if(targ.takedamage == DAMAGE_AIM)
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.turret_flags & TUR_FLAG_ISTURRET) && victim.active == ACTIVE_ACTIVE) || (victim.flags & FL_MONSTER))
- if(IS_PLAYER(victim) || IS_TURRET(victim) || IS_MONSTER(victim))
++ if(IS_PLAYER(victim) || (IS_TURRET(victim) && victim.active == ACTIVE_ACTIVE) || IS_MONSTER(victim))
{
if(DIFF_TEAM(victim, attacker) && !victim.frozen)
{
farcent.think = SUB_Remove;
}
else
+ {
self.velocity = self.velocity + farce;
+ self.move_velocity = self.velocity;
+ }
self.flags &= ~FL_ONGROUND;
+ self.move_flags &= ~FL_ONGROUND;
UpdateCSQCProjectile(self);
}
// apply damage
}
}
- float RadiusDamageForSource (entity inflictor, vector inflictororigin, vector inflictorvelocity, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float inflictorselfdamage, float forceintensity, float deathtype, entity directhitentity)
+ float RadiusDamageForSource (entity inflictor, vector inflictororigin, vector inflictorvelocity, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float inflictorselfdamage, float forceintensity, int deathtype, entity directhitentity)
// Returns total damage applies to creatures
{
entity targ;
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)
RadiusDamage_running = 0;
if(!DEATH_ISSPECIAL(deathtype))
- accuracy_add(attacker, DEATH_WEAPONOFWEAPONDEATH(deathtype), 0, min(coredamage, stat_damagedone));
+ accuracy_add(attacker, DEATH_WEAPONOF(deathtype), 0, min(coredamage, stat_damagedone));
return total_damage_to_creatures;
}
- float RadiusDamage (entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float forceintensity, float deathtype, entity directhitentity)
+ float RadiusDamage (entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float forceintensity, int deathtype, entity directhitentity)
{
return RadiusDamageForSource (inflictor, (inflictor.origin + (inflictor.mins + inflictor.maxs) * 0.5), inflictor.velocity, attacker, coredamage, edgedamage, rad, cantbe, mustbe, false, forceintensity, deathtype, directhitentity);
}
}
}
if(accuracy_isgooddamage(o, e))
- accuracy_add(o, DEATH_WEAPONOFWEAPONDEATH(dt), 0, max(0, totaldamage - mindamage));
+ accuracy_add(o, DEATH_WEAPONOF(dt), 0, max(0, totaldamage - mindamage));
return max(0, totaldamage - mindamage); // can never be negative, but to make sure
}
else
e.fire_owner = o;
e.fire_hitsound = false;
if(accuracy_isgooddamage(o, e))
- accuracy_add(o, DEATH_WEAPONOFWEAPONDEATH(dt), 0, d);
+ accuracy_add(o, DEATH_WEAPONOF(dt), 0, d);
return d;
}
}
#include "../common/constants.qh"
#include "../common/teams.qh"
#include "../common/util.qh"
- #include "../common/weapons/weapons.qh"
+ #include "../common/weapons/all.qh"
#include "weapons/accuracy.qh"
#include "weapons/csqcprojectile.qh"
#include "weapons/selection.qh"
#include "../common/notifications.qh"
#include "../common/deathtypes.qh"
#include "mutators/mutators_include.qh"
- #include "vehicles/vehicles_def.qh"
- #include "tturrets/include/turrets_early.qh"
++ #include "../common/turrets/sv_turrets.qh"
+ #include "../common/vehicles/sv_vehicles.qh"
#include "../csqcmodellib/sv_model.qh"
#include "../common/playerstats.qh"
#include "g_hook.qh"
.float dmg_force;
.float dmg_radius;
- float Damage_DamageInfo_SendEntity(entity to, float sf);
+ float Damage_DamageInfo_SendEntity(entity to, int sf);
- void Damage_DamageInfo(vector org, float coredamage, float edgedamage, float rad, vector force, float deathtype, float bloodtype, entity dmgowner);
+ void Damage_DamageInfo(vector org, float coredamage, float edgedamage, float rad, vector force, int deathtype, float bloodtype, entity dmgowner);
float checkrules_firstblood;
// NOTE: f=0 means still count as a (positive) kill, but count no frags for it
void W_SwitchWeapon_Force(entity e, float w);
entity GiveFrags_randomweapons;
- void GiveFrags (entity attacker, entity targ, float f, float deathtype);
+ void GiveFrags (entity attacker, entity targ, float f, int deathtype);
string AppendItemcodes(string s, entity player);
- void LogDeath(string mode, float deathtype, entity killer, entity killed);
+ void LogDeath(string mode, int deathtype, entity killer, entity killed);
void Obituary_SpecialDeath(
entity notif_target,
float murder,
- float deathtype,
+ int deathtype,
string s1, string s2, string s3,
float f1, float f2, float f3);
float Obituary_WeaponDeath(
entity notif_target,
float murder,
- float deathtype,
+ int deathtype,
string s1, string s2, string s3,
float f1, float f2);
- void Obituary(entity attacker, entity inflictor, entity targ, float deathtype);
+ void Obituary(entity attacker, entity inflictor, entity targ, int deathtype);
void Ice_Think();
entity damage_inflictor;
entity damage_attacker;
- void Damage (entity targ, entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force);
+ void Damage (entity targ, entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force);
float RadiusDamage_running;
- float RadiusDamageForSource (entity inflictor, vector inflictororigin, vector inflictorvelocity, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float inflictorselfdamage, float forceintensity, float deathtype, entity directhitentity);
+ float RadiusDamageForSource (entity inflictor, vector inflictororigin, vector inflictorvelocity, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float inflictorselfdamage, float forceintensity, int deathtype, entity directhitentity);
// Returns total damage applies to creatures
- float RadiusDamage (entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float forceintensity, float deathtype, entity directhitentity);
+ float RadiusDamage (entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float forceintensity, int deathtype, entity directhitentity);
.float fire_damagepersec;
.float fire_endtime;
#include "g_world.qh"
-
+ #include "_all.qh"
+
+ #include "anticheat.qh"
+ #include "antilag.qh"
+ #include "bot/bot.qh"
+ #include "campaign.qh"
+ #include "cheats.qh"
+ #include "cl_client.qh"
+ #include "command/common.qh"
+ #include "command/getreplies.qh"
+ #include "command/sv_cmd.qh"
+ #include "command/vote.qh"
+ #include "g_hook.qh"
+ #include "ipban.qh"
+ #include "mapvoting.qh"
+ #include "mutators/mutators_include.qh"
+ #include "race.qh"
+ #include "scores.qh"
+ #include "teamplay.qh"
+ #include "waypointsprites.qh"
+ #include "weapons/weaponstats.qh"
#include "../common/buffs.qh"
-
- #if defined(CSQC)
- #elif defined(MENUQC)
- #elif defined(SVQC)
- #include "../common/constants.qh"
- #include "../common/stats.qh"
- #include "../common/teams.qh"
- #include "../common/util.qh"
- #include "../common/monsters/sv_monsters.qh"
- #include "../common/weapons/weapons.qh"
- #include "weapons/weaponstats.qh"
- #include "autocvars.qh"
- #include "constants.qh"
- #include "defs.qh"
- #include "../common/notifications.qh"
- #include "mutators/mutators_include.qh"
- #include "campaign.qh"
- #include "../common/mapinfo.qh"
- #include "command/common.qh"
- #include "command/vote.qh"
- #include "command/getreplies.qh"
- #include "command/sv_cmd.qh"
- #include "anticheat.qh"
- #include "cheats.qh"
- #include "../common/turrets/turrets.qh"
- #include "../common/playerstats.qh"
- #include "g_hook.qh"
- #include "scores.qh"
- #include "mapvoting.qh"
- #include "ipban.qh"
- #include "race.qh"
- #include "antilag.qh"
- #include "secret.qh"
- #endif
+ #include "../common/constants.qh"
+ #include "../common/deathtypes.qh"
+ #include "../common/effects.qh"
+ #include "../common/mapinfo.qh"
+ #include "../common/monsters/all.qh"
+ #include "../common/monsters/sv_monsters.qh"
+ #include "../common/vehicles/vehicles.qh"
+ #include "../common/notifications.qh"
+ #include "../common/playerstats.qh"
+ #include "../common/stats.qh"
+ #include "../common/teams.qh"
+ #include "../common/util.qh"
+ #include "../common/items/all.qh"
+ #include "../common/weapons/all.qh"
const float LATENCY_THINKRATE = 10;
.float latency_sum;
float world_initialized;
string GetGametype();
- void GotoNextMap(float reinit);
void ShuffleMaplist();
- float(float reinit) DoNextMapOverride;
void SetDefaultAlpha()
{
BADCVAR("g_configversion");
BADCVAR("g_maplist_index");
BADCVAR("halflifebsp");
+ BADCVAR("sv_mapformat_is_quake2");
+ BADCVAR("sv_mapformat_is_quake3");
BADPREFIX("sv_world");
// client
BADCVAR("g_domination_default_teams");
BADCVAR("g_freezetag");
BADCVAR("g_freezetag_teams");
+ BADCVAR("g_invasion_teams");
BADCVAR("g_keepaway");
BADCVAR("g_keyhunt");
BADCVAR("g_keyhunt_teams");
BADCVAR("g_ca_teams_override");
BADCVAR("g_ctf_ignore_frags");
BADCVAR("g_domination_point_limit");
+ BADCVAR("g_domination_teams_override");
BADCVAR("g_freezetag_teams_override");
BADCVAR("g_friendlyfire");
BADCVAR("g_fullbrightitems");
BADCVAR("g_nexball_goallimit");
BADCVAR("g_powerups");
BADCVAR("g_start_delay");
+ BADCVAR("g_tdm_teams_override");
BADCVAR("g_warmup");
BADCVAR("g_weapon_stay"); BADPRESUFFIX("g_", "_weapon_stay");
BADCVAR("hostname");
}
entity randomseed;
- float RandomSeed_Send(entity to, float sf)
+ float RandomSeed_Send(entity to, int sf)
{
WriteByte(MSG_ENTITY, ENT_CLIENT_RANDOMSEED);
WriteShort(MSG_ENTITY, self.cnt);
self.classname = "worldspawn"; // safeguard against various stuff ;)
// needs to be done so early because of the constants they create
- CALL_ACCUMULATED_FUNCTION(RegisterWeapons);
+ static_init();
+ CALL_ACCUMULATED_FUNCTION(RegisterTurrets);
- CALL_ACCUMULATED_FUNCTION(RegisterMonsters);
- CALL_ACCUMULATED_FUNCTION(RegisterGametypes);
CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
- CALL_ACCUMULATED_FUNCTION(RegisterBuffs);
+ CALL_ACCUMULATED_FUNCTION(RegisterEffects);
+ CALL_ACCUMULATED_FUNCTION(RegisterVehicles);
MapInfo_Enumerate();
MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0);
void Map_MarkAsRecent(string m);
float world_already_spawned;
void Nagger_Init();
+ void Item_ItemsTime_Init();
void ClientInit_Spawn();
void WeaponStats_Init();
void WeaponStats_Shutdown();
+ void Physics_AddStats();
void spawnfunc_worldspawn (void)
{
- float fd, l, i, j, n;
+ float fd, l, j, n;
string s;
cvar = cvar_normal;
server_is_dedicated = (stof(cvar_defstring("is_dedicated")) ? true : false);
// needs to be done so early because of the constants they create
- CALL_ACCUMULATED_FUNCTION(RegisterWeapons);
+ static_init();
+ CALL_ACCUMULATED_FUNCTION(RegisterTurrets);
- CALL_ACCUMULATED_FUNCTION(RegisterMonsters);
- CALL_ACCUMULATED_FUNCTION(RegisterGametypes);
CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
- CALL_ACCUMULATED_FUNCTION(RegisterBuffs);
+ CALL_ACCUMULATED_FUNCTION(RegisterEffects);
+ CALL_ACCUMULATED_FUNCTION(RegisterVehicles);
ServerProgsDB = db_load(strcat("server.db", autocvar_sessionid));
// character set: ASCII 33-126 without the following characters: : ; ' " \ $
if(autocvar_sv_eventlog)
{
- s = sprintf("%d.%s.%06d", ftos(autocvar_sv_eventlog_files_counter), strftime(false, "%s"), floor(random() * 1000000));
+ s = sprintf("%d.%s.%06d", itos(autocvar_sv_eventlog_files_counter), strftime(false, "%s"), floor(random() * 1000000));
matchid = strzone(s);
GameLogEcho(strcat(":gamestart:", GetGametype(), "_", GetMapname(), ":", s));
s = ":gameinfo:mutators:LIST";
- ret_string = s;
- MUTATOR_CALLHOOK(BuildMutatorsString);
+ MUTATOR_CALLHOOK(BuildMutatorsString, s);
s = ret_string;
// simple, probably not good in the mutator system
WeaponStats_Init();
WepSet_AddStat();
+ WepSet_AddStat_InMap();
addstat(STAT_SWITCHWEAPON, AS_INT, switchweapon);
addstat(STAT_SWITCHINGWEAPON, AS_INT, switchingweapon);
addstat(STAT_GAMESTARTTIME, AS_FLOAT, stat_game_starttime);
addstat(STAT_ARC_HEAT, AS_FLOAT, arc_heat_percent);
+ // items time
+ addstat(STAT_ARMOR_LARGE_TIME, AS_FLOAT, item_armor_large_time);
+ addstat(STAT_HEALTH_MEGA_TIME, AS_FLOAT, item_health_mega_time);
+ addstat(STAT_INVISIBLE_TIME, AS_FLOAT, item_invisible_time);
+ addstat(STAT_SPEED_TIME, AS_FLOAT, item_speed_time);
+ addstat(STAT_EXTRALIFE_TIME, AS_FLOAT, item_extralife_time);
+ addstat(STAT_STRENGTH_TIME, AS_FLOAT, item_strength_time);
+ addstat(STAT_SHIELD_TIME, AS_FLOAT, item_shield_time);
+ addstat(STAT_FUELREGEN_TIME, AS_FLOAT, item_fuelregen_time);
+ addstat(STAT_JETPACK_TIME, AS_FLOAT, item_jetpack_time);
+ addstat(STAT_SUPERWEAPONS_TIME, AS_FLOAT, item_superweapons_time);
+ Item_ItemsTime_Init();
+
// freeze attacks
addstat(STAT_FROZEN, AS_INT, frozen);
addstat(STAT_REVIVE_PROGRESS, AS_FLOAT, revive_progress);
- // g_movementspeed hack
- addstat(STAT_MOVEVARS_AIRSPEEDLIMIT_NONQW, AS_FLOAT, stat_sv_airspeedlimit_nonqw);
- addstat(STAT_MOVEVARS_MAXSPEED, AS_FLOAT, stat_sv_maxspeed);
- addstat(STAT_MOVEVARS_AIRACCEL_QW, AS_FLOAT, stat_sv_airaccel_qw);
- addstat(STAT_MOVEVARS_AIRSTRAFEACCEL_QW, AS_FLOAT, stat_sv_airstrafeaccel_qw);
+ // physics
+ Physics_AddStats();
+
+ // new properties
+ addstat(STAT_MOVEVARS_JUMPVELOCITY, AS_FLOAT, stat_sv_jumpvelocity);
+ addstat(STAT_MOVEVARS_AIRACCEL_QW_STRETCHFACTOR, AS_FLOAT, stat_sv_airaccel_qw_stretchfactor);
+ addstat(STAT_MOVEVARS_MAXAIRSTRAFESPEED, AS_FLOAT, stat_sv_maxairstrafespeed);
+ addstat(STAT_MOVEVARS_MAXAIRSPEED, AS_FLOAT, stat_sv_maxairspeed);
+ addstat(STAT_MOVEVARS_AIRSTRAFEACCELERATE, AS_FLOAT, stat_sv_airstrafeaccelerate);
+ addstat(STAT_MOVEVARS_WARSOWBUNNY_TURNACCEL, AS_FLOAT, stat_sv_warsowbunny_turnaccel);
+ addstat(STAT_MOVEVARS_AIRACCEL_SIDEWAYS_FRICTION, AS_FLOAT, stat_sv_airaccel_sideways_friction);
+ addstat(STAT_MOVEVARS_AIRCONTROL, AS_FLOAT, stat_sv_aircontrol);
+ addstat(STAT_MOVEVARS_AIRCONTROL_POWER, AS_FLOAT, stat_sv_aircontrol_power);
+ addstat(STAT_MOVEVARS_AIRCONTROL_PENALTY, AS_FLOAT, stat_sv_aircontrol_penalty);
+ addstat(STAT_MOVEVARS_WARSOWBUNNY_AIRFORWARDACCEL, AS_FLOAT, stat_sv_warsowbunny_airforwardaccel);
+ addstat(STAT_MOVEVARS_WARSOWBUNNY_TOPSPEED, AS_FLOAT, stat_sv_warsowbunny_topspeed);
+ addstat(STAT_MOVEVARS_WARSOWBUNNY_ACCEL, AS_FLOAT, stat_sv_warsowbunny_accel);
+ addstat(STAT_MOVEVARS_WARSOWBUNNY_BACKTOSIDERATIO, AS_FLOAT, stat_sv_warsowbunny_backtosideratio);
+ addstat(STAT_MOVEVARS_FRICTION, AS_FLOAT, stat_sv_friction);
+ addstat(STAT_MOVEVARS_ACCELERATE, AS_FLOAT, stat_sv_accelerate);
+ addstat(STAT_MOVEVARS_STOPSPEED, AS_FLOAT, stat_sv_stopspeed);
+ addstat(STAT_MOVEVARS_AIRACCELERATE, AS_FLOAT, stat_sv_airaccelerate);
+ addstat(STAT_MOVEVARS_AIRSTOPACCELERATE, AS_FLOAT, stat_sv_airstopaccelerate);
// secrets
addstat(STAT_SECRETS_TOTAL, AS_FLOAT, stat_secrets_total);
maplist_reply = strzone(getmaplist());
lsmaps_reply = strzone(getlsmaps());
monsterlist_reply = strzone(getmonsterlist());
- for(i = 0; i < 10; ++i)
+ for(int i = 0; i < 10; ++i)
{
s = getrecords(i);
if (s)
{
s = "";
n = tokenize_console(cvar_string("sv_curl_serverpackages"));
- for(i = 0; i < n; ++i)
+ for(int i = 0; i < n; ++i)
if(substring(argv(i), -18, -1) != "-serverpackage.txt")
if(substring(argv(i), -14, -1) != ".serverpackage") // OLD legacy
s = strcat(s, " ", argv(i));
if(fd >= 0)
{
j = search_getsize(fd);
- for(i = 0; i < j; ++i)
+ for(int i = 0; i < j; ++i)
s = strcat(s, " ", search_getfilename(fd, i));
search_end(fd);
}
if(fd >= 0)
{
j = search_getsize(fd);
- for(i = 0; i < j; ++i)
+ for(int i = 0; i < j; ++i)
s = strcat(s, " ", search_getfilename(fd, i));
search_end(fd);
}
{
entity head;
FOR_EACH_PLAYER(head)
- head.winning = (head.field == value);
+ head.winning = (head.(field) == value);
}
// set the .winning flag for those players with a given field value
{
entity head;
FOR_EACH_PLAYER(head)
- if(head.field == value)
+ if (head.(field) == value)
head.winning = 1;
}
if(have_team_spawns <= 0)
return WINNING_NO;
- if(autocvar_g_spawn_useallspawns <= 0)
+ if(!autocvar_g_spawn_useallspawns)
return WINNING_NO;
if(!some_spawn_has_been_used)
Exit deathmatch games upon conditions
============
*/
- void ReadyRestart();
void CheckRules_World()
{
float timelimit;
- #if defined(CSQC)
- #elif defined(MENUQC)
- #elif defined(SVQC)
- #include "miscfunctions.qh"
- #include "../dpdefs/progsdefs.qh"
- #include "../dpdefs/dpextensions.qh"
- #include "../common/playerstats.qh"
- #include "../warpzonelib/anglestransform.qh"
- #include "../warpzonelib/server.qh"
- #include "../common/constants.qh"
- #include "../common/teams.qh"
- #include "../common/util.qh"
- #include "../common/urllib.qh"
- #include "../common/command/generic.qh"
- #include "../common/weapons/weapons.qh"
- #include "weapons/accuracy.qh"
- #include "weapons/csqcprojectile.qh"
- #include "weapons/selection.qh"
- #include "t_items.qh"
- #include "autocvars.qh"
- #include "constants.qh"
- #include "defs.qh"
- #include "../common/notifications.qh"
- #include "../common/deathtypes.qh"
- #include "mutators/mutators_include.qh"
- #include "../common/mapinfo.qh"
- #include "command/common.qh"
- #include "../csqcmodellib/sv_model.qh"
- #include "ipban.qh"
- #endif
+ #include "miscfunctions.qh"
+ #include "_all.qh"
+ #include "antilag.qh"
+ #include "command/common.qh"
+ #include "constants.qh"
+ #include "g_hook.qh"
+ #include "ipban.qh"
+ #include "mutators/mutators_include.qh"
-#include "tturrets/include/turrets_early.qh"
+ #include "t_items.qh"
+ #include "weapons/accuracy.qh"
+ #include "weapons/csqcprojectile.qh"
+ #include "weapons/selection.qh"
+ #include "../common/command/generic.qh"
+ #include "../common/constants.qh"
+ #include "../common/deathtypes.qh"
+ #include "../common/mapinfo.qh"
+ #include "../common/notifications.qh"
+ #include "../common/playerstats.qh"
+ #include "../common/teams.qh"
+ #include "../common/triggers/subs.qh"
+ #include "../common/urllib.qh"
+ #include "../common/util.qh"
++#include "../common/turrets/sv_turrets.qh"
+ #include "../common/weapons/all.qh"
+ #include "../csqcmodellib/sv_model.qh"
+ #include "../warpzonelib/anglestransform.qh"
+ #include "../warpzonelib/server.qh"
void crosshair_trace(entity pl)
{
void GameLogEcho(string s)
{
string fn;
- float matches;
+ int matches;
if (autocvar_sv_eventlog_files)
{
{
logfile_open = true;
matches = autocvar_sv_eventlog_files_counter + 1;
- cvar_set("sv_eventlog_files_counter", ftos(matches));
+ cvar_set("sv_eventlog_files_counter", itos(matches));
fn = ftos(matches);
if (strlen(fn) < 8)
fn = strcat(substring("00000000", 0, 8 - strlen(fn)), fn);
return nearest_entity[0];
}
- void spawnfunc_target_location()
- {
- self.classname = "target_location";
- // location name in netname
- // eventually support: count, teamgame selectors, line of sight?
- }
-
- void spawnfunc_info_location()
- {
- self.classname = "target_location";
- self.message = self.netname;
- }
-
string NearestLocation(vector p)
{
entity loc;
wep = self.cnt;
replacement = WEP_NAME(wep);
} else if (escape == "W") {
- if (self.items & IT_SHELLS) replacement = "shells";
- else if (self.items & IT_NAILS) replacement = "bullets";
- else if (self.items & IT_ROCKETS) replacement = "rockets";
- else if (self.items & IT_CELLS) replacement = "cells";
- else if (self.items & IT_PLASMA) replacement = "plasma";
+ if (self.items & ITEM_Shells.m_itemid) replacement = "shells";
+ else if (self.items & ITEM_Bullets.m_itemid) replacement = "bullets";
+ else if (self.items & ITEM_Rockets.m_itemid) replacement = "rockets";
+ else if (self.items & ITEM_Cells.m_itemid) replacement = "cells";
+ else if (self.items & ITEM_Plasma.m_itemid) replacement = "plasma";
else replacement = "batteries"; // ;)
} else if (escape == "x") {
replacement = cursor_ent.netname;
{
if (f < 0)
{
- if (self.field)
- strunzone(self.field);
- self.field = string_null;
+ if (self.(field))
+ strunzone(self.(field));
+ self.(field) = string_null;
}
else if (f > 0)
{
if (thisname == name)
{
- if (self.field)
- strunzone(self.field);
- self.field = strzone(argv(f + 1));
+ if (self.(field))
+ strunzone(self.(field));
+ self.(field) = strzone(argv(f + 1));
}
}
else
if (f >= 0) // also initialize to the fitting value for "" when sending cvars out
if (thisname == name)
{
- string s;
- s = func(strcat1(self.field));
- if (s != self.field)
+ string s = func(strcat1(self.(field)));
+ if (s != self.(field))
{
- strunzone(self.field);
- self.field = strzone(s);
+ strunzone(self.(field));
+ self.(field) = strzone(s);
}
}
}
else if (f > 0)
{
if (thisname == name)
- self.field = stof(argv(f + 1));
+ self.(field) = stof(argv(f + 1));
}
else
stuffcmd(self, strcat("cl_cmd sendcvar ", name, "\n"));
{
if (thisname == name)
{
- if(!self.field)
+ if (!self.(field))
{
- self.field = stof(argv(f + 1));
- if(!self.field)
- self.field = -1;
+ self.(field) = stof(argv(f + 1));
+ if (!self.(field))
+ self.(field) = -1;
}
}
}
else
{
- if(!self.field)
+ if (!self.(field))
stuffcmd(self, strcat("cl_cmd sendcvar ", name, "\n"));
}
}
get_cvars_f = f;
get_cvars_s = s;
-
MUTATOR_CALLHOOK(GetCvars);
Notification_GetCvars();
GetCvars_handleFloat(s, f, cvar_cl_autoscreenshot, "cl_autoscreenshot");
GetCvars_handleFloat(s, f, cvar_cl_jetpack_jump, "cl_jetpack_jump");
GetCvars_handleString(s, f, cvar_g_xonoticversion, "g_xonoticversion");
+ GetCvars_handleString(s, f, cvar_cl_physics, "cl_physics");
GetCvars_handleFloat(s, f, cvar_cl_handicap, "cl_handicap");
GetCvars_handleFloat(s, f, cvar_cl_clippedspectating, "cl_clippedspectating");
GetCvars_handleString_Fixup(s, f, cvar_cl_weaponpriority, "cl_weaponpriority", W_FixWeaponOrder_ForceComplete_AndBuildImpulseList);
d = false;
}
else if (g_cts)
- d = (i == WEP_SHOTGUN);
+ d = (i == WEP_SHOTGUN.m_id);
else if (g_nexball)
d = 0; // weapon is set a few lines later
else
d = !(!weaponinfo.weaponstart);
if(g_grappling_hook) // if possible, redirect off-hand hook to on-hand hook
- d |= (i == WEP_HOOK);
+ d |= (i == WEP_HOOK.m_id);
if(!g_cts && (weaponinfo.spawnflags & WEP_FLAG_MUTATORBLOCKED)) // never default mutator blocked guns
d = 0;
s = cvar_string("g_weaponarena");
if (s == "0" || s == "")
{
- if(g_ca)
+ if(g_ca || g_freezetag)
s = "most";
}
warmup_start_weapons_default = start_weapons_default;
warmup_start_weapons_defaultmask = start_weapons_defaultmask;
- if (!g_weaponarena && !g_ca)
+ if (!g_weaponarena && !g_ca && !g_freezetag)
{
warmup_start_ammo_shells = cvar("g_warmup_start_ammo_shells");
warmup_start_ammo_nails = cvar("g_warmup_start_ammo_nails");
}
if (g_jetpack)
- start_items |= IT_JETPACK;
+ start_items |= ITEM_Jetpack.m_itemid;
MUTATOR_CALLHOOK(SetStartItems);
- if ((start_items & IT_JETPACK) || (g_grappling_hook && (start_weapons & WEPSET_HOOK)))
+ if ((start_items & ITEM_Jetpack.m_itemid) || (g_grappling_hook && (start_weapons & WEPSET_HOOK)))
{
- start_items |= IT_FUEL_REGEN;
+ start_items |= ITEM_JetpackRegen.m_itemid;
start_ammo_fuel = max(start_ammo_fuel, cvar("g_balance_fuel_rotstable"));
warmup_start_ammo_fuel = max(warmup_start_ammo_fuel, cvar("g_balance_fuel_rotstable"));
}
warmup_start_ammo_fuel = max(0, warmup_start_ammo_fuel);
}
- float sound_allowed(float _dest, entity e)
+ float sound_allowed(float destin, entity e)
{
// sounds from world may always pass
for (;;)
break;
}
// sounds to self may always pass
- if (_dest == MSG_ONE)
+ if (destin == MSG_ONE)
if (e == msg_entity)
return true;
// sounds by players can be removed
}
#undef sound
- void sound(entity e, float chan, string samp, float vol, float _atten)
+ void sound(entity e, float chan, string samp, float vol, float attenu)
{
if (!sound_allowed(MSG_BROADCAST, e))
return;
- sound7(e, chan, samp, vol, _atten, 0, 0);
+ sound7(e, chan, samp, vol, attenu, 0, 0);
}
- void soundtoat(float _dest, entity e, vector o, float chan, string samp, float vol, float _atten)
+ void soundtoat(float _dest, entity e, vector o, float chan, string samp, float vol, float attenu)
{
float entno, idx;
entno = num_for_edict(e);
idx = precache_sound_index(samp);
- float sflags;
+ int sflags;
sflags = 0;
- _atten = floor(_atten * 64);
+ attenu = floor(attenu * 64);
vol = floor(vol * 255);
if (vol != 255)
sflags |= SND_VOLUME;
- if (_atten != 64)
+ if (attenu != 64)
sflags |= SND_ATTENUATION;
if (entno >= 8192 || chan < 0 || chan > 7)
sflags |= SND_LARGEENTITY;
if (sflags & SND_VOLUME)
WriteByte(_dest, vol);
if (sflags & SND_ATTENUATION)
- WriteByte(_dest, _atten);
+ WriteByte(_dest, attenu);
if (sflags & SND_LARGEENTITY)
{
WriteShort(_dest, entno);
precache_model ("models/misc/chatbubble.spr");
precache_model("models/ice/ice.md3");
-#ifdef TTURRETS_ENABLED
- if (autocvar_g_turrets)
- turrets_precash();
-#endif
-
// Precache all player models if desired
if (autocvar_sv_precacheplayermodels)
{
e.uncustomizeentityforclient_set = !!uncustomizer;
}
-
- void Net_LinkEntity(entity e, float docull, float dt, float(entity, float) sendfunc)
+ void Net_LinkEntity(entity e, bool docull, float dt, bool(entity, int) sendfunc)
{
vector mi, ma;
}
- entity eliminatedPlayers;
.float(entity) isEliminated;
float EliminatedPlayers_SendEntity(entity to, float sendflags)
{
#define SUB_OwnerCheck() (other && (other == self.owner))
- void RemoveGrapplingHook(entity pl);
void W_Crylink_Dequeue(entity e);
float WarpZone_Projectile_Touch_ImpactFilter_Callback()
{
.float scale2;
- float modeleffect_SendEntity(entity to, float sf)
+ float modeleffect_SendEntity(entity to, int sf)
{
float f;
WriteByte(MSG_ENTITY, ENT_CLIENT_MODELEFFECT);
#include "t_items.qh"
- #include "mutators/base.qh"
+ #include "mutators/events.qh"
#include "mutators/gamemode_race.qh"
#include "../common/constants.qh"
#include "../common/mapinfo.qh"
++#include "../common/turrets/turrets.qh"
#ifdef RELEASE
#define cvar_string_normal builtin_cvar_string
#else
string cvar_string_normal(string n)
{
- if (!(cvar_type(n) & 1))
+ if (!(cvar_type(n) & CVAR_TYPEFLAG_EXISTS))
backtrace(strcat("Attempt to access undefined cvar: ", n));
return builtin_cvar_string(n);
}
.float uncustomizeentityforclient_set;
.float nottargeted;
+ entity eliminatedPlayers;
+ void EliminatedPlayers_Init(float(entity) isEliminated_func);
+
+ string admin_name(void);
+
+ void write_recordmarker(entity pl, float tstart, float dt);
+
+ void play2all(string samp);
+
+ void DistributeEvenly_Init(float amount, float totalweight);
+ float DistributeEvenly_Get(float weight);
+
+ void modeleffect_spawn(string m, float s, float f, vector o, vector v, vector ang, vector angv, float s0, float s2, float a, float t1, float t2);
+
+ void shockwave_spawn(string m, vector org, float sz, float t1, float t2);
+
+ vector randompos(vector m1, vector m2);
+
+ void play2team(float t, string filename);
+
+ void GetCvars_handleFloat(string thisname, float f, .float field, string name);
+
+ float spamsound(entity e, float chan, string samp, float vol, float _atten);
+
+ void GetCvars_handleString(string thisname, float f, .string field, string name);
+
+ void precache_all_playermodels(string pattern);
+
+ void soundat(entity e, vector o, float chan, string samp, float vol, float _atten);
+
+ void defer(float fdelay, void() func);
+
+ void UncustomizeEntitiesRun();
+ void InitializeEntitiesRun();
+
+ void stopsoundto(float _dest, entity e, float chan);
+ void soundtoat(float _dest, entity e, vector o, float chan, string samp, float vol, float _atten);
+ float ExponentialFalloff(float mindist, float maxdist, float halflifedist, float d);
+
+ vector shotorg_adjust(vector vecs, float y_is_right, float visual);
float DistributeEvenly_amount;
float DistributeEvenly_totalweight;
- var void remove(entity e);
void objerror(string s);
void droptofloor();
void() spawnfunc_info_player_deathmatch; // needed for the other spawnpoints
float LostMovetypeFollow(entity ent);
+ string uid2name(string myuid);
+
float MoveToRandomMapLocation(entity e, float goodcontents, float badcontents, float badsurfaceflags, float attempts, float maxaboveground, float minviewdistance);
string NearestLocation(vector p);
void WarpZone_traceline_antilag (entity source, vector v1, vector v2, float nomonst, entity forent, float lag);
- #define IFTARGETED if(!self.nottargeted && self.targetname != "")
-
#define ITEM_TOUCH_NEEDKILL() (((trace_dpstartcontents | trace_dphitcontents) & DPCONTENTS_NODROP) || (trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY))
#define ITEM_DAMAGE_NEEDKILL(dt) (((dt) == DEATH_HURTTRIGGER) || ((dt) == DEATH_SLIME) || ((dt) == DEATH_LAVA) || ((dt) == DEATH_SWAMP))
#define PROJECTILE_TOUCH if(WarpZone_Projectile_Touch()) return
- #define move_out_of_solid(e) WarpZoneLib_MoveOutOfSolid(e)
-
const string STR_PLAYER = "player";
const string STR_SPECTATOR = "spectator";
const string STR_OBSERVER = "observer";
#define IS_REAL_CLIENT(v) (clienttype(v) == CLIENTTYPE_REAL)
#define IS_NOT_A_CLIENT(v) (clienttype(v) == CLIENTTYPE_NOTACLIENT)
-#define IS_TURRET(v) (v.turrcaps_flags & TFL_TURRCAPS_ISTURRET)
+ #define IS_MONSTER(v) (v.flags & FL_MONSTER)
+ #define IS_VEHICLE(v) (v.vehicle_flags & VHF_ISVEHICLE)
++#define IS_TURRET(v) (v.turret_flags & TUR_FLAG_ISTURRET)
+
#define FOR_EACH_CLIENTSLOT(v) for(v = world; (v = nextent(v)) && (num_for_edict(v) <= maxclients); )
#define FOR_EACH_CLIENT(v) FOR_EACH_CLIENTSLOT(v) if(IS_CLIENT(v))
#define FOR_EACH_REALCLIENT(v) FOR_EACH_CLIENT(v) if(IS_REAL_CLIENT(v))
const float SND_LARGEENTITY = 8;
const float SND_LARGESOUND = 16;
- // WARNING: this kills the trace globals
- #define EXACTTRIGGER_TOUCH if(WarpZoneLib_ExactTrigger_Touch()) return
- #define EXACTTRIGGER_INIT WarpZoneLib_ExactTrigger_Init()
-
const float INITPRIO_FIRST = 0;
const float INITPRIO_GAMETYPE = 0;
const float INITPRIO_GAMETYPE_FALLBACK = 1;
float sound_allowed(float dest, entity e);
void InitializeEntity(entity e, void(void) func, float order);
void SetCustomizer(entity e, float(void) customizer, void(void) uncustomizer);
- void Net_LinkEntity(entity e, float docull, float dt, float(entity, float) sendfunc);
+ void Net_LinkEntity(entity e, bool docull, float dt, bool(entity, int) sendfunc);
#endif
+ #include "gamemode_assault.qh"
+ #include "../_all.qh"
+
+ #include "gamemode.qh"
+
+ .entity sprite;
+
// random functions
void assault_objective_use()
{
activator = self;
SUB_UseTargets();
-#ifdef TTURRETS_ENABLED
entity ent, oldself;
//(Re)spawn all turrets
self = ent;
// Dubbles as teamchange
- turret_stdproc_respawn();
+ turret_respawn();
ent = find(ent, classname, "turret_main");
}
self = oldself;
-#endif
}
void assault_wall_think()
// trigger new round
// reset objectives, toggle spawnpoints, reset triggers, ...
+ void vehicles_clearreturn(entity veh);
+ void vehicles_spawn();
void assault_new_round()
{
+ entity oldself;
+ //bprint("ASSAULT: new round\n");
+
+ oldself = self;
+ // Eject players from vehicles
+ FOR_EACH_PLAYER(self)
+ {
+ if(self.vehicle)
+ vehicles_exit(VHEF_RELEASE);
+ }
+
+ self = findchainflags(vehicle_flags, VHF_ISVEHICLE);
+ while(self)
+ {
+ vehicles_clearreturn(self);
+ vehicles_spawn();
+ self = self.chain;
+ }
+
+ self = oldself;
+
// up round counter
self.winning = self.winning + 1;
+ #include "../_all.qh"
+
+ #include "gamemode.qh"
+
float autocvar_g_onslaught_spawn_at_controlpoints;
float autocvar_g_onslaught_spawn_at_generator;
float autocvar_g_onslaught_cp_proxydecap;
entity ons_red_generator;
entity ons_blue_generator;
- void ons_gib_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce)
+ void ons_gib_damage (entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector vforce)
{
self.velocity = self.velocity + vforce;
}
if(d>2)
if(random()<0.6)
- pointparticles(particleeffectnum("onslaught_generator_gib_flame"), self.origin, '0 0 0', 1);
+ Send_Effect("onslaught_generator_gib_flame", self.origin, '0 0 0', 1);
}
void ons_throwgib(vector v_from, vector v_to, string smodel, float f_lifetime, float b_burn)
if(random() < 0.9 - self.owner.health / self.owner.max_health)
if(random() < 0.01)
{
- pointparticles(particleeffectnum("electro_ballexplode"), self.origin + randompos('-50 -50 -20', '50 50 50'), '0 0 0', 1);
+ Send_Effect("electro_ballexplode", self.origin + randompos('-50 -50 -20', '50 50 50'), '0 0 0', 1);
sound(self, CH_TRIGGER, "onslaught/electricity_explode.wav", VOL_BASE, ATTEN_NORM);
}
else
- pointparticles(particleeffectnum("torch_small"), self.origin + randompos('-60 -60 -20', '60 60 60'), '0 0 0', 1);
+ Send_Effect("torch_small", self.origin + randompos('-60 -60 -20', '60 60 60'), '0 0 0', 1);
}
void onslaught_generator_damage_spawn(entity gd_owner)
for(i=0;i < 10;++i)
{
org = self.origin + randompos('-30 -30 -30' * i + '0 0 -20', '30 30 30' * i + '0 0 20');
- pointparticles(particleeffectnum("onslaught_generator_gib_explode"), org, '0 0 0', 1);
+ Send_Effect("onslaught_generator_gib_explode", org, '0 0 0', 1);
}
// Short explosion sound + small explosion
// Particles
org = self.origin + randompos(self.mins + '8 8 8', self.maxs + '-8 -8 -8');
- pointparticles(particleeffectnum("onslaught_generator_smallexplosion"), org, '0 0 0', 1);
+ Send_Effect("onslaught_generator_smallexplosion", org, '0 0 0', 1);
// rays
if(random() > 0.25 )
org = self.origin;
te_explosion(org);
onslaught_generator_shockwave_spawn(org);
- pointparticles(particleeffectnum("onslaught_generator_finalexplosion"), org, '0 0 0', 1);
+ Send_Effect("onslaught_generator_finalexplosion", org, '0 0 0', 1);
sound(self, CH_TRIGGER, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM);
}
else
self.count = self.count - 1;
}
- void onslaught_generator_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
+ void onslaught_generator_damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
{
float i;
if (damage <= 0)
else
{
// particles on every hit
- pointparticles(particleeffectnum("sparks"), hitloc, force * -1, 1);
+ Send_Effect("sparks", hitloc, force * -1, 1);
//sound on every hit
if (random() < 0.5)
float ons_notification_time_team1;
float ons_notification_time_team2;
- void onslaught_controlpoint_icon_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
+ void onslaught_controlpoint_icon_damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
{
entity oself;
float nag;
// colormod flash when shot
self.colormod = '2 2 2';
// particles on every hit
- pointparticles(particleeffectnum("sparks"), hitloc, force*-1, 1);
+ Send_Effect("sparks", hitloc, force*-1, 1);
//sound on every hit
if (random() < 0.5)
sound(self, CH_TRIGGER, "onslaught/ons_hit1.wav", VOL_BASE+0.3, ATTEN_NORM);
if (self.health < 0)
{
sound(self, CH_TRIGGER, "weapons/grenade_impact.wav", VOL_BASE, ATTEN_NORM);
- pointparticles(particleeffectnum("rocket_explode"), self.origin, '0 0 0', 1);
+ Send_Effect("rocket_explode", self.origin, '0 0 0', 1);
{
string t;
t = Team_ColoredFullName(attacker.team);
// damaged fx
if(random() < 0.6 - self.health / self.max_health)
{
- pointparticles(particleeffectnum("electricity_sparks"), self.origin + randompos('-10 -10 -20', '10 10 20'), '0 0 0', 1);
+ Send_Effect("electricity_sparks", self.origin + randompos('-10 -10 -20', '10 10 20'), '0 0 0', 1);
if(random() > 0.8)
sound(self, CH_PAIN, "onslaught/ons_spark1.wav", VOL_BASE, ATTEN_NORM);
//setsize(self, '-32 -32 0', '32 32 8');
if(random() < 0.9 - self.health / self.max_health)
- pointparticles(particleeffectnum("rage"), self.origin + 10 * randomvec(), '0 0 -1', 1);
+ Send_Effect("rage", self.origin + 10 * randomvec(), '0 0 -1', 1);
}
-
-
-
void onslaught_controlpoint_touch()
{
entity e;
return 0;
}
+MUTATOR_HOOKFUNCTION(ons_TurretSpawn)
+{
+ entity e, ee = world;
+ if(self.targetname)
+ {
+ e = find(world, target, self.targetname);
+
+ if(e != world)
+ {
+ self.team = e.team;
+ ee = e;
+ }
+ }
+
+ if(ee)
+ {
+ activator = ee;
+ self.use();
+ }
+
+ return FALSE;
+}
+
MUTATOR_HOOKFUNCTION(ons_MonsterThink)
{
entity e = find(world, targetname, self.target);
if(self.targetname)
{
e = find(world,target,self.targetname);
- if(e != world)
- {
- self.team = e.team;
- ee = e;
- }
- }
-
- if(ee)
- {
activator = ee;
self.use();
}
MUTATOR_HOOK(BuildMutatorsPrettyString, ons_BuildMutatorsPrettyString, CBC_ORDER_ANY);
MUTATOR_HOOK(BuildMutatorsString, ons_BuildMutatorsString, CBC_ORDER_ANY);
MUTATOR_HOOK(PlayerSpawn, ons_PlayerSpawn, CBC_ORDER_ANY);
+ MUTATOR_HOOK(TurretSpawn, ons_TurretSpawn, CBC_ORDER_ANY);
MUTATOR_HOOK(MonsterMove, ons_MonsterThink, CBC_ORDER_ANY);
MUTATOR_HOOK(MonsterSpawn, ons_MonsterSpawn, CBC_ORDER_ANY);
//MUTATOR_HOOK(Spawn_Score, ons_Spawn_Score, CBC_ORDER_ANY);
#include "../../common/command/markup.qh"
#include "../../common/command/rpn.qh"
#include "../../common/command/generic.qh"
- #include "../../common/command/shared_defs.qh"
+ #include "../../common/command/command.qh"
#include "../../common/net_notice.qh"
#include "../../common/animdecide.qh"
- #include "../../common/monsters/monsters.qh"
+ #include "../../common/monsters/all.qh"
#include "../../common/monsters/sv_monsters.qh"
#include "../../common/monsters/spawn.qh"
#include "../../common/weapons/config.qh"
- #include "../../common/weapons/weapons.qh"
+ #include "../../common/weapons/all.qh"
#include "../weapons/accuracy.qh"
#include "../weapons/common.qh"
#include "../weapons/csqcprojectile.qh"
#include "../../common/notifications.qh"
#include "../../common/deathtypes.qh"
#include "mutators_include.qh"
- #include "../vehicles/vehicles_def.qh"
- #include "../tturrets/include/turrets_early.qh"
++ #include "../../common/turrets/sv_turrets.qh"
+ #include "../../common/vehicles/sv_vehicles.qh"
#include "../campaign.qh"
#include "../../common/campaign_common.qh"
#include "../../common/mapinfo.qh"
#include "../playerdemo.qh"
#include "../round_handler.qh"
#include "../item_key.qh"
- #include "../secret.qh"
#include "../pathlib/pathlib.qh"
- #include "../vehicles/vehicles.qh"
- #include "../tturrets/include/turrets.qh"
++ #include "../../common/vehicles/vehicles.qh"
#endif
- #include "base.qc"
+ #include "../../common/mutators/base.qh"
#include "gamemode_assault.qc"
#include "gamemode_ca.qc"
#include "gamemode_ctf.qc"
../dpdefs/progsdefs.qh
../dpdefs/dpextensions.qh
sys-post.qh
+ ../common/util-post.qh
anticheat.qc
antilag.qc
- // assault.qc
campaign.qc
cheats.qc
cl_client.qc
cl_impulse.qc
- cl_physics.qc
cl_player.qc
csqceffects.qc
- // ctf.qc
- // domination.qc
ent_cs.qc
- func_breakable.qc
g_casings.qc
g_damage.qc
g_hook.qc
+ // g_lights.qc // TODO: was never used
g_models.qc
g_subs.qc
g_tetris.qc
- g_triggers.qc
g_violence.qc
g_world.qc
ipban.qc
item_key.qc
mapvoting.qc
miscfunctions.qc
- // mode_onslaught.qc
movelib.qc
- // nexball.qc
+ // pathlib.qc // TODO: was never used. Seems to duplicate `pathlib/`
playerdemo.qc
portals.qc
race.qc
round_handler.qc
- // runematch.qc
scores.qc
scores_rules.qc
- secret.qc
spawnpoints.qc
steerlib.qc
sv_main.qc
- target_music.qc
- target_spawn.qc
teamplay.qc
t_halflife.qc
t_items.qc
- t_jumppads.qc
- t_plats.qc
t_quake3.qc
t_quake.qc
- t_swamp.qc
- t_teleporters.qc
waypointsprites.qc
+ bot/aim.qc
bot/bot.qc
+ bot/navigation.qc
+ bot/scripting.qc
+ bot/waypoints.qc
- command/banning.qc
- command/cmd.qc
- command/common.qc
- command/getreplies.qc
- command/radarmap.qc
- command/sv_cmd.qc
- command/vote.qc
+ bot/havocbot/havocbot.qc
+ bot/havocbot/role_keyhunt.qc
+ bot/havocbot/role_onslaught.qc
+ bot/havocbot/roles.qc
+
+ command/all.qc
mutators/mutators_include.qc
mutators/mutators.qc
+ pathlib/costs.qc
+ pathlib/expandnode.qc
+ pathlib/main.qc
+ pathlib/movenode.qc
+ pathlib/path_waypoint.qc
+ pathlib/utility.qc
+
weapons/accuracy.qc
weapons/common.qc
weapons/csqcprojectile.qc // TODO
../common/buffs.qc
../common/campaign_file.qc
../common/campaign_setup.qc
- ../common/command/generic.qc
- ../common/command/markup.qc
- ../common/command/rpn.qc
+ ../common/effects.qc
../common/mapinfo.qc
- ../common/monsters/monsters.qc
+ ../common/monsters/all.qc
../common/monsters/spawn.qc
../common/monsters/sv_monsters.qc
+ ../common/movetypes/include.qc
../common/nades.qc
../common/net_notice.qc
../common/notifications.qc
+ ../common/physics.qc
../common/playerstats.qc
+ ../common/p2mathlib.qc
../common/test.qc
+ ../common/viewloc.qc
+ ../common/triggers/include.qc
../common/urllib.qc
../common/util.qc
+ ../common/vehicles/vehicles_include.qc
+
+ ../common/items/all.qc
+
+../common/turrets/sv_turrets.qc
+../common/turrets/config.qc
+../common/turrets/util.qc
+../common/turrets/turrets.qc
+../common/turrets/checkpoint.qc
+../common/turrets/targettrigger.qc
../common/weapons/config.qc
- ../common/weapons/weapons.qc // TODO
+ ../common/weapons/all.qc // TODO
../csqcmodellib/sv_model.qc
../warpzonelib/mathlib.qc
../warpzonelib/server.qc
../warpzonelib/util_server.qc
+
+ ../../mod/server/progs.inc