+ #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
+
void DamageEffect_Think()
{
// if particle distribution is enabled, slow ticrate by total number of damages
pointparticles(self.team, org, '0 0 0', 1);
}
- void DamageEffect(vector hitorg, float dmg, float type, float specnum)
+ void DamageEffect(vector hitorg, float dmg, int type, int specnum)
{
// particle effects for players and objects damaged by weapons (eg: flames coming out of victims shot with rockets)
- float life, nearestbone = 0;
+ int nearestbone = 0;
+ float life;
string specstr, effectname;
entity e;
{
specstr = species_prefix(specnum);
specstr = substring(specstr, 0, strlen(specstr) - 1);
- effectname = strreplace("BLOOD", specstr, effectname);
+ effectname = strreplace("BLOOD", specstr, effectname);
}
else { return; } // objects don't bleed
}
void Ent_DamageInfo(float isNew)
{
- float dmg, rad, edge, thisdmg, forcemul, species, hitplayer = FALSE;
+ float dmg, rad, edge, thisdmg;
+ bool hitplayer = false;
+ int species, forcemul;
vector force, thisforce;
entity oldself;
w_issilent = (w_deathtype & 0x8000);
w_deathtype = (w_deathtype & 0x7FFF);
- w_org_x = ReadCoord();
- w_org_y = ReadCoord();
- w_org_z = ReadCoord();
+ w_org.x = ReadCoord();
+ w_org.y = ReadCoord();
+ w_org.z = ReadCoord();
dmg = ReadByte();
rad = ReadByte();
DamageEffect(w_org, thisdmg, w_deathtype, species);
if(self.isplayermodel)
- hitplayer = TRUE; // this impact damaged a player
+ hitplayer = true; // this impact damaged a player
}
self = oldself;
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;
if(!DEATH_ISSPECIAL(w_deathtype))
if(!hitplayer || rad) // don't show ground impacts for hitscan weapons if a player was hit
{
- float hitwep;
-
- hitwep = DEATH_WEAPONOFWEAPONDEATH(w_deathtype);
+ int hitwep = DEATH_WEAPONOFWEAPONDEATH(w_deathtype);
w_random = prandom();
traceline(w_org - normalize(force) * 16, w_org + normalize(force) * 16, MOVE_NOMONSTERS, world);
--- /dev/null
-#include "tturrets.qh"
+ #include "mapvoting.qh"
+ #include "modeleffects.qh"
+ #include "particles.qh"
+ #include "scoreboard.qh"
+ #include "shownames.qh"
+ #include "target_music.qh"
- turrets_precache();
+ #include "tuba.qh"
+ #include "wall.qh"
+ #include "waypointsprites.qh"
+
+ #include "vehicles/vehicles.qh"
+
+ #include "../server/vehicles/bumblebee.qh"
+
+ #include "../common/net_notice.qh"
+
+ #include "../common/monsters/monsters.qh"
+
++#include "../common/turrets/cl_turrets.qh"
++#include "../common/turrets/turrets.qh"
++
+ #include "../warpzonelib/client.qh"
+
+ // --------------------------------------------------------------------------
+ // BEGIN REQUIRED CSQC FUNCTIONS
+ //include "main.qh"
+
+ entity clearentity_ent;
+ void clearentity(entity e)
+ {
+ if (!clearentity_ent)
+ {
+ clearentity_ent = spawn();
+ clearentity_ent.classname = "clearentity";
+ }
+ int n = e.entnum;
+ copyentity(clearentity_ent, e);
+ e.entnum = n;
+ }
+
+ #define DP_CSQC_ENTITY_REMOVE_IS_B0RKED
+ void menu_show_error()
+ {
+ drawstring('0 200 0', _("ERROR - MENU IS VISIBLE BUT NO MENU WAS DEFINED!"), '8 8 0', '1 0 0', 1, 0);
+ }
+
+ // CSQC_Init : Called every time the CSQC code is initialized (essentially at map load)
+ // Useful for precaching things
+
+ void menu_sub_null()
+ {
+ }
+
+ string forcefog;
+ void WaypointSprite_Load();
+ void ConsoleCommand_macro_init();
+ void CSQC_Init(void)
+ {
+ prvm_language = cvar_string("prvm_language");
+
+ #ifdef WATERMARK
+ dprintf("^4CSQC Build information: ^1%s\n", WATERMARK);
+ #endif
+
+ int i;
+
+ binddb = db_create();
+ tempdb = db_create();
+ ClientProgsDB = db_load("client.db");
+ compressShortVector_init();
+
+ draw_endBoldFont();
+ menu_visible = false;
+ menu_show = menu_show_error;
+ menu_action = func_null;
+
+ for(i = 0; i < 255; ++i)
+ if(getplayerkeyvalue(i, "viewentity") == "")
+ break;
+ maxclients = i;
+
+ //registercommand("hud_configure");
+ //registercommand("hud_save");
+ //registercommand("menu_action");
+
+ ConsoleCommand_macro_init();
+
+ registercvar("hud_usecsqc", "1");
+ registercvar("scoreboard_columns", "default");
+
+ registercvar("cl_nade_type", "3");
+ registercvar("cl_pokenade_type", "zombie");
+
+ gametype = 0;
+
+ // hud_fields uses strunzone on the titles!
+ for(i = 0; i < MAX_HUD_FIELDS; ++i)
+ hud_title[i] = strzone("(null)");
+
+ Cmd_HUD_SetFields(0);
+
+ postinit = false;
+
+ calledhooks = 0;
+
+ teams = Sort_Spawn();
+ players = Sort_Spawn();
+
+ GetTeam(NUM_SPECTATOR, true); // add specs first
+
+ // needs to be done so early because of the constants they create
+ CALL_ACCUMULATED_FUNCTION(RegisterWeapons);
++ 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);
+
+ WaypointSprite_Load();
+
+ // precaches
+ precache_model("null");
+ precache_sound("misc/hit.wav");
+ precache_sound("misc/typehit.wav");
+
+ Projectile_Precache();
+ Hook_Precache();
+ GibSplash_Precache();
+ Casings_Precache();
+ Vehicles_Precache();
+ Tuba_Precache();
+ CSQCPlayer_Precache();
+
+ if(autocvar_cl_reticle)
+ {
+ precache_pic("gfx/reticle_normal");
+ // weapon reticles are precached in weapon files
+ }
+
+ get_mi_min_max_texcoords(1); // try the CLEVER way first
+ minimapname = strcat("gfx/", mi_shortname, "_radar.tga");
+ shortmapname = mi_shortname;
+
+ if(precache_pic(minimapname) == "")
+ {
+ // but maybe we have a non-clever minimap
+ minimapname = strcat("gfx/", mi_shortname, "_mini.tga");
+ if(precache_pic(minimapname) == "")
+ minimapname = ""; // FAIL
+ else
+ get_mi_min_max_texcoords(0); // load new texcoords
+ }
+
+ mi_center = (mi_min + mi_max) * 0.5;
+ mi_scale = mi_max - mi_min;
+ minimapname = strzone(minimapname);
+
+ WarpZone_Init();
+
+ hud_skin_path = strzone(strcat("gfx/hud/", autocvar_hud_skin));
+ draw_currentSkin = strzone(strcat("gfx/menu/", cvar_string("menu_skin")));
+ }
+
+ // CSQC_Shutdown : Called every time the CSQC code is shutdown (changing maps, quitting, etc)
+ void Shutdown(void)
+ {
+ WarpZone_Shutdown();
+
+ remove(teams);
+ remove(players);
+ db_close(binddb);
+ db_close(tempdb);
+ if(autocvar_cl_db_saveasdump)
+ db_dump(ClientProgsDB, "client.db");
+ else
+ db_save(ClientProgsDB, "client.db");
+ db_close(ClientProgsDB);
+
+ if(camera_active)
+ cvar_set("chase_active",ftos(chase_active_backup));
+
+ // unset the event chasecam's chase_active
+ if(autocvar_chase_active < 0)
+ cvar_set("chase_active", "0");
+
+ if (!isdemo())
+ {
+ if (!(calledhooks & HOOK_START))
+ localcmd("\n_cl_hook_gamestart nop\n");
+ if (!(calledhooks & HOOK_END))
+ localcmd("\ncl_hook_gameend\n");
+ }
+ }
+
+ .float has_team;
+ float SetTeam(entity o, int Team)
+ {
+ entity tm;
+ if(teamplay)
+ {
+ switch(Team)
+ {
+ case -1:
+ case NUM_TEAM_1:
+ case NUM_TEAM_2:
+ case NUM_TEAM_3:
+ case NUM_TEAM_4:
+ break;
+ default:
+ if(GetTeam(Team, false) == world)
+ {
+ dprintf("trying to switch to unsupported team %d\n", Team);
+ Team = NUM_SPECTATOR;
+ }
+ break;
+ }
+ }
+ else
+ {
+ switch(Team)
+ {
+ case -1:
+ case 0:
+ break;
+ default:
+ if(GetTeam(Team, false) == world)
+ {
+ dprintf("trying to switch to unsupported team %d\n", Team);
+ Team = NUM_SPECTATOR;
+ }
+ break;
+ }
+ }
+ if(Team == -1) // leave
+ {
+ if(o.has_team)
+ {
+ tm = GetTeam(o.team, false);
+ tm.team_size -= 1;
+ o.has_team = 0;
+ return true;
+ }
+ }
+ else
+ {
+ if (!o.has_team)
+ {
+ o.team = Team;
+ tm = GetTeam(Team, true);
+ tm.team_size += 1;
+ o.has_team = 1;
+ return true;
+ }
+ else if(Team != o.team)
+ {
+ tm = GetTeam(o.team, false);
+ tm.team_size -= 1;
+ o.team = Team;
+ tm = GetTeam(Team, true);
+ tm.team_size += 1;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void Playerchecker_Think()
+ {
+ int i;
+ entity e;
+ for(i = 0; i < maxclients; ++i)
+ {
+ e = playerslots[i];
+ if(GetPlayerName(i) == "")
+ {
+ if(e.sort_prev)
+ {
+ // player disconnected
+ SetTeam(e, -1);
+ RemovePlayer(e);
+ e.sort_prev = world;
+ //e.gotscores = 0;
+ }
+ }
+ else
+ {
+ if (!e.sort_prev)
+ {
+ // player connected
+ if (!e)
+ playerslots[i] = e = spawn();
+ e.sv_entnum = i;
+ e.ping = 0;
+ e.ping_packetloss = 0;
+ e.ping_movementloss = 0;
+ //e.gotscores = 0; // we might already have the scores...
+ SetTeam(e, GetPlayerColor(i)); // will not hurt; later updates come with HUD_UpdatePlayerTeams
+ RegisterPlayer(e);
+ HUD_UpdatePlayerPos(e);
+ }
+ }
+ }
+ self.nextthink = time + 0.2;
+ }
+
+ void Porto_Init();
+ void TrueAim_Init();
+ void PostInit(void)
+ {
+ entity playerchecker;
+ playerchecker = spawn();
+ playerchecker.think = Playerchecker_Think;
+ playerchecker.nextthink = time + 0.2;
+
+ Porto_Init();
+ TrueAim_Init();
+
+ postinit = true;
+ }
+
+ // CSQC_InputEvent : Used to perform actions based on any key pressed, key released and mouse on the client.
+ // Return value should be 1 if CSQC handled the input, otherwise return 0 to have the input passed to the engine.
+ // All keys are in ascii.
+ // bInputType = 0 is key pressed, 1 is key released, 2 and 3 are mouse input.
+ // In the case of keyboard input, nPrimary is the ascii code, and nSecondary is 0.
+ // In the case of mouse input, nPrimary is xdelta, nSecondary is ydelta.
+ // In the case of mouse input after a setcursormode(1) call, nPrimary is xpos, nSecondary is ypos.
+ float CSQC_InputEvent(float bInputType, float nPrimary, float nSecondary)
+ {
+ float bSkipKey;
+ bSkipKey = false;
+
+ if (HUD_Panel_InputEvent(bInputType, nPrimary, nSecondary))
+ return true;
+
+ if (MapVote_InputEvent(bInputType, nPrimary, nSecondary))
+ return true;
+
+ if(menu_visible && menu_action)
+ if(menu_action(bInputType, nPrimary, nSecondary))
+ return true;
+
+ return bSkipKey;
+ }
+
+ // END REQUIRED CSQC FUNCTIONS
+ // --------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------
+ // BEGIN OPTIONAL CSQC FUNCTIONS
+ void Ent_RemoveEntCS()
+ {
+ entcs_receiver[self.sv_entnum] = world;
+ }
+ void Ent_ReadEntCS()
+ {
+ int sf;
+ InterpolateOrigin_Undo();
+
+ self.classname = "entcs_receiver";
+ sf = ReadByte();
+
+ if(sf & 1)
+ self.sv_entnum = ReadByte();
+ if(sf & 2)
+ {
+ self.origin_x = ReadShort();
+ self.origin_y = ReadShort();
+ self.origin_z = ReadShort();
+ setorigin(self, self.origin);
+ }
+ if(sf & 4)
+ {
+ self.angles_y = ReadByte() * 360.0 / 256;
+ self.angles_x = self.angles_z = 0;
+ }
+ if(sf & 8)
+ self.healthvalue = ReadByte() * 10;
+ if(sf & 16)
+ self.armorvalue = ReadByte() * 10;
+
+ entcs_receiver[self.sv_entnum] = self;
+ self.entremove = Ent_RemoveEntCS;
+ self.iflags |= IFLAG_ORIGIN;
+
+ InterpolateOrigin_Note();
+ }
+
+ void Ent_Remove();
+
+ void Ent_RemovePlayerScore()
+ {
+ if(self.owner) {
+ SetTeam(self.owner, -1);
+ self.owner.gotscores = 0;
+ for(int i = 0; i < MAX_SCORE; ++i) {
+ self.owner.(scores[i]) = 0; // clear all scores
+ }
+ }
+ }
+
+ void Ent_ReadPlayerScore()
+ {
+ int i, n;
+ bool isNew;
+ entity o;
+
+ // damnit -.- don't want to go change every single .sv_entnum in hud.qc AGAIN
+ // (no I've never heard of M-x replace-string, sed, or anything like that)
+ isNew = !self.owner; // workaround for DP bug
+ n = ReadByte()-1;
+
+ #ifdef DP_CSQC_ENTITY_REMOVE_IS_B0RKED
+ if(!isNew && n != self.sv_entnum)
+ {
+ //print("A CSQC entity changed its owner!\n");
+ printf("A CSQC entity changed its owner! (edict: %d, classname: %s)\n", num_for_edict(self), self.classname);
+ isNew = true;
+ Ent_Remove();
+ self.enttype = ENT_CLIENT_SCORES;
+ }
+ #endif
+
+ self.sv_entnum = n;
+
+ if (!(playerslots[self.sv_entnum]))
+ playerslots[self.sv_entnum] = spawn();
+ o = self.owner = playerslots[self.sv_entnum];
+ o.sv_entnum = self.sv_entnum;
+ o.gotscores = 1;
+
+ //if (!o.sort_prev)
+ // RegisterPlayer(o);
+ //playerchecker will do this for us later, if it has not already done so
+
+ int sf, lf;
+ #if MAX_SCORE <= 8
+ sf = ReadByte();
+ lf = ReadByte();
+ #else
+ sf = ReadShort();
+ lf = ReadShort();
+ #endif
+ int p;
+ for(i = 0, p = 1; i < MAX_SCORE; ++i, p *= 2)
+ if(sf & p)
+ {
+ if(lf & p)
+ o.(scores[i]) = ReadInt24_t();
+ else
+ o.(scores[i]) = ReadChar();
+ }
+
+ if(o.sort_prev)
+ HUD_UpdatePlayerPos(o); // if not registered, we cannot do this yet!
+
+ self.entremove = Ent_RemovePlayerScore;
+ }
+
+ void Ent_ReadTeamScore()
+ {
+ int i;
+ entity o;
+
+ self.team = ReadByte();
+ o = self.owner = GetTeam(self.team, true); // these team numbers can always be trusted
+
+ int sf, lf;
+ #if MAX_TEAMSCORE <= 8
+ sf = ReadByte();
+ lf = ReadByte();
+ #else
+ sf = ReadShort();
+ lf = ReadShort();
+ #endif
+ int p;
+ for(i = 0, p = 1; i < MAX_TEAMSCORE; ++i, p *= 2)
+ if(sf & p)
+ {
+ if(lf & p)
+ o.(teamscores[i]) = ReadInt24_t();
+ else
+ o.(teamscores[i]) = ReadChar();
+ }
+
+ HUD_UpdateTeamPos(o);
+ }
+
+ void Ent_ClientData()
+ {
+ float newspectatee_status;
+
+ int f = ReadByte();
+
+ scoreboard_showscores_force = (f & 1);
+
+ if(f & 2)
+ {
+ newspectatee_status = ReadByte();
+ if(newspectatee_status == player_localnum + 1)
+ newspectatee_status = -1; // observing
+ }
+ else
+ newspectatee_status = 0;
+
+ spectatorbutton_zoom = (f & 4);
+
+ if(f & 8)
+ {
+ angles_held_status = 1;
+ angles_held.x = ReadAngle();
+ angles_held.y = ReadAngle();
+ angles_held.z = 0;
+ }
+ else
+ angles_held_status = 0;
+
+ if(newspectatee_status != spectatee_status)
+ {
+ // clear race stuff
+ race_laptime = 0;
+ race_checkpointtime = 0;
+ }
+ if (autocvar_hud_panel_healtharmor_progressbar_gfx)
+ {
+ if ( (spectatee_status == -1 && newspectatee_status > 0) //before observing, now spectating
+ || (spectatee_status > 0 && newspectatee_status > 0 && spectatee_status != newspectatee_status) //changed spectated player
+ )
+ prev_p_health = -1;
+ else if(spectatee_status && !newspectatee_status) //before observing/spectating, now playing
+ prev_health = -1;
+ }
+ spectatee_status = newspectatee_status;
+
+ // we could get rid of spectatee_status, and derive it from player_localentnum and player_localnum
+ }
+
+ void Ent_Nagger()
+ {
+ int i, j, b, f;
+
+ int nags = ReadByte(); // NAGS NAGS NAGS NAGS NAGS NAGS NADZ NAGS NAGS NAGS
+
+ if(!(nags & 4))
+ {
+ if(vote_called_vote)
+ strunzone(vote_called_vote);
+ vote_called_vote = string_null;
+ vote_active = 0;
+ }
+ else
+ {
+ vote_active = 1;
+ }
+
+ if(nags & 64)
+ {
+ vote_yescount = ReadByte();
+ vote_nocount = ReadByte();
+ vote_needed = ReadByte();
+ vote_highlighted = ReadChar();
+ }
+
+ if(nags & 128)
+ {
+ if(vote_called_vote)
+ strunzone(vote_called_vote);
+ vote_called_vote = strzone(ColorTranslateRGB(ReadString()));
+ }
+
+ if(nags & 1)
+ {
+ for(j = 0; j < maxclients; ++j)
+ if(playerslots[j])
+ playerslots[j].ready = 1;
+ for(i = 1; i <= maxclients; i += 8)
+ {
+ f = ReadByte();
+ for(j = i-1, b = 1; b < 256; b *= 2, ++j)
+ if (!(f & b))
+ if(playerslots[j])
+ playerslots[j].ready = 0;
+ }
+ }
+
+ ready_waiting = (nags & 1);
+ ready_waiting_for_me = (nags & 2);
+ vote_waiting = (nags & 4);
+ vote_waiting_for_me = (nags & 8);
+ warmup_stage = (nags & 16);
+ }
+
+ void Ent_EliminatedPlayers()
+ {
+ int i, j, b, f;
+
+ int sf = ReadByte();
+ if(sf & 1)
+ {
+ for(j = 0; j < maxclients; ++j)
+ if(playerslots[j])
+ playerslots[j].eliminated = 1;
+ for(i = 1; i <= maxclients; i += 8)
+ {
+ f = ReadByte();
+ for(j = i-1, b = 1; b < 256; b *= 2, ++j)
+ if (!(f & b))
+ if(playerslots[j])
+ playerslots[j].eliminated = 0;
+ }
+ }
+ }
+
+ void Ent_RandomSeed()
+ {
+ float s;
+ prandom_debug();
+ s = ReadShort();
+ psrandom(s);
+ }
+
+ void Ent_ReadAccuracy(void)
+ {
+ int f, w;
+ int sf = ReadInt24_t();
+ if(sf == 0)
+ {
+ for(w = 0; w <= WEP_LAST - WEP_FIRST; ++w)
+ weapon_accuracy[w] = -1;
+ return;
+ }
+
+ for(w = 0, f = 1; w <= WEP_LAST - WEP_FIRST; ++w)
+ {
+ if(sf & f)
+ {
+ int b = ReadByte();
+ if(b == 0)
+ weapon_accuracy[w] = -1;
+ else if(b == 255)
+ weapon_accuracy[w] = 1.0; // no better error handling yet, sorry
+ else
+ weapon_accuracy[w] = (b - 1.0) / 100.0;
+ }
+ if(f == 0x800000)
+ f = 1;
+ else
+ f *= 2;
+ }
+ }
+
+ void Spawn_Draw(void)
+ {
+ pointparticles(self.cnt, self.origin + '0 0 28', '0 0 2', bound(0, frametime, 0.1));
+ }
+
+ void Ent_ReadSpawnPoint(float is_new) // entity for spawnpoint
+ {
+ float teamnum = (ReadByte() - 1);
+ vector spn_origin;
+ spn_origin.x = ReadShort();
+ spn_origin.y = ReadShort();
+ spn_origin.z = ReadShort();
+
+ if(is_new)
+ {
+ self.origin = spn_origin;
+ setsize(self, PL_MIN, PL_MAX);
+ droptofloor();
+
+ /*if(autocvar_cl_spawn_point_model) // needs a model first
+ {
+ self.mdl = "models/spawnpoint.md3";
+ self.colormod = Team_ColorRGB(teamnum);
+ precache_model(self.mdl);
+ setmodel(self, self.mdl);
+ self.drawmask = MASK_NORMAL;
+ //self.movetype = MOVETYPE_NOCLIP;
+ //self.draw = Spawn_Draw;
+ }*/
+ if(autocvar_cl_spawn_point_particles)
+ {
+ if((serverflags & SERVERFLAG_TEAMPLAY))
+ {
+ switch(teamnum)
+ {
+ case NUM_TEAM_1: self.cnt = particleeffectnum("spawn_point_red"); break;
+ case NUM_TEAM_2: self.cnt = particleeffectnum("spawn_point_blue"); break;
+ case NUM_TEAM_3: self.cnt = particleeffectnum("spawn_point_yellow"); break;
+ case NUM_TEAM_4: self.cnt = particleeffectnum("spawn_point_pink"); break;
+ default: self.cnt = particleeffectnum("spawn_point_neutral"); break;
+ }
+ }
+ else { self.cnt = particleeffectnum("spawn_point_neutral"); }
+
+ self.draw = Spawn_Draw;
+ }
+ }
+
+ //printf("Ent_ReadSpawnPoint(is_new = %d); origin = %s, team = %d, effect = %d\n", is_new, vtos(self.origin), teamnum, self.cnt);
+ }
+
+ void Ent_ReadSpawnEvent(float is_new)
+ {
+ // If entnum is 0, ONLY do the local spawn actions
+ // this way the server can disable the sending of
+ // spawn origin or such to clients if wanted.
+ float entnum = ReadByte();
+
+ if(entnum)
+ {
+ self.origin_x = ReadShort();
+ self.origin_y = ReadShort();
+ self.origin_z = ReadShort();
+
+ if(is_new)
+ {
+ float teamnum = GetPlayerColor(entnum - 1);
+
+ if(autocvar_cl_spawn_event_particles)
+ {
+ switch(teamnum)
+ {
+ case NUM_TEAM_1: pointparticles(particleeffectnum("spawn_event_red"), self.origin, '0 0 0', 1); break;
+ case NUM_TEAM_2: pointparticles(particleeffectnum("spawn_event_blue"), self.origin, '0 0 0', 1); break;
+ case NUM_TEAM_3: pointparticles(particleeffectnum("spawn_event_yellow"), self.origin, '0 0 0', 1); break;
+ case NUM_TEAM_4: pointparticles(particleeffectnum("spawn_event_pink"), self.origin, '0 0 0', 1); break;
+ default: pointparticles(particleeffectnum("spawn_event_neutral"), self.origin, '0 0 0', 1); break;
+ }
+ }
+ if(autocvar_cl_spawn_event_sound)
+ {
+ sound(self, CH_TRIGGER, "misc/spawn.wav", VOL_BASE, ATTEN_NORM);
+ }
+ }
+ }
+
+ // local spawn actions
+ if(is_new && (!entnum || (entnum == player_localentnum)))
+ {
+ zoomin_effect = 1;
+ current_viewzoom = (1 / bound(1, autocvar_cl_spawnzoom_factor, 16));
+
+ if(autocvar_cl_unpress_zoom_on_spawn)
+ {
+ localcmd("-zoom\n");
+ button_zoom = false;
+ }
+ }
+
+ //printf("Ent_ReadSpawnEvent(is_new = %d); origin = %s, entnum = %d, localentnum = %d\n", is_new, vtos(self.origin), entnum, player_localentnum);
+ }
+
+ // CSQC_Ent_Update : Called every frame that the server has indicated an update to the SSQC / CSQC entity has occured.
+ // The only parameter reflects if the entity is "new" to the client, meaning it just came into the client's PVS.
+ void Ent_RadarLink();
+ void Ent_Init();
+ void Ent_ScoresInfo();
+ void CSQC_Ent_Update(float bIsNewEntity)
+ {
+ float t;
+ float savetime;
+ t = ReadByte();
+
+ if(autocvar_developer_csqcentities)
+ printf("CSQC_Ent_Update(%d) with self=%i self.entnum=%d self.enttype=%d t=%d\n", bIsNewEntity, self, self.entnum, self.enttype, t);
+
+ // set up the "time" global for received entities to be correct for interpolation purposes
+ savetime = time;
+ if(servertime)
+ {
+ time = servertime;
+ }
+ else
+ {
+ serverprevtime = time;
+ serverdeltatime = getstatf(STAT_MOVEVARS_TICRATE) * getstatf(STAT_MOVEVARS_TIMESCALE);
+ time = serverprevtime + serverdeltatime;
+ }
+
+ #ifdef DP_CSQC_ENTITY_REMOVE_IS_B0RKED
+ if(self.enttype)
+ {
+ if(t != self.enttype || bIsNewEntity)
+ {
+ //print("A CSQC entity changed its type!\n");
+ printf("A CSQC entity changed its type! (edict: %d, server: %d, type: %d -> %d)\n", num_for_edict(self), self.entnum, self.enttype, t);
+ Ent_Remove();
+ clearentity(self);
+ bIsNewEntity = 1;
+ }
+ }
+ else
+ {
+ if(!bIsNewEntity)
+ {
+ printf("A CSQC entity appeared out of nowhere! (edict: %d, server: %d, type: %d)\n", num_for_edict(self), self.entnum, t);
+ bIsNewEntity = 1;
+ }
+ }
+ #endif
+ self.enttype = t;
+ switch(t)
+ {
+ case ENT_CLIENT_ENTCS: Ent_ReadEntCS(); break;
+ case ENT_CLIENT_SCORES: Ent_ReadPlayerScore(); break;
+ case ENT_CLIENT_TEAMSCORES: Ent_ReadTeamScore(); break;
+ case ENT_CLIENT_POINTPARTICLES: Ent_PointParticles(); break;
+ case ENT_CLIENT_RAINSNOW: Ent_RainOrSnow(); break;
+ case ENT_CLIENT_LASER: Ent_Laser(); break;
+ case ENT_CLIENT_NAGGER: Ent_Nagger(); break;
+ case ENT_CLIENT_ELIMINATEDPLAYERS: Ent_EliminatedPlayers(); break;
+ case ENT_CLIENT_WAYPOINT: Ent_WaypointSprite(); break;
+ case ENT_CLIENT_RADARLINK: Ent_RadarLink(); break;
+ case ENT_CLIENT_PROJECTILE: Ent_Projectile(); break;
+ case ENT_CLIENT_GIBSPLASH: Ent_GibSplash(bIsNewEntity); break;
+ case ENT_CLIENT_DAMAGEINFO: Ent_DamageInfo(bIsNewEntity); break;
+ case ENT_CLIENT_CASING: Ent_Casing(bIsNewEntity); break;
+ case ENT_CLIENT_INIT: Ent_Init(); break;
+ case ENT_CLIENT_SCORES_INFO: Ent_ScoresInfo(); break;
+ case ENT_CLIENT_MAPVOTE: Ent_MapVote(); break;
+ case ENT_CLIENT_CLIENTDATA: Ent_ClientData(); break;
+ case ENT_CLIENT_RANDOMSEED: Ent_RandomSeed(); break;
+ case ENT_CLIENT_WALL: Ent_Wall(); break;
+ case ENT_CLIENT_MODELEFFECT: Ent_ModelEffect(bIsNewEntity); break;
+ case ENT_CLIENT_TUBANOTE: Ent_TubaNote(bIsNewEntity); break;
+ case ENT_CLIENT_WARPZONE: WarpZone_Read(bIsNewEntity); break;
+ case ENT_CLIENT_WARPZONE_CAMERA: WarpZone_Camera_Read(bIsNewEntity); break;
+ 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_ARC_BEAM: Ent_ReadArcBeam(bIsNewEntity); break;
+ case ENT_CLIENT_ACCURACY: Ent_ReadAccuracy(); break;
+ case ENT_CLIENT_AUXILIARYXHAIR: Net_AuXair2(bIsNewEntity); break;
+ case ENT_CLIENT_TURRET: ent_turret(); break;
+ case ENT_CLIENT_MODEL: CSQCModel_Read(bIsNewEntity); break;
+ case ENT_CLIENT_ITEM: ItemRead(bIsNewEntity); break;
+ case ENT_CLIENT_BUMBLE_RAYGUN: bumble_raygun_read(bIsNewEntity); break;
+ case ENT_CLIENT_SPAWNPOINT: Ent_ReadSpawnPoint(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;
+
+ default:
+ //error(strcat(_("unknown entity type in CSQC_Ent_Update: %d\n"), self.enttype));
+ error(sprintf("Unknown entity type in CSQC_Ent_Update (enttype: %d, edict: %d, classname: %s)\n", self.enttype, num_for_edict(self), self.classname));
+ break;
+ }
+
+ time = savetime;
+ }
+ // Destructor, but does NOT deallocate the entity by calling remove(). Also
+ // used when an entity changes its type. For an entity that someone interacts
+ // with others, make sure it can no longer do so.
+ void Ent_Remove()
+ {
+ if(self.entremove)
+ self.entremove();
+
+ if(self.skeletonindex)
+ {
+ skel_delete(self.skeletonindex);
+ self.skeletonindex = 0;
+ }
+
+ if(self.snd_looping > 0)
+ {
+ sound(self, self.snd_looping, "misc/null.wav", VOL_BASE, autocvar_g_jetpack_attenuation);
+ self.snd_looping = 0;
+ }
+
+ self.enttype = 0;
+ self.classname = "";
+ self.draw = menu_sub_null;
+ self.entremove = menu_sub_null;
+ // TODO possibly set more stuff to defaults
+ }
+ // CSQC_Ent_Remove : Called when the server requests a SSQC / CSQC entity to be removed. Essentially call remove(self) as well.
+ void CSQC_Ent_Remove()
+ {
+ if(autocvar_developer_csqcentities)
+ printf("CSQC_Ent_Remove() with self=%i self.entnum=%d self.enttype=%d\n", self, self.entnum, self.enttype);
+
+ if(wasfreed(self))
+ {
+ print("WARNING: CSQC_Ent_Remove called for already removed entity. Packet loss?\n");
+ return;
+ }
+ if(self.enttype)
+ Ent_Remove();
+ remove(self);
+ }
+
+ void Gamemode_Init()
+ {
+ if (!isdemo())
+ {
+ if(!(calledhooks & HOOK_START))
+ localcmd("\n_cl_hook_gamestart ", MapInfo_Type_ToString(gametype), "\n");
+ calledhooks |= HOOK_START;
+ }
+ }
+ // CSQC_Parse_StuffCmd : Provides the stuffcmd string in the first parameter that the server provided. To execute standard behavior, simply execute localcmd with the string.
+ void CSQC_Parse_StuffCmd(string strMessage)
+ {
+ if(autocvar_developer_csqcentities)
+ printf("CSQC_Parse_StuffCmd(\"%s\")\n", strMessage);
+
+ localcmd(strMessage);
+ }
+ // CSQC_Parse_Print : Provides the print string in the first parameter that the server provided. To execute standard behavior, simply execute print with the string.
+ void CSQC_Parse_Print(string strMessage)
+ {
+ if(autocvar_developer_csqcentities)
+ printf("CSQC_Parse_Print(\"%s\")\n", strMessage);
+
+ print(ColorTranslateRGB(strMessage));
+ }
+
+ // CSQC_Parse_CenterPrint : Provides the centerprint_hud string in the first parameter that the server provided.
+ void CSQC_Parse_CenterPrint(string strMessage)
+ {
+ if(autocvar_developer_csqcentities)
+ printf("CSQC_Parse_CenterPrint(\"%s\")\n", strMessage);
+
+ centerprint_hud(strMessage);
+ }
+
+ string notranslate_fogcmd1 = "\nfog ";
+ string notranslate_fogcmd2 = "\nr_fog_exp2 0\nr_drawfog 1\n";
+ void Fog_Force()
+ {
+ // TODO somehow thwart prvm_globalset client ...
+
+ if(autocvar_cl_orthoview && autocvar_cl_orthoview_nofog)
+ { localcmd("\nr_drawfog 0\n"); }
+ else if(forcefog != "")
+ { localcmd(strcat(notranslate_fogcmd1, forcefog, notranslate_fogcmd2)); }
+ }
+
+ void Gamemode_Init();
+ void Ent_ScoresInfo()
+ {
+ int i;
+ self.classname = "ent_client_scores_info";
+ gametype = ReadInt24_t();
+ HUD_ModIcons_SetFunc();
+ for(i = 0; i < MAX_SCORE; ++i)
+ {
+ if(scores_label[i])
+ strunzone(scores_label[i]);
+ scores_label[i] = strzone(ReadString());
+ scores_flags[i] = ReadByte();
+ }
+ for(i = 0; i < MAX_TEAMSCORE; ++i)
+ {
+ if(teamscores_label[i])
+ strunzone(teamscores_label[i]);
+ teamscores_label[i] = strzone(ReadString());
+ teamscores_flags[i] = ReadByte();
+ }
+ HUD_InitScores();
+ Gamemode_Init();
+ }
+
+ void Ent_Init()
+ {
+ self.classname = "ent_client_init";
+
+ nb_pb_period = ReadByte() / 32; //Accuracy of 1/32th
+
+ hook_shotorigin[0] = decompressShotOrigin(ReadInt24_t());
+ hook_shotorigin[1] = decompressShotOrigin(ReadInt24_t());
+ hook_shotorigin[2] = decompressShotOrigin(ReadInt24_t());
+ hook_shotorigin[3] = decompressShotOrigin(ReadInt24_t());
+ arc_shotorigin[0] = decompressShotOrigin(ReadInt24_t());
+ arc_shotorigin[1] = decompressShotOrigin(ReadInt24_t());
+ arc_shotorigin[2] = decompressShotOrigin(ReadInt24_t());
+ arc_shotorigin[3] = decompressShotOrigin(ReadInt24_t());
+
+ if(forcefog)
+ strunzone(forcefog);
+ forcefog = strzone(ReadString());
+
+ armorblockpercent = ReadByte() / 255.0;
+
+ g_balance_mortar_bouncefactor = ReadCoord();
+ g_balance_mortar_bouncestop = ReadCoord();
+ g_balance_electro_secondary_bouncefactor = ReadCoord();
+ g_balance_electro_secondary_bouncestop = ReadCoord();
+
+ vortex_scope = !ReadByte();
+ rifle_scope = !ReadByte();
+
+ serverflags = ReadByte();
+
+ minelayer_maxmines = ReadByte();
+
+ hagar_maxrockets = ReadByte();
+
+ g_trueaim_minrange = ReadCoord();
+ g_balance_porto_secondary = ReadByte();
+
+ if(!postinit)
+ PostInit();
+ }
+
+ void Net_ReadRace()
+ {
+ float b;
+
+ b = ReadByte();
+
+ switch(b)
+ {
+ case RACE_NET_CHECKPOINT_HIT_QUALIFYING:
+ race_checkpoint = ReadByte();
+ race_time = ReadInt24_t();
+ race_previousbesttime = ReadInt24_t();
+ if(race_previousbestname)
+ strunzone(race_previousbestname);
+ race_previousbestname = strzone(ColorTranslateRGB(ReadString()));
+
+ race_checkpointtime = time;
+
+ if(race_checkpoint == 0 || race_checkpoint == 254)
+ {
+ race_penaltyaccumulator = 0;
+ race_laptime = time; // valid
+ }
+
+ break;
+
+ case RACE_NET_CHECKPOINT_CLEAR:
+ race_laptime = 0;
+ race_checkpointtime = 0;
+ break;
+
+ case RACE_NET_CHECKPOINT_NEXT_SPEC_QUALIFYING:
+ race_laptime = ReadCoord();
+ race_checkpointtime = -99999;
+ // fall through
+ case RACE_NET_CHECKPOINT_NEXT_QUALIFYING:
+ race_nextcheckpoint = ReadByte();
+
+ race_nextbesttime = ReadInt24_t();
+ if(race_nextbestname)
+ strunzone(race_nextbestname);
+ race_nextbestname = strzone(ColorTranslateRGB(ReadString()));
+ break;
+
+ case RACE_NET_CHECKPOINT_HIT_RACE:
+ race_mycheckpoint = ReadByte();
+ race_mycheckpointtime = time;
+ race_mycheckpointdelta = ReadInt24_t();
+ race_mycheckpointlapsdelta = ReadByte();
+ if(race_mycheckpointlapsdelta >= 128)
+ race_mycheckpointlapsdelta -= 256;
+ if(race_mycheckpointenemy)
+ strunzone(race_mycheckpointenemy);
+ race_mycheckpointenemy = strzone(ColorTranslateRGB(ReadString()));
+ break;
+
+ case RACE_NET_CHECKPOINT_HIT_RACE_BY_OPPONENT:
+ race_othercheckpoint = ReadByte();
+ race_othercheckpointtime = time;
+ race_othercheckpointdelta = ReadInt24_t();
+ race_othercheckpointlapsdelta = ReadByte();
+ if(race_othercheckpointlapsdelta >= 128)
+ race_othercheckpointlapsdelta -= 256;
+ if(race_othercheckpointenemy)
+ strunzone(race_othercheckpointenemy);
+ race_othercheckpointenemy = strzone(ColorTranslateRGB(ReadString()));
+ break;
+
+ case RACE_NET_PENALTY_RACE:
+ race_penaltyeventtime = time;
+ race_penaltytime = ReadShort();
+ //race_penaltyaccumulator += race_penaltytime;
+ if(race_penaltyreason)
+ strunzone(race_penaltyreason);
+ race_penaltyreason = strzone(ReadString());
+ break;
+
+ case RACE_NET_PENALTY_QUALIFYING:
+ race_penaltyeventtime = time;
+ race_penaltytime = ReadShort();
+ race_penaltyaccumulator += race_penaltytime;
+ if(race_penaltyreason)
+ strunzone(race_penaltyreason);
+ race_penaltyreason = strzone(ReadString());
+ break;
+
+ case RACE_NET_SERVER_RECORD:
+ race_server_record = ReadInt24_t();
+ break;
+ case RACE_NET_SPEED_AWARD:
+ race_speedaward = ReadInt24_t();
+ if(race_speedaward_holder)
+ strunzone(race_speedaward_holder);
+ race_speedaward_holder = strzone(ReadString());
+ break;
+ case RACE_NET_SPEED_AWARD_BEST:
+ race_speedaward_alltimebest = ReadInt24_t();
+ if(race_speedaward_alltimebest_holder)
+ strunzone(race_speedaward_alltimebest_holder);
+ race_speedaward_alltimebest_holder = strzone(ReadString());
+ break;
+ case RACE_NET_SERVER_RANKINGS:
+ float prevpos, del;
+ int pos = ReadShort();
+ prevpos = ReadShort();
+ del = ReadShort();
+
+ // move other rankings out of the way
+ int i;
+ if (prevpos) {
+ for (i=prevpos-1;i>pos-1;--i) {
+ grecordtime[i] = grecordtime[i-1];
+ if(grecordholder[i])
+ strunzone(grecordholder[i]);
+ grecordholder[i] = strzone(grecordholder[i-1]);
+ }
+ } else if (del) { // a record has been deleted by the admin
+ for (i=pos-1; i<= RANKINGS_CNT-1; ++i) {
+ if (i == RANKINGS_CNT-1) { // clear out last record
+ grecordtime[i] = 0;
+ if (grecordholder[i])
+ strunzone(grecordholder[i]);
+ grecordholder[i] = string_null;
+ }
+ else {
+ grecordtime[i] = grecordtime[i+1];
+ if (grecordholder[i])
+ strunzone(grecordholder[i]);
+ grecordholder[i] = strzone(grecordholder[i+1]);
+ }
+ }
+ } else { // player has no ranked record yet
+ for (i=RANKINGS_CNT-1;i>pos-1;--i) {
+ grecordtime[i] = grecordtime[i-1];
+ if(grecordholder[i])
+ strunzone(grecordholder[i]);
+ grecordholder[i] = strzone(grecordholder[i-1]);
+ }
+ }
+
+ // store new ranking
+ if(grecordholder[pos-1] != "")
+ strunzone(grecordholder[pos-1]);
+ grecordholder[pos-1] = strzone(ReadString());
+ grecordtime[pos-1] = ReadInt24_t();
+ if(grecordholder[pos-1] == GetPlayerName(player_localnum))
+ race_myrank = pos;
+ break;
+ case RACE_NET_SERVER_STATUS:
+ race_status = ReadShort();
+ if(race_status_name)
+ strunzone(race_status_name);
+ race_status_name = strzone(ReadString());
+ }
+ }
+
+ void Net_TeamNagger()
+ {
+ teamnagger = 1;
+ }
+
+ void Net_ReadPingPLReport()
+ {
+ int e, pi, pl, ml;
+ e = ReadByte();
+ pi = ReadShort();
+ pl = ReadByte();
+ ml = ReadByte();
+ if (!(playerslots[e]))
+ return;
+ playerslots[e].ping = pi;
+ playerslots[e].ping_packetloss = pl / 255.0;
+ playerslots[e].ping_movementloss = ml / 255.0;
+ }
+
+ void Net_WeaponComplain()
+ {
+ complain_weapon = ReadByte();
+
+ if(complain_weapon_name)
+ strunzone(complain_weapon_name);
+ complain_weapon_name = strzone(WEP_NAME(complain_weapon));
+
+ complain_weapon_type = ReadByte();
+
+ complain_weapon_time = time;
+ weapontime = time; // ping the weapon panel
+
+ switch(complain_weapon_type)
+ {
+ case 0: Local_Notification(MSG_MULTI, ITEM_WEAPON_NOAMMO, complain_weapon); break;
+ case 1: Local_Notification(MSG_MULTI, ITEM_WEAPON_DONTHAVE, complain_weapon); break;
+ default: Local_Notification(MSG_MULTI, ITEM_WEAPON_UNAVAILABLE, complain_weapon); break;
+ }
+ }
+
+ // CSQC_Parse_TempEntity : Handles all temporary entity network data in the CSQC layer.
+ // You must ALWAYS first acquire the temporary ID, which is sent as a byte.
+ // Return value should be 1 if CSQC handled the temporary entity, otherwise return 0 to have the engine process the event.
+ float CSQC_Parse_TempEntity()
+ {
+ float bHandled;
+ bHandled = true;
+ // Acquire TE ID
+ float nTEID;
+ nTEID = ReadByte();
+
+ if(autocvar_developer_csqcentities)
+ printf("CSQC_Parse_TempEntity() with nTEID=%d\n", nTEID);
+
+ // NOTE: Could just do return instead of break...
+ switch(nTEID)
+ {
+ case TE_CSQC_TARGET_MUSIC:
+ Net_TargetMusic();
+ bHandled = true;
+ break;
+ case TE_CSQC_PICTURE:
+ Net_MapVote_Picture();
+ bHandled = true;
+ break;
+ case TE_CSQC_RACE:
+ Net_ReadRace();
+ bHandled = true;
+ break;
+ case TE_CSQC_VORTEXBEAMPARTICLE:
+ Net_ReadVortexBeamParticle();
+ bHandled = true;
+ break;
+ case TE_CSQC_TEAMNAGGER:
+ Net_TeamNagger();
+ bHandled = true;
+ break;
+ case TE_CSQC_ARC:
+ Net_ReadArc();
+ bHandled = true;
+ break;
+ case TE_CSQC_PINGPLREPORT:
+ Net_ReadPingPLReport();
+ bHandled = true;
+ break;
+ case TE_CSQC_WEAPONCOMPLAIN:
+ Net_WeaponComplain();
+ bHandled = true;
+ break;
+ case TE_CSQC_VEHICLESETUP:
+ Net_VehicleSetup();
+ bHandled = true;
+ break;
+ case TE_CSQC_SVNOTICE:
+ cl_notice_read();
+ bHandled = true;
+ break;
+ case TE_CSQC_SHOCKWAVEPARTICLE:
+ Net_ReadShockwaveParticle();
+ bHandled = true;
+ break;
+ default:
+ // No special logic for this temporary entity; return 0 so the engine can handle it
+ bHandled = false;
+ break;
+ }
+
+ return bHandled;
+ }
+
+ string getcommandkey(string text, string command)
+ {
+ string keys;
+ float n, j, k, l = 0;
+
+ if (!autocvar_hud_showbinds)
+ return text;
+
+ keys = db_get(binddb, command);
+ if (keys == "")
+ {
+ n = tokenize(findkeysforcommand(command, 0)); // uses '...' strings
+ for(j = 0; j < n; ++j)
+ {
+ k = stof(argv(j));
+ if(k != -1)
+ {
+ if ("" == keys)
+ keys = keynumtostring(k);
+ else
+ keys = strcat(keys, ", ", keynumtostring(k));
+
+ ++l;
+ if (autocvar_hud_showbinds_limit > 0 && autocvar_hud_showbinds_limit <= l)
+ break;
+ }
+
+ }
+ if (keys == "")
+ keys = "NO_KEY";
+ db_put(binddb, command, keys);
+ }
+
+ if (keys == "NO_KEY") {
+ if (autocvar_hud_showbinds > 1)
+ return sprintf(_("%s (not bound)"), text);
+ else
+ return text;
+ }
+ else if (autocvar_hud_showbinds > 1)
+ return sprintf("%s (%s)", text, keys);
+ else
+ return keys;
+ }
../../csprogs.dat
../common/util-pre.qh
- sys-pre.qh
- ../dpdefs/csprogsdefs.qc
- sys-post.qh
+ ../dpdefs/csprogsdefs.qh
- Defs.qc
- ../dpdefs/keycodes.qc
- ../common/constants.qh
- ../common/stats.qh
-
- ../warpzonelib/anglestransform.qh
- ../warpzonelib/mathlib.qh
- ../warpzonelib/common.qh
- ../warpzonelib/client.qh
-
- ../common/playerstats.qh
- ../common/teams.qh
- ../common/util.qh
- ../common/nades.qh
- ../common/buffs.qh
- ../common/test.qh
- ../common/counting.qh
- ../common/weapons/weapons.qh // TODO
- ../common/mapinfo.qh
- ../common/command/markup.qh
- ../common/command/rpn.qh
- ../common/command/generic.qh
- ../common/command/shared_defs.qh
- ../common/urllib.qh
- ../common/animdecide.qh
- command/cl_cmd.qh
-
- ../common/monsters/monsters.qh
-
- autocvars.qh
-
- ../common/notifications.qh // must be after autocvars
- ../common/deathtypes.qh // must be after notifications
-
- ../common/turrets/turrets.qh
- ../common/turrets/cl_turrets.qh
-
- damage.qh
-
- ../csqcmodellib/interpolate.qh
- teamradar.qh
- hud.qh
- scoreboard.qh
- waypointsprites.qh
- movetypes.qh
- prandom.qh
- bgmscript.qh
- noise.qh
- ../server/movelib.qc
- main.qh
- vehicles/vehicles.qh
- ../common/csqcmodel_settings.qh
- ../csqcmodellib/common.qh
- ../csqcmodellib/cl_model.qh
- ../csqcmodellib/cl_player.qh
- weapons/projectile.qh // TODO
- player_skeleton.qh
-
- sortlist.qc
- miscfunctions.qc
- ../server/t_items.qh
- ../server/t_items.qc
-
- teamradar.qc
- hud_config.qc
- hud.qc
- scoreboard.qc
- mapvoting.qc
+ announcer.qc
+ bgmscript.qc
+ casings.qc
csqcmodel_hooks.qc
- ../common/net_notice.qc
-
- rubble.qc
- hook.qc
- particles.qc
- laser.qc
- weapons/projectile.qc // TODO
- gibs.qc
damage.qc
- casings.qc
- ../csqcmodellib/cl_model.qc
- ../csqcmodellib/cl_player.qc
effects.qc
- wall.qc
+ gibs.qc
+ hook.qc
+ hud_config.qc
+ hud.qc
+ laser.qc
+ main.qc
+ mapvoting.qc
+ miscfunctions.qc
modeleffects.qc
- tuba.qc
+ movetypes.qc
+ noise.qc
+ particles.qc
+ player_skeleton.qc
+ prandom.qc
+ rubble.qc
+ scoreboard.qc
+ shownames.qc
+ sortlist.qc
target_music.qc
-
+ teamradar.qc
-tturrets.qc
+ tuba.qc
vehicles/vehicles.qc
- ../server/vehicles/bumblebee.qc
- shownames.qh
- shownames.qc
-
- announcer.qc
- Main.qc
- View.qc
- ../csqcmodellib/interpolate.qc
+ view.qc
+ wall.qc
waypointsprites.qc
- movetypes.qc
- prandom.qc
- bgmscript.qc
- noise.qc
+ command/cl_cmd.qc
+
+ weapons/projectile.qc // TODO
+
+ ../common/animdecide.qc
+ ../common/buffs.qc
+ ../common/mapinfo.qc
+ ../common/nades.qc
+ ../common/net_notice.qc
+ ../common/notifications.qc
+ ../common/playerstats.qc
../common/test.qc
+ ../common/urllib.qc
../common/util.qc
- ../common/playerstats.qc
- ../common/notifications.qc
+
+ ../common/command/generic.qc
../common/command/markup.qc
../common/command/rpn.qc
- ../common/command/generic.qc
- ../common/mapinfo.qc
- ../common/weapons/weapons.qc // TODO
- ../common/urllib.qc
- command/cl_cmd.qc
../common/monsters/monsters.qc
- ../common/nades.qc
- ../common/buffs.qc
++../common/turrets/cl_turrets.qc
++../common/turrets/turrets.qc
++
+ ../common/weapons/weapons.qc // TODO
+
+ ../csqcmodellib/cl_model.qc
+ ../csqcmodellib/cl_player.qc
+ ../csqcmodellib/interpolate.qc
+
+ ../server/movelib.qc
+ ../server/t_items.qc
+ ../server/vehicles/bumblebee.qc
../warpzonelib/anglestransform.qc
- ../warpzonelib/mathlib.qc
- ../warpzonelib/common.qc
../warpzonelib/client.qc
- ../common/turrets/cl_turrets.qc
- ../common/turrets/turrets.qc
-
- player_skeleton.qc
- ../common/animdecide.qc
+
+ ../warpzonelib/common.qc
+ ../warpzonelib/mathlib.qc
+++ /dev/null
-#include "tturrets.qh"
-#include "waypointsprites.qh"
-
-#include "../server/movelib.qh"
-
--string tid2info_base;
--string tid2info_head;
--string tid2info_name;
--vector tid2info_min;
--vector tid2info_max;
--
--void turret_tid2info(float _tid);
--void turret_precache(float _tid);
--float turret_is_precache[TID_LAST];
--
--void turrets_precache()
--{
-- turret_precache(TID_COMMON);
--}
--
- void turret_precache(float _tid)
-void turret_precache(int _tid)
--{
-- if (!turret_is_precache[TID_COMMON])
-- {
-- 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/terrainbase.md3");
-- precache_model ("models/turrets/base.md3");
-- precache_model ("models/turrets/rocket.md3");
-- }
-- turret_tid2info(_tid);
-- if(turret_is_precache[_tid])
-- return;
--
-- switch(_tid)
-- {
-- case TID_EWHEEL:
-- precache_model ("models/turrets/ewheel-base2.md3");
-- precache_model ("models/turrets/ewheel-gun1.md3");
-- break;
-- case TID_FLAC:
-- precache_model ("models/turrets/flac.md3");
-- break;
-- case TID_FUSION:
-- precache_model ("models/turrets/reactor.md3");
-- break;
-- case TID_HELLION:
-- precache_model ("models/turrets/hellion.md3");
-- break;
-- case TID_HK:
-- precache_model ("models/turrets/hk.md3");
-- break;
-- case TID_MACHINEGUN:
-- precache_model ("models/turrets/machinegun.md3");
-- precache_sound ("weapons/uzi_fire.wav");
-- break;
-- case TID_MLRS:
-- precache_model ("models/turrets/mlrs.md3");
-- break;
-- case TID_PHASER:
-- precache_model ("models/turrets/phaser.md3");
-- precache_model ("models/turrets/phaser_beam.md3");
-- precache_sound ("turrets/phaser.wav");
-- break;
-- case TID_PLASMA:
-- precache_model ("models/turrets/plasma.md3");
-- break;
-- case TID_PLASMA_DUAL:
-- precache_model ("models/turrets/plasmad.md3");
-- break;
-- case TID_TESLA:
-- precache_model ("models/turrets/tesla_head.md3");
-- precache_model ("models/turrets/tesla_base.md3");
-- break;
-- case TID_WALKER:
-- precache_model ("models/turrets/walker_head_minigun.md3");
-- precache_model ("models/turrets/walker_body.md3");
-- precache_sound ("weapons/uzi_fire.wav");
-- break;
-- }
- turret_is_precache[_tid] = TRUE;
- turret_is_precache[_tid] = true;
--}
--
--void turret_tid2info(float _tid)
--{
-- tid2info_base = "models/turrets/base.md3";
-- tid2info_min = '-32 -32 0';
-- tid2info_max = '32 32 64';
--
-- switch(_tid)
-- {
-- case TID_EWHEEL:
-- tid2info_base = "models/turrets/ewheel-base2.md3";
-- tid2info_head = "models/turrets/ewheel-gun1.md3";
-- tid2info_name = "eWheel";
-- break;
-- case TID_FLAC:
-- tid2info_head = "models/turrets/flac.md3";
-- tid2info_name = "Flac Cannon";
-- break;
-- case TID_FUSION:
-- tid2info_head = "models/turrets/reactor.md3";
-- tid2info_name = "Fusion Reactor";
-- tid2info_min = '-34 -34 0';
-- tid2info_max = '34 34 90';
-- break;
-- case TID_HELLION:
-- tid2info_head = "models/turrets/hellion.md3";
-- tid2info_name = "Hellion";
-- break;
-- case TID_HK:
-- tid2info_head = "models/turrets/hk.md3";
-- tid2info_name = "Hunter-Killer";
-- break;
-- case TID_MACHINEGUN:
-- tid2info_head = "models/turrets/machinegun.md3";
-- tid2info_name = "Machinegun";
-- break;
-- case TID_MLRS:
-- tid2info_head = "models/turrets/mlrs.md3";
-- tid2info_name = "MLRS";
-- break;
-- case TID_PHASER:
-- tid2info_head = "models/turrets/phaser.md3";
-- tid2info_name = "Phaser";
-- break;
-- case TID_PLASMA:
-- tid2info_head = "models/turrets/plasma.md3";
-- tid2info_name = "Plasma";
-- break;
-- case TID_PLASMA_DUAL:
-- tid2info_head = "models/turrets/plasmad.md3";
-- tid2info_name = "Dual Plasma";
-- break;
-- case TID_TESLA:
-- tid2info_base = "models/turrets/tesla_base.md3";
-- tid2info_head = "models/turrets/tesla_head.md3";
-- tid2info_name = "Tesla coil";
-- tid2info_min = '-60 -60 0';
-- tid2info_max ='60 60 128';
-- break;
-- case TID_WALKER:
-- tid2info_base = "models/turrets/walker_body.md3";
-- tid2info_head = "models/turrets/walker_head_minigun.md3";
-- tid2info_name = "Walker";
-- tid2info_min = '-70 -70 0';
-- tid2info_max = '70 70 95';
-- break;
-- }
--}
--
--void turret_remove()
--{
-- remove(self.tur_head);
-- //remove(self.enemy);
-- self.tur_head = world;
--}
--
--.vector glowmod;
--void turret_changeteam()
--{
-- switch(self.team - 1)
-- {
-- case NUM_TEAM_1: // Red
-- self.glowmod = '2 0 0';
-- self.teamradar_color = '1 0 0';
-- break;
--
-- case NUM_TEAM_2: // Blue
-- self.glowmod = '0 0 2';
-- self.teamradar_color = '0 0 1';
-- break;
--
-- case NUM_TEAM_3: // Yellow
-- self.glowmod = '1 1 0';
-- self.teamradar_color = '1 1 0';
-- break;
--
-- case NUM_TEAM_4: // Pink
-- self.glowmod = '1 0 1';
-- self.teamradar_color = '1 0 1';
-- break;
-- }
--
-- 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)))
- 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;
- o.z = 0;
-- if(hud != HUD_NORMAL)
-- {
-- switch(hud)
-- {
-- case HUD_SPIDERBOT:
-- case HUD_WAKIZASHI:
-- case HUD_RAPTOR:
-- case HUD_BUMBLEBEE:
-- if(self.turret_type == TID_EWHEEL || self.turret_type == TID_WALKER)
-- txt = "gfx/vehicles/vth-mover.tga";
-- else
-- txt = "gfx/vehicles/vth-stationary.tga";
--
-- vector pz = drawgetimagesize(txt) * 0.25;
-- drawpic(o - pz * 0.5, txt, pz , '1 1 1', 0.75, DRAWFLAG_NORMAL);
-- break;
-- }
-- }
-- }
--
-- 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)))
- 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;
- 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);
- 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) );
- 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_walker_draw()
--{
-- 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;
- 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);
--}
--
--void turret_ewheel_draw()
--{
-- float dt;
--
-- dt = time - self.move_time;
-- self.move_time = time;
-- if(dt <= 0)
-- return;
--
-- 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;
- self.angles_y = self.move_angles.y;
--
-- if (self.health < 127)
-- if(random() < 0.05)
-- te_spark(self.origin + '0 0 40', randomvec() * 256 + '0 0 256', 16);
--}
--
- void(entity e, entity tagentity, string tagname) setattachment = #443;
--void turret_construct()
--{
-- if(self.tur_head == world)
-- self.tur_head = spawn();
--
-- turret_tid2info(self.turret_type);
-- self.netname = tid2info_name;
--
-- setorigin(self, self.origin);
-- setmodel(self, tid2info_base);
-- setmodel(self.tur_head, tid2info_head);
-- setsize(self, tid2info_min, tid2info_max);
-- setsize(self.tur_head, '0 0 0', '0 0 0');
--
-- if(self.turret_type == TID_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;
--
-- if(self.turret_type == TID_EWHEEL || self.turret_type == TID_WALKER)
-- {
-- self.gravity = 1;
-- self.movetype = MOVETYPE_BOUNCE;
-- self.move_movetype = MOVETYPE_BOUNCE;
-- self.move_origin = self.origin;
-- self.move_time = time;
-- switch(self.turret_type)
-- {
-- case TID_EWHEEL:
-- self.draw = turret_ewheel_draw;
-- break;
-- case TID_WALKER:
-- self.draw = turret_walker_draw;
-- break;
--
-- }
-- }
--}
--
--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);
- 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);
-- turret_tid2info(self.turret_type);
-- if (!autocvar_cl_nogibs)
-- {
-- // Base
-- if(self.turret_type == TID_EWHEEL)
- turret_gibtoss(tid2info_base, self.origin + '0 0 18', self.velocity + '0 0 400' + '0.1 0.1 1' * (random() * 400), '-1 -1 -1', TRUE);
- turret_gibtoss(tid2info_base, self.origin + '0 0 18', self.velocity + '0 0 400' + '0.1 0.1 1' * (random() * 400), '-1 -1 -1', true);
-- else if (self.turret_type == TID_WALKER)
- turret_gibtoss(tid2info_base, self.origin + '0 0 18', self.velocity + '0 0 300' + '0.1 0.1 1' * (random() * 200), '-1 -1 -1', TRUE);
- turret_gibtoss(tid2info_base, self.origin + '0 0 18', self.velocity + '0 0 300' + '0.1 0.1 1' * (random() * 200), '-1 -1 -1', true);
-- else if (self.turret_type == TID_TESLA)
- turret_gibtoss(tid2info_base, self.origin + '0 0 18', '0 0 200', '-1 -1 -1', FALSE);
- turret_gibtoss(tid2info_base, 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);
- 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);
- turret_gibtoss("models/turrets/base-gib1.md3", self.origin + '0 0 8', '0 0 0', '0 0 0', true);
--
- entity headgib = turret_gibtoss(tid2info_head, self.origin + '0 0 32', '0 0 200' + randomvec() * 200, '-1 -1 -1', TRUE);
- entity headgib = turret_gibtoss(tid2info_head, 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.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();
- int sf = ReadByte();
--
-- if(sf & TNSF_SETUP)
-- {
-- self.turret_type = 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_precache(self.turret_type);
-- 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();
- int _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;
--}
+ #include "generic.qh"
+ #include "shared_defs.qh"
++#include "../turrets/config.qh"
+
// =========================================================
// Generic program common command code, written by Samual
// Last updated: February 19th, 2012
}
// used by curl command
- void Curl_URI_Get_Callback(float id, float status, string data)
+ void Curl_URI_Get_Callback(int id, float status, string data)
{
- float i;
- float do_exec;
- string do_cvar;
- i = id - URI_GET_CURL;
- do_exec = curl_uri_get_exec[i];
- do_cvar = curl_uri_get_cvar[i];
+ int i = id - URI_GET_CURL;
+ float do_exec = curl_uri_get_exec[i];
+ string do_cvar = curl_uri_get_cvar[i];
if(status != 0)
{
dprintf("error: status is %d\n", status);
{
case CMD_REQUEST_COMMAND:
{
- float i;
-
if(argc >= 2)
{
string original_cvar = argv(1);
else // add it to the end of the list if the list doesn't already have it
{
argc = tokenizebyseparator(cvar_string(original_cvar), " ");
-
+ int i;
for(i = 0; i < argc; ++i)
if(argv(i) == tmp_string)
return; // already in list
{
case CMD_REQUEST_COMMAND:
{
- float do_exec;
- string do_cvar;
- float key;
- float i, j;
- string url;
- float buf;
- float r;
-
- do_exec = FALSE;
- do_cvar = string_null;
- key = -1;
-
+ bool do_exec = false;
+ string do_cvar = string_null;
+ float key = -1;
+ int i;
for(i = 1; i+1 < argc; ++i)
{
if(argv(i) == "--cvar" && i+2 < argc)
}
if(argv(i) == "--exec")
{
- do_exec = TRUE;
+ do_exec = true;
continue;
}
if(argv(i) == "--key" && i+2 < argc)
// now, argv(i) is the URL
// following args may be POST parameters
- url = argv(i);
+ string url = argv(i);
++i;
- buf = buf_create();
- j = 0;
- for(; i+1 < argc; i += 2)
+ float buf = buf_create();
+ int j;
+ for(j = 0; i+1 < argc; i += 2)
bufstr_set(buf, ++j, sprintf("%s=%s", uri_escape(argv(i)), uri_escape(argv(i+1))));
if(i < argc)
bufstr_set(buf, ++j, sprintf("submit=%s", uri_escape(argv(i))));
+ float r;
if(j == 0) // no args: GET
r = crypto_uri_postbuf(url, URI_GET_CURL + curl_uri_get_pos, string_null, string_null, -1, key);
else // with args: POST
case CMD_REQUEST_COMMAND:
{
#ifndef MENUQC
- float fh, alsoprint = FALSE;
+ float fh, alsoprint = false;
string filename = argv(1);
if(filename == "")
{
filename = "notifications_dump.cfg";
- alsoprint = FALSE;
+ alsoprint = false;
}
else if(filename == "-")
{
filename = "notifications_dump.cfg";
- alsoprint = TRUE;
+ alsoprint = true;
}
fh = fopen(filename, FILE_WRITE);
wep_config_file = -1;
wep_config_alsoprint = -1;
string filename = argv(1);
-
+
if(filename == "")
{
filename = "weapons_dump.cfg";
- wep_config_alsoprint = FALSE;
+ wep_config_alsoprint = false;
}
else if(filename == "-")
{
filename = "weapons_dump.cfg";
- wep_config_alsoprint = TRUE;
+ wep_config_alsoprint = true;
}
wep_config_file = fopen(filename, FILE_WRITE);
-
+
if(wep_config_file >= 0)
{
Dump_Weapon_Settings();
#endif
return;
}
-
+
default:
case CMD_REQUEST_USAGE:
{
}
}
+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)
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("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 GENERIC_COMMAND(name,function,description) \
{ print(" ^2", name, "^7: ", description, "\n"); }
- GENERIC_COMMANDS(0, 0, "")
+ GENERIC_COMMANDS(0, 0, "");
#undef GENERIC_COMMAND
return;
float GenericCommand_macro_command(float argc, string command)
{
#define GENERIC_COMMAND(name,function,description) \
- { if(name == strtolower(argv(0))) { function; return TRUE; } }
+ { if(name == strtolower(argv(0))) { function; return true; } }
- GENERIC_COMMANDS(CMD_REQUEST_COMMAND, argc, command)
+ GENERIC_COMMANDS(CMD_REQUEST_COMMAND, argc, command);
#undef GENERIC_COMMAND
- return FALSE;
+ return false;
}
float GenericCommand_macro_usage(float argc)
{
#define GENERIC_COMMAND(name,function,description) \
- { if(name == strtolower(argv(1))) { function; return TRUE; } }
+ { if(name == strtolower(argv(1))) { function; return true; } }
- GENERIC_COMMANDS(CMD_REQUEST_USAGE, argc, "")
+ GENERIC_COMMANDS(CMD_REQUEST_USAGE, argc, "");
#undef GENERIC_COMMAND
- return FALSE;
+ return false;
}
void GenericCommand_macro_write_aliases(float fh)
#define GENERIC_COMMAND(name,function,description) \
{ CMD_Write_Alias("qc_cmd_svmenu", name, description); }
- GENERIC_COMMANDS(0, 0, "")
+ GENERIC_COMMANDS(0, 0, "");
#undef GENERIC_COMMAND
return;
if(GenericCommand_macro_command(argc, command)) // continue as usual and scan for normal commands
{
- return TRUE; // handled by one of the above GenericCommand_* functions
+ return true; // handled by one of the above GenericCommand_* functions
}
else if(argc >= 3 && argv(0) == "red")
{
s = substring(command, argv_start_index(2), argv_end_index(-1) - argv_start_index(2));
localcmd(strcat(argv(1), " ", GenericCommand_markup(s)));
- return TRUE;
+ return true;
}
else if(argc >= 3 && crc16(0, argv(0)) == 38566 && crc16(0, strcat(argv(0), argv(0), argv(0))) == 59830)
{
localcmd(strcat(argv(1), " ", s));
- return TRUE;
+ return true;
}
else if(argc >= 3 && crc16(0, argv(0)) == 3826 && crc16(0, strcat(argv(0), argv(0), argv(0))) == 55790)
{
localcmd(strcat(argv(1), " ", s2));
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
+ #ifndef DEATHTYPES_H
+ #define DEATHTYPES_H
+
+ #include "notifications.qh"
+
// ================================
// Deathtypes, reworked by Samual
// ================================
+ int DEATH_SPECIAL_START;
+ int NORMAL_POS;
+ int DEATH_MONSTER_FIRST;
+ int DEATH_MONSTER_LAST;
+ int DEATH_TURRET_FIRST;
+ int DEATH_TURRET_LAST;
+ int DEATH_VHFIRST;
+ int DEATH_VHLAST;
+
#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_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) \
#define DT_FIRST 10000
#define DT_MAX 128 // limit of recursive functions with ACCUMULATE_FUNCTION
- float DT_COUNT;
+ int DT_COUNT;
entity deathtypes[DT_MAX];
.entity death_msgself;
.entity death_msgmurder;
#define DEATHTYPE(name,msg_death,msg_death_by,position) \
- float name; \
- float position; \
+ int name; \
void RegisterDeathtype_##name() \
{ \
SET_FIRST_OR_LAST(position, DT_FIRST, DT_COUNT) \
#define DEATH_WEAPONOF(t) (DEATH_ISSPECIAL(t) ? 0 : DEATH_WEAPONOFWEAPONDEATH(t))
#define WEP_VALID(w) ((w) >= WEP_FIRST && (w) <= WEP_LAST)
- string Deathtype_Name(float deathtype)
+ string Deathtype_Name(int deathtype)
{
if(DEATH_ISSPECIAL(deathtype))
{
else { return ftos(deathtype); }
}
- const float DEATH_WEAPONMASK = 0xFF;
- const float DEATH_HITTYPEMASK = 0x1F00; // which is WAY below 10000 used for normal deaths
- const float HITTYPE_SECONDARY = 0x100;
- const float HITTYPE_SPLASH = 0x200; // automatically set by RadiusDamage
- const float HITTYPE_BOUNCE = 0x400;
- const float HITTYPE_RESERVED2 = 0x800;
- const float HITTYPE_RESERVED = 0x1000; // unused yet
+ const int DEATH_WEAPONMASK = 0xFF;
+ const int DEATH_HITTYPEMASK = 0x1F00; // which is WAY below 10000 used for normal deaths
+ const int HITTYPE_SECONDARY = 0x100;
+ const int HITTYPE_SPLASH = 0x200; // automatically set by RadiusDamage
+ const int HITTYPE_BOUNCE = 0x400;
+ const int HITTYPE_RESERVED2 = 0x800;
+ const int HITTYPE_RESERVED = 0x1000; // unused yet
+ #endif
- #include "../../server/tturrets/include/turrets_early.qh"
+ #if defined(CSQC)
+ #elif defined(MENUQC)
+ #elif defined(SVQC)
+ #include "../../dpdefs/progsdefs.qh"
+ #include "../../dpdefs/dpextensions.qh"
+ #include "../../warpzonelib/common.qh"
+ #include "../constants.qh"
+ #include "../teams.qh"
+ #include "../util.qh"
+ #include "monsters.qh"
+ #include "sv_monsters.qh"
+ #include "../weapons/weapons.qh"
+ #include "../../server/autocvars.qh"
+ #include "../../server/defs.qh"
+ #include "../deathtypes.qh"
+ #include "../../server/mutators/mutators_include.qh"
- #include "../../server/tturrets/include/turrets.qh"
+ #include "../../server/vehicles/vehicles_def.qh"
+ #include "../../server/campaign.qh"
+ #include "../../server/command/common.qh"
+ #include "../../server/command/cmd.qh"
+ #include "../../csqcmodellib/sv_model.qh"
+ #include "../../server/round_handler.qh"
+ #endif
+
// =========================
// SVQC Monster Properties
// =========================
if(e && e.monster_loot)
{
self = e;
- e.noalign = TRUE;
+ e.noalign = true;
e.monster_loot();
e.gravity = 1;
e.movetype = MOVETYPE_TOSS;
float monster_isvalidtarget (entity targ, entity ent)
{
if(!targ || !ent)
- return FALSE; // someone doesn't exist
+ return false; // someone doesn't exist
if(targ == ent)
- return FALSE; // don't attack ourselves
+ return false; // don't attack ourselves
//traceline(ent.origin, targ.origin, MOVE_NORMAL, ent);
//if(trace_ent != targ)
- //return FALSE;
+ //return false;
if(targ.vehicle_flags & VHF_ISVEHICLE)
if(!((get_monsterinfo(ent.monsterid)).spawnflags & MON_FLAG_RANGED))
- return FALSE; // melee attacks are useless against vehicles
+ return false; // melee attacks are useless against vehicles
if(time < game_starttime)
- return FALSE; // monsters do nothing before the match has started
+ return false; // monsters do nothing before the match has started
if(targ.takedamage == DAMAGE_NO)
- return FALSE; // enemy can't be damaged
+ return false; // enemy can't be damaged
if(targ.items & IT_INVISIBILITY)
- return FALSE; // enemy is invisible
+ return false; // enemy is invisible
if(substring(targ.classname, 0, 10) == "onslaught_")
- return FALSE; // don't attack onslaught targets
+ return false; // don't attack onslaught targets
if(IS_SPEC(targ) || IS_OBSERVER(targ))
- return FALSE; // enemy is a spectator
+ return false; // enemy is a spectator
if(!(targ.vehicle_flags & VHF_ISVEHICLE))
if(targ.deadflag != DEAD_NO || ent.deadflag != DEAD_NO || targ.health <= 0 || ent.health <= 0)
- return FALSE; // enemy/self is dead
+ return false; // enemy/self is dead
if(ent.monster_owner == targ)
- return FALSE; // don't attack our master
+ return false; // don't attack our master
if(targ.monster_owner == ent)
- return FALSE; // don't attack our pet
+ return false; // don't attack our pet
if(!(targ.vehicle_flags & VHF_ISVEHICLE))
if(targ.flags & FL_NOTARGET)
- return FALSE; // enemy can't be targeted
+ return false; // enemy can't be targeted
if(!autocvar_g_monsters_typefrag)
if(targ.BUTTON_CHAT)
- return FALSE; // no typefragging!
+ return false; // no typefragging!
if(SAME_TEAM(targ, ent))
- return FALSE; // enemy is on our team
+ return false; // enemy is on our team
if (targ.frozen)
- return FALSE; // ignore frozen
+ return false; // ignore frozen
if(autocvar_g_monsters_target_infront || (ent.spawnflags & MONSTERFLAG_INFRONT))
if(ent.enemy != targ)
dot = normalize (targ.origin - ent.origin) * v_forward;
if(dot <= 0.3)
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
entity FindTarget (entity ent)
entity head, closest_target = world;
head = findradius(ent.origin, ent.target_range);
- //head = WarpZone_FindRadius(ent.origin, ent.target_range, TRUE);
+ //head = WarpZone_FindRadius(ent.origin, ent.target_range, true);
while(head) // find the closest acceptable target to pass to
{
float globhandle, n, i;
string f;
- globhandle = search_begin(strcat(m, "_*.sounds"), TRUE, FALSE);
+ globhandle = search_begin(strcat(m, "_*.sounds"), true, false);
if (globhandle < 0)
return;
n = search_getsize(globhandle);
return 1;
}
- .float skin_for_monstersound;
+ .int skin_for_monstersound;
void UpdateMonsterSounds()
{
entity mon = get_monsterinfo(self.monsterid);
v = e.origin + (e.mins + e.maxs) * 0.5;
self.v_angle = vectoangles(v - (self.origin + self.view_ofs));
- self.v_angle_x = -self.v_angle_x;
+ self.v_angle_x = -self.v_angle.x;
makevectors(self.v_angle);
}
float monster_melee(entity targ, float damg, float anim, float er, float anim_finished, float deathtype, float dostop)
{
if (self.health <= 0)
- return FALSE; // attacking while dead?!
+ return false; // attacking while dead?!
if(dostop)
{
if(trace_ent.takedamage)
Damage(trace_ent, self, self, damg * Monster_SkillModifier(), deathtype, trace_ent.origin, normalize(trace_ent.origin - self.origin));
- return TRUE;
+ return true;
}
void Monster_CheckMinibossFlag ()
other = ent;
if(ent.deadflag == DEAD_DEAD) // don't call when monster isn't dead
if(MUTATOR_CALLHOOK(MonsterRespawn))
- return TRUE; // enabled by a mutator
+ return true; // enabled by a mutator
if(ent.spawnflags & MONSTERFLAG_NORESPAWN)
- return FALSE;
+ return false;
if(!autocvar_g_monsters_respawn)
- return FALSE;
+ return false;
- return TRUE;
+ return true;
}
- float monster_initialize(float mon_id);
void monster_respawn()
{
// is this function really needed?
float Monster_CanJump (vector vel)
{
if(self.state)
- return FALSE; // already attacking
+ return false; // already attacking
if(!(self.flags & FL_ONGROUND))
- return FALSE; // not on the ground
+ return false; // not on the ground
if(self.health <= 0)
- return FALSE; // called when dead?
+ return false; // called when dead?
if(time < self.attack_finished_single)
- return FALSE; // still attacking
+ return false; // still attacking
vector old = self.velocity;
tracetoss(self, self);
self.velocity = old;
if (trace_ent != self.enemy)
- return FALSE;
+ return false;
- return TRUE;
+ return true;
}
float monster_leap (float anm, void() touchfunc, vector vel, float anim_finished)
{
if(!Monster_CanJump(vel))
- return FALSE;
+ return false;
self.frame = anm;
self.state = MONSTER_STATE_ATTACK_LEAP;
self.attack_finished_single = time + anim_finished;
- return TRUE;
+ return true;
}
void monster_checkattack(entity e, entity targ)
if(vlen(targ.origin - e.origin) <= e.attack_range)
if(e.monster_attackfunc(MONSTER_ATTACK_MELEE))
{
- MonsterSound(monstersound_melee, 0, FALSE, CH_VOICE);
+ MonsterSound(monstersound_melee, 0, false, CH_VOICE);
return;
}
if(vlen(targ.origin - e.origin) > e.attack_range)
if(e.monster_attackfunc(MONSTER_ATTACK_RANGED))
{
- MonsterSound(monstersound_ranged, 0, FALSE, CH_VOICE);
+ MonsterSound(monstersound_ranged, 0, false, CH_VOICE);
return;
}
}
vector targ_origin = ((self.enemy.absmin + self.enemy.absmax) * 0.5);
targ_origin = WarpZone_RefSys_TransformOrigin(self.enemy, self, targ_origin); // origin of target as seen by the monster (us)
WarpZone_TraceLine(self.origin, targ_origin, MOVE_NOMONSTERS, self);
-
+
if((self.enemy == world)
|| (self.enemy.deadflag != DEAD_NO || self.enemy.health < 1)
|| (self.enemy.frozen)
self.enemy = world;
self.pass_distance = 0;
}
-
+
if(self.enemy)
{
/*WarpZone_TrailParticles(world, particleeffectnum("red_pass"), self.origin, targ_origin);
print("Trace origin: ", vtos(targ_origin), "\n");
print("Target origin: ", vtos(self.enemy.origin), "\n");
print("My origin: ", vtos(self.origin), "\n"); */
-
+
self.monster_movestate = MONSTER_MOVE_ENEMY;
self.last_trace = time + 1.2;
return targ_origin;
}
-
+
/*makevectors(self.angles);
self.monster_movestate = MONSTER_MOVE_ENEMY;
self.last_trace = time + 1.2;
if(((self.flags & FL_FLY) && (self.spawnflags & MONSTERFLAG_FLY_VERTICAL)) || (self.flags & FL_SWIM))
{
- pos_z = random() * 200;
+ pos.z = random() * 200;
if(random() >= 0.5)
- pos_z *= -1;
+ pos.z *= -1;
}
}
void monster_CalculateVelocity(entity mon, vector to, vector from, float turnrate, float movespeed)
{
- 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 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)));
//print("current_height = ", ftos(current_height), ", initial_height = ", ftos(initial_height), ".\n");
{
if(time >= self.last_trace)
{
- self.fish_wasdrowning = TRUE;
+ self.fish_wasdrowning = true;
self.last_trace = time + 0.4;
Damage (self, world, world, 2, DEATH_DROWN, self.origin, '0 0 0');
}
else if(self.fish_wasdrowning)
{
- self.fish_wasdrowning = FALSE;
+ self.fish_wasdrowning = false;
self.angles_x = 0;
self.movetype = MOVETYPE_WALK;
}
WarpZone_RefSys_Copy(self.enemy, self);
WarpZone_RefSys_AddInverse(self.enemy, self); // wz1^-1 ... wzn^-1 receiver
self.moveto = WarpZone_RefSys_TransformOrigin(self.enemy, self, (0.5 * (self.enemy.absmin + self.enemy.absmax)));
-
- self.pass_distance = vlen((('1 0 0' * self.enemy.origin_x) + ('0 1 0' * self.enemy.origin_y)) - (('1 0 0' * self.origin_x) + ('0 1 0' * self.origin_y)));
- MonsterSound(monstersound_sight, 0, FALSE, CH_VOICE);
+
+ self.pass_distance = vlen((('1 0 0' * self.enemy.origin.x) + ('0 1 0' * self.enemy.origin.y)) - (('1 0 0' * self.origin.x) + ('0 1 0' * self.origin.y)));
+ MonsterSound(monstersound_sight, 0, false, CH_VOICE);
}
}
self.moveto = monster_pickmovetarget(targ);
if(!self.enemy)
- MonsterSound(monstersound_idle, 7, TRUE, CH_VOICE);
+ MonsterSound(monstersound_idle, 7, true, CH_VOICE);
if(self.state == MONSTER_STATE_ATTACK_LEAP && (self.flags & FL_ONGROUND))
{
if(!(((self.flags & FL_FLY) && (self.spawnflags & MONSTERFLAG_FLY_VERTICAL)) || (self.flags & FL_SWIM)))
//v_forward = normalize(self.moveto - self.origin);
//else
- self.moveto_z = self.origin_z;
+ self.moveto_z = self.origin.z;
if(vlen(self.origin - self.moveto) > 64)
{
if((self.flags & FL_ONGROUND) || ((self.flags & FL_FLY) || (self.flags & FL_SWIM)))
- monster_CalculateVelocity(self, self.moveto, self.origin, TRUE, ((self.enemy) ? runspeed : walkspeed));
-
+ monster_CalculateVelocity(self, self.moveto, self.origin, true, ((self.enemy) ? runspeed : walkspeed));
+
/*&if(self.flags & FL_FLY || self.flags & FL_SWIM)
movelib_move_simple(v_forward, ((self.enemy) ? runspeed : walkspeed), 0.6);
else
if (vlen(self.velocity) <= 30)
self.frame = manim_idle;
}
-
+
self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
-
+
vector real_angle = vectoangles(self.steerto) - self.angles;
float turny = 25;
if(self.state == MONSTER_STATE_ATTACK_MELEE)
turny = 0;
if(turny)
{
- turny = bound(turny * -1, shortangle_f(real_angle_y, self.angles_y), turny);
+ turny = bound(turny * -1, shortangle_f(real_angle.y, self.angles.y), turny);
self.angles_y += turny;
}
float Monster_CheckAppearFlags(entity ent, float monster_id)
{
if(!(ent.spawnflags & MONSTERFLAG_APPEAR))
- return FALSE;
+ return false;
ent.think = func_null;
ent.monsterid = monster_id; // set so this monster is properly registered (otherwise, normal initialization is used)
ent.use = Monster_Appear;
ent.flags = FL_MONSTER; // set so this monster can get butchered
- return TRUE;
+ return true;
}
void monsters_reset()
monster_dropitem();
- MonsterSound(monstersound_death, 0, FALSE, CH_VOICE);
+ MonsterSound(monstersound_death, 0, false, CH_VOICE);
if(!(self.spawnflags & MONSTERFLAG_SPAWNED) && !(self.spawnflags & MONSTERFLAG_RESPAWNED))
monsters_killed += 1;
float take, save;
v = healtharmor_applydamage(self.armorvalue, self.m_armor_blockpercent, deathtype, damage);
- take = v_x;
- save = v_y;
+ take = v.x;
+ save = v.y;
self.health -= take;
if(self.health <= 0)
{
if(deathtype == DEATH_KILL)
- self.candrop = FALSE; // killed by mobkill command
+ self.candrop = false; // killed by mobkill command
// TODO: fix this?
activator = attacker;
void monster_changeteam(entity ent, float newteam)
{
if(!teamplay) { return; }
-
+
ent.team = newteam;
- ent.monster_attack = TRUE; // new team, activate attacking
+ ent.monster_attack = true; // new team, activate attacking
monster_setupcolors(ent);
-
+
if(ent.sprite)
{
WaypointSprite_UpdateTeamRadar(ent.sprite, RADARICON_DANGER, ((newteam) ? Team_ColorRGB(newteam) : '1 0 0'));
UpdateMonsterSounds();
if(teamplay)
- self.monster_attack = TRUE; // we can have monster enemies in team games
+ self.monster_attack = true; // we can have monster enemies in team games
- MonsterSound(monstersound_spawn, 0, FALSE, CH_VOICE);
+ MonsterSound(monstersound_spawn, 0, false, CH_VOICE);
- WaypointSprite_Spawn(M_NAME(self.monsterid), 0, 1024, self, '0 0 1' * (self.maxs_z + 15), world, self.team, self, sprite, TRUE, RADARICON_DANGER, ((self.team) ? Team_ColorRGB(self.team) : '1 0 0'));
+ WaypointSprite_Spawn(M_NAME(self.monsterid), 0, 1024, self, '0 0 1' * (self.maxs.z + 15), world, self.team, self, sprite, true, RADARICON_DANGER, ((self.team) ? Team_ColorRGB(self.team) : '1 0 0'));
if(!(self.spawnflags & MONSTERFLAG_INVINCIBLE))
{
WaypointSprite_UpdateMaxHealth(self.sprite, self.max_health);
self.nextthink = time + self.ticrate;
if(MUTATOR_CALLHOOK(MonsterSpawn))
- return FALSE;
+ return false;
- return TRUE;
+ return true;
}
float monster_initialize(float mon_id)
{
- if(!autocvar_g_monsters) { return FALSE; }
+ if(!autocvar_g_monsters) { return false; }
if(!(self.spawnflags & MONSTERFLAG_RESPAWNED)) { MON_ACTION(mon_id, MR_PRECACHE); }
- if(Monster_CheckAppearFlags(self, mon_id)) { return TRUE; } // return true so the monster isn't removed
+ if(Monster_CheckAppearFlags(self, mon_id)) { return true; } // return true so the monster isn't removed
entity mon = get_monsterinfo(mon_id);
self.monster_skill = cvar("g_monsters_skill");
// support for quake style removing monsters based on skill
- if(self.monster_skill == MONSTER_SKILL_EASY) if(self.spawnflags & MONSTERSKILL_NOTEASY) { return FALSE; }
- if(self.monster_skill == MONSTER_SKILL_MEDIUM) if(self.spawnflags & MONSTERSKILL_NOTMEDIUM) { return FALSE; }
- if(self.monster_skill == MONSTER_SKILL_HARD) if(self.spawnflags & MONSTERSKILL_NOTHARD) { return FALSE; }
+ if(self.monster_skill == MONSTER_SKILL_EASY) if(self.spawnflags & MONSTERSKILL_NOTEASY) { return false; }
+ if(self.monster_skill == MONSTER_SKILL_MEDIUM) if(self.spawnflags & MONSTERSKILL_NOTMEDIUM) { return false; }
+ if(self.monster_skill == MONSTER_SKILL_HARD) if(self.spawnflags & MONSTERSKILL_NOTHARD) { return false; }
if(self.team && !teamplay)
self.team = 0;
//setsize(self, mon.mins, mon.maxs);
self.flags = FL_MONSTER;
self.takedamage = DAMAGE_AIM;
- self.bot_attack = TRUE;
- self.iscreature = TRUE;
- self.teleportable = TRUE;
- self.damagedbycontents = TRUE;
+ self.bot_attack = true;
+ self.iscreature = true;
+ self.teleportable = true;
+ self.damagedbycontents = true;
self.monsterid = mon_id;
self.damageforcescale = 0;
self.event_damage = monsters_damage;
self.reset = monsters_reset;
self.netname = mon.netname;
self.monster_name = M_NAME(mon_id);
- self.candrop = TRUE;
- self.view_ofs = '0 0 1' * (self.maxs_z * 0.5);
+ self.candrop = true;
+ self.view_ofs = '0 0 1' * (self.maxs.z * 0.5);
self.oldtarget2 = self.target2;
self.pass_distance = 0;
self.deadflag = DEAD_NO;
if(mon.spawnflags & MONSTER_SIZE_BROKEN)
if(!(self.spawnflags & MONSTERFLAG_RESPAWNED))
self.scale *= 1.3;
-
+
setsize(self, mon.mins * self.scale, mon.maxs * self.scale);
if(!self.ticrate)
}
if(!monster_spawn())
- return FALSE;
+ return false;
if(!(self.spawnflags & MONSTERFLAG_RESPAWNED))
monster_setupcolors(self);
CSQCMODEL_AUTOINIT();
- return TRUE;
+ return true;
}
- .float healer_lifetime;
- .float healer_radius;
+ #if defined(CSQC)
+ #include "../dpdefs/csprogsdefs.qh"
+ #include "../client/defs.qh"
+ #include "nades.qh"
+ #include "buffs.qh"
+ #include "../client/movetypes.qh"
- #include "../server/tturrets/include/turrets_early.qh"
+ #include "../client/main.qh"
+ #include "../csqcmodellib/cl_model.qh"
+ #elif defined(MENUQC)
+ #elif defined(SVQC)
+ #include "../dpdefs/progsdefs.qh"
+ #include "constants.qh"
+ #include "../server/constants.qh"
+ #endif
+
#ifdef SVQC
- float healer_send(entity to, float sf)
+ float healer_send(entity to, int sf)
{
WriteByte(MSG_ENTITY, ENT_CLIENT_HEALING_ORB);
WriteByte(MSG_ENTITY, sf);
if(sf & 1)
{
- WriteCoord(MSG_ENTITY, self.origin_x);
- WriteCoord(MSG_ENTITY, self.origin_y);
- WriteCoord(MSG_ENTITY, self.origin_z);
+ WriteCoord(MSG_ENTITY, self.origin.x);
+ WriteCoord(MSG_ENTITY, self.origin.y);
+ WriteCoord(MSG_ENTITY, self.origin.z);
WriteByte(MSG_ENTITY, self.healer_lifetime);
//WriteByte(MSG_ENTITY, self.ltime - time + 1);
WriteByte(MSG_ENTITY, (self.ltime - time)*10.0+0.5);
}
- return TRUE;
+ return true;
}
#endif // SVQC
setmodel(self, "models/ctf/shield.md3");
setorigin(self, self.origin);
-
- float model_radius = self.maxs_x;
+
+ float model_radius = self.maxs.x;
vector size = '1 1 1' * self.healer_radius / 2;
setsize(self,-size,size);
self.healer_radius = self.healer_radius/model_radius*0.6;
void ent_healer()
{
- float sf = ReadByte();
+ int sf = ReadByte();
if(sf & TNSF_SETUP)
{
healer_setup();
}
}
- #endif // CSQC
+ #endif // CSQC
+ #ifndef NOTIFICATIONS_H
+ #define NOTIFICATIONS_H
+
+ #include "constants.qh"
+ #include "teams.qh"
+
// ================================================
// Unified notification system, written by Samual
// Last updated: March, 2013
// ================================================
// main types/groups of notifications
- #define MSG_ANNCE 1 // "Global" AND "personal" announcer messages
- #define MSG_INFO 2 // "Global" information messages
- #define MSG_CENTER 3 // "Personal" centerprint messages
- #define MSG_CENTER_CPID 4 // Kill centerprint message
- #define MSG_MULTI 5 // Subcall MSG_INFO and/or MSG_CENTER notifications
- #define MSG_CHOICE 6 // Choose which subcall wrapper to activate
+ const int MSG_ANNCE = 1; // "Global" AND "personal" announcer messages
+ const int MSG_INFO = 2; // "Global" information messages
+ const int MSG_CENTER = 3; // "Personal" centerprint messages
+ const int MSG_CENTER_CPID = 4; // Kill centerprint message
+ const int MSG_MULTI = 5; // Subcall MSG_INFO and/or MSG_CENTER notifications
+ const int MSG_CHOICE = 6; // Choose which subcall wrapper to activate
// negative confirmations
- #define NO_MSG -12345 // allows various things to know when no information is added
- #define NOTIF_ABORT -1234 // allows Send_Notification to safely abort sending
+ const int NO_MSG = -12345; // allows various things to know when no information is added
+ const int NOTIF_ABORT = -1234; // allows Send_Notification to safely abort sending
#define EIGHT_VARS_TO_VARARGS_VARLIST \
VARITEM(1, 0, s1) \
void Create_Notification_Entity(
float var_default,
float var_cvar,
- float typeid,
+ float typeId,
float nameid,
string namestring,
- float strnum,
- float flnum,
+ int strnum,
+ int flnum,
/* MSG_ANNCE */
float channel,
string snd,
void Debug_Notification(string input);
#endif
- void Local_Notification(float net_type, float net_name, ...count);
+ void Local_Notification(int net_type, int net_name, ...count);
void Local_Notification_WOVA(
float net_type, float net_name,
float stringcount, float floatcount,
#endif
#ifdef SVQC // SERVER ONLY
- #define NOTIF_ONE 1
- #define NOTIF_ONE_ONLY 2
- #define NOTIF_TEAM 3
- #define NOTIF_TEAM_EXCEPT 4
- #define NOTIF_ALL 5
- #define NOTIF_ALL_EXCEPT 6
+ const float NOTIF_ONE = 1;
+ const float NOTIF_ONE_ONLY = 2;
+ const float NOTIF_TEAM = 3;
+ const float NOTIF_TEAM_EXCEPT = 4;
+ const float NOTIF_ALL = 5;
+ const float NOTIF_ALL_EXCEPT = 6;
void Kill_Notification(
float broadcast, entity client,
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_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_WEAPON_MINELAYER_LIMIT, 0, 1, "f1", NO_CPID, "0 0", _("^BGYou cannot place more than ^F2%s^BG mines at a time"), "")
+ 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) \
MSG_MULTI_NOTIF(default, prefix##RED, anncepre##RED, infopre##RED, centerpre##RED) \
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) \
// MAKE SURE THIS IS ALWAYS SYNCHRONIZED WITH THE DUMP
// NOTIFICATIONS FUNCTION IN THE .QC FILE!
- #define NOTIF_ADD_AUTOCVAR(name,default) var float autocvar_notification_##name = default;
+ #define NOTIF_ADD_AUTOCVAR(name,default) float autocvar_notification_##name = default;
- var float autocvar_notification_show_location = FALSE;
- var string autocvar_notification_show_location_string = ""; //_(" at the %s");
- var float autocvar_notification_show_sprees = TRUE;
- var float autocvar_notification_show_sprees_info = 3; // 0 = off, 1 = target only, 2 = attacker only, 3 = target and attacker
- var float autocvar_notification_show_sprees_info_newline = TRUE;
- var float autocvar_notification_show_sprees_info_specialonly = TRUE;
- var float autocvar_notification_errors_are_fatal = TRUE;
- var float autocvar_notification_lifetime_runtime = 0.5;
- var float autocvar_notification_lifetime_mapload = 10;
- var float autocvar_notification_debug = FALSE;
+ float autocvar_notification_show_location = false;
+ string autocvar_notification_show_location_string = ""; //_(" at the %s");
+ float autocvar_notification_show_sprees = true;
+ float autocvar_notification_show_sprees_info = 3; // 0 = off, 1 = target only, 2 = attacker only, 3 = target and attacker
+ float autocvar_notification_show_sprees_info_newline = true;
+ float autocvar_notification_show_sprees_info_specialonly = true;
+ float autocvar_notification_errors_are_fatal = true;
+ float autocvar_notification_lifetime_runtime = 0.5;
+ float autocvar_notification_lifetime_mapload = 10;
+ float autocvar_notification_debug = false;
#ifdef SVQC
.float FRAG_VERBOSE;
void Notification_GetCvars(void);
- var float autocvar_notification_server_allows_location = 1; // 0 = no, 1 = yes
+ float autocvar_notification_server_allows_location = 1; // 0 = no, 1 = yes
#else
- var float autocvar_notification_item_centerprinttime = 1.5;
+ float autocvar_notification_item_centerprinttime = 1.5;
// 0 = no, 1 = yes, 2 = forced on for all MSG_INFO notifs
// DISABLED IN CODE, BUT ENABLED IN CONFIG FOR COMPATIBILITY WITH OLD CLIENTS
- var float autocvar_notification_allow_chatboxprint = 0;
+ float autocvar_notification_allow_chatboxprint = 0;
- var float autocvar_notification_show_sprees_center = TRUE;
- var float autocvar_notification_show_sprees_center_specialonly = TRUE;
+ float autocvar_notification_show_sprees_center = true;
+ float autocvar_notification_show_sprees_center_specialonly = true;
#endif
death_team: show the full name of the team a player is switching from
*/
- #define NOTIF_MAX_ARGS 7
- #define NOTIF_MAX_HUDARGS 2
- #define NOTIF_MAX_DURCNT 2
+ const float NOTIF_MAX_ARGS = 7;
+ const float NOTIF_MAX_HUDARGS = 2;
+ const float NOTIF_MAX_DURCNT = 2;
string arg_slot[NOTIF_MAX_ARGS];
- #define ARG_CS_SV_HA 1 // enabled on CSQC, SVQC, and Hudargs
- #define ARG_CS_SV_DC 2 // enabled on CSQC, SVQC, and durcnt centerprint
- #define ARG_CS_SV 3 // enabled on CSQC and SVQC
- #define ARG_CS 4 // unique result to CSQC
- #define ARG_SV 5 // unique result to SVQC
- #define ARG_DC 6 // unique result to durcnt/centerprint
+ const float ARG_CS_SV_HA = 1; // enabled on CSQC, SVQC, and Hudargs
+ const float ARG_CS_SV_DC = 2; // enabled on CSQC, SVQC, and durcnt centerprint
+ const float ARG_CS_SV = 3; // enabled on CSQC and SVQC
+ const float ARG_CS = 4; // unique result to CSQC
+ const float ARG_SV = 5; // unique result to SVQC
+ const float ARG_DC = 6; // unique result to durcnt/centerprint
// todo possible idea.... declare how many floats/strings each arg needs, and then dynamically increment the input
// this way, we don't need to have duplicates like i.e. s2loc and s3loc?
ARG_CASE(ARG_CS_SV, "race_diff", ((f2 > f3) ? sprintf(CCR("^1[+%s]"), mmssss(f2 - f3)) : sprintf(CCR("^2[-%s]"), mmssss(f3 - f2)))) \
ARG_CASE(ARG_CS, "missing_teams", notif_arg_missing_teams(f1)) \
ARG_CASE(ARG_CS, "pass_key", ((((tmp_s = getcommandkey("pass", "+use")) != "pass") && !(strstrofs(tmp_s, "not bound", 0) >= 0)) ? sprintf(CCR(_(" ^F1(Press %s)")), tmp_s) : "")) \
- ARG_CASE(ARG_CS, "frag_ping", notif_arg_frag_ping(TRUE, f2)) \
+ ARG_CASE(ARG_CS, "frag_ping", notif_arg_frag_ping(true, f2)) \
ARG_CASE(ARG_CS, "frag_stats", notif_arg_frag_stats(f2, f3, f4)) \
/*ARG_CASE(ARG_CS, "frag_pos", ((Should_Print_Score_Pos(f1)) ? sprintf("\n^BG%s", Read_Score_Pos(f1)) : ""))*/ \
ARG_CASE(ARG_CS, "spree_cen", (autocvar_notification_show_sprees ? notif_arg_spree_cen(f1) : "")) \
ARG_CASE(ARG_SV, "death_team", Team_ColoredFullName(f1)) \
ARG_CASE(ARG_CS, "death_team", Team_ColoredFullName(f1 - 1))
- #define NOTIF_HIT_MAX(count,funcname) if(sel_num == count) { backtrace(sprintf("%s: Hit maximum arguments!\n", funcname)); break; }
+ #define NOTIF_HIT_MAX(count,funcname) do { \
+ if(sel_num == count) { backtrace(sprintf("%s: Hit maximum arguments!\n", funcname)); break; } \
+ } while(0)
#define NOTIF_HIT_UNKNOWN(token,funcname) { backtrace(sprintf("%s: Hit unknown token in selected string! '%s'\n", funcname, selected)); break; }
#define KILL_SPREE_LIST \
string notif_arg_frag_stats(float fhealth, float farmor, float fping)
{
if (!(fhealth < 1))
- return sprintf(CCR(_("\n(Health ^1%d^BG / Armor ^2%d^BG)%s")), fhealth, farmor, notif_arg_frag_ping(FALSE, fping));
+ return sprintf(CCR(_("\n(Health ^1%d^BG / Armor ^2%d^BG)%s")), fhealth, farmor, notif_arg_frag_ping(false, fping));
else
- return sprintf(CCR(_("\n(^F4Dead^BG)%s")), notif_arg_frag_ping(FALSE, fping));
+ return sprintf(CCR(_("\n(^F4Dead^BG)%s")), notif_arg_frag_ping(false, fping));
}
string notif_arg_missing_teams(float f1)
// Initialization/Create Declarations
// ====================================
+ enum {
+ NO_CPID
+ , CPID_ASSAULT_ROLE
+ , CPID_ROUND
+ , CPID_CAMPCHECK
+ , CPID_CTF_CAPSHIELD
+ , CPID_CTF_LOWPRIO
+ , CPID_CTF_PASS
+ , CPID_STALEMATE
+ , CPID_NADES
+ , CPID_IDLING
+ , CPID_ITEM
+ , CPID_PREVENT_JOIN
+ , CPID_KEEPAWAY
+ , CPID_KEEPAWAY_WARN
+ , CPID_KEYHUNT
+ , CPID_KEYHUNT_OTHER
+ , CPID_LMS
+ , CPID_MISSING_TEAMS
+ , CPID_MISSING_PLAYERS
+ , CPID_INSTAGIB_FINDAMMO
+ , CPID_MOTD
+ , CPID_NIX
+ , CPID_ONSLAUGHT
+ , CPID_OVERTIME
+ , CPID_POWERUP
+ , CPID_RACE_FINISHLAP
+ , CPID_TEAMCHANGE
+ , CPID_TIMEOUT
+ // always last
+ , NOTIF_CPID_COUNT
+ };
// notification counts
- #define NOTIF_FIRST 1
+ const float NOTIF_FIRST = 1;
float NOTIF_ANNCE_COUNT;
float NOTIF_INFO_COUNT;
float NOTIF_CENTER_COUNT;
float NOTIF_MULTI_COUNT;
float NOTIF_CHOICE_COUNT;
- float NOTIF_CPID_COUNT;
// notification limits -- INCREASE AS NECESSARY
- #define NOTIF_ANNCE_MAX 100
- #define NOTIF_INFO_MAX 300
- #define NOTIF_CENTER_MAX 200
- #define NOTIF_MULTI_MAX 200
- #define NOTIF_CHOICE_MAX 20
+ const float NOTIF_ANNCE_MAX = 100;
+ const float NOTIF_INFO_MAX = 300;
+ const float NOTIF_CENTER_MAX = 200;
+ const float NOTIF_MULTI_MAX = 200;
+ const float NOTIF_CHOICE_MAX = 20;
// notification entities
entity msg_annce_notifs[NOTIF_ANNCE_MAX];
.float nent_type;
.float nent_id;
.string nent_name;
- .float nent_stringcount;
- .float nent_floatcount;
+ .int nent_stringcount;
+ .int nent_floatcount;
// MSG_ANNCE entity values
.float nent_channel;
/* COMMON ======================== */ \
default, /* var_default */ \
ACVNN(name), /* var_cvar */ \
- MSG_ANNCE, /* typeid */ \
+ MSG_ANNCE, /* typeId */ \
name, /* nameid */ \
strtoupper(#name), /* namestring */ \
NO_MSG, /* strnum */ \
#define MSG_INFO_NOTIF(default,name,strnum,flnum,args,hudargs,icon,normal,gentle) \
NOTIF_ADD_AUTOCVAR(name, default) \
- float name; \
+ int name; \
void RegisterNotification_##name() \
{ \
SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_INFO_COUNT) \
/* COMMON ======================== */ \
default, /* var_default */ \
ACVNN(name), /* var_cvar */ \
- MSG_INFO, /* typeid */ \
+ MSG_INFO, /* typeId */ \
name, /* nameid */ \
strtoupper(#name), /* namestring */ \
strnum, /* strnum */ \
#define MSG_CENTER_NOTIF(default,name,strnum,flnum,args,cpid,durcnt,normal,gentle) \
NOTIF_ADD_AUTOCVAR(name, default) \
float name; \
- float cpid; \
void RegisterNotification_##name() \
{ \
SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_CENTER_COUNT) \
- SET_FIELD_COUNT(cpid, NOTIF_FIRST, NOTIF_CPID_COUNT) \
CHECK_MAX_COUNT(name, NOTIF_CENTER_MAX, NOTIF_CENTER_COUNT, "MSG_CENTER") \
Create_Notification_Entity( \
/* COMMON ======================== */ \
default, /* var_default */ \
ACVNN(name), /* var_cvar */ \
- MSG_CENTER, /* typeid */ \
+ MSG_CENTER, /* typeId */ \
name, /* nameid */ \
strtoupper(#name), /* namestring */ \
strnum, /* strnum */ \
#define MSG_MULTI_NOTIF(default,name,anncename,infoname,centername) \
NOTIF_ADD_AUTOCVAR(name, default) \
- float name; \
+ int name; \
void RegisterNotification_##name() \
{ \
SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_MULTI_COUNT) \
/* COMMON ======================== */ \
default, /* var_default */ \
ACVNN(name), /* var_cvar */ \
- MSG_MULTI, /* typeid */ \
+ MSG_MULTI, /* typeId */ \
name, /* nameid */ \
strtoupper(#name), /* namestring */ \
NO_MSG, /* strnum */ \
/* COMMON ======================== */ \
default, /* var_default */ \
ACVNN(name), /* var_cvar */ \
- MSG_CHOICE, /* typeid */ \
+ MSG_CHOICE, /* typeId */ \
name, /* nameid */ \
strtoupper(#name), /* namestring */ \
NO_MSG, /* strnum */ \
void RegisterNotifications_First()
{
- notif_global_error = FALSE;
+ notif_global_error = false;
#ifdef SVQC
#define dedi (server_is_dedicated ? "a dedicated " : "")
#else
if(autocvar_notification_version_mismatch_server_error)
#endif
- notif_global_error = TRUE;
+ notif_global_error = true;
printf("^1NOTIFICATION VERSION MISMATCH: ^7program = %s, config = %d, code = %d.\n",
PROGNAME, autocvar_notification_version, NOTIF_VERSION);
#undef MSG_CHOICE_NOTIF
#undef NOTIF_ADD_AUTOCVAR
+ #endif
--- /dev/null
- void(entity e, entity tagentity, string tagname) setattachment = #443;
+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-mover.tga";
+ else
+ txt = "gfx/vehicles/vth-stationary.tga";
+
+ vector pz = drawgetimagesize(txt) * 0.25;
+ drawpic(o - pz * 0.5, txt, pz , '1 1 1', 0.75, 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
+ );
+}
+
- turret_gibtoss(strcat("models/turrets/head-gib", ftos(i), ".md3"), self.origin + '0 0 2', self.velocity + randomvec() * 700, '0 0 0', FALSE);
+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((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);
++ 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 300' + '0.1 0.1 1' * (random() * 200), '-1 -1 -1', TRUE);
++ 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', '0 0 200', '-1 -1 -1', FALSE);
++ 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("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);
++ 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-gib1.md3", self.origin + '0 0 8', '0 0 0', '0 0 0', TRUE);
++ 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
- entity headgib = turret_gibtoss((get_turretinfo(self.turretid)).head_model, self.origin + '0 0 32', '0 0 200' + randomvec() * 200, '-1 -1 -1', TRUE);
++ 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
++#ifndef CL_TURRETS_H
++#define CL_TURRETS_H
++
+void ent_turret();
++
++#endif
--- /dev/null
- // ==========================
- // Turret Config Generator
- // ==========================
++#ifndef TURRETS_CONFIG_H
++#define TURRETS_CONFIG_H
++
++#ifdef SVQC
+
+void Dump_Turret_Settings(void);
+float tur_config_file;
+float tur_config_alsoprint;
+
+#define MAX_TUR_CONFIG 256
+float TUR_CONFIG_COUNT;
+string tur_config_queue[MAX_TUR_CONFIG];
+
+#define TUR_CONFIG_QUEUE(a) { \
+ tur_config_queue[TUR_CONFIG_COUNT] = a; \
+ ++TUR_CONFIG_COUNT; }
+
+#define TUR_CONFIG_WRITETOFILE(a) { \
+ fputs(tur_config_file, a); \
+ if(tur_config_alsoprint) { print(a); } }
+
+#define TUR_CONFIG_WRITE_CVARS(turret,name) \
+ { TUR_CONFIG_QUEUE( \
+ sprintf("set g_turrets_unit_%s_%s %g\n", #turret, #name, \
+ cvar(sprintf("g_turrets_unit_%s_%s", #turret, #name)))) } \
+
+#define TUR_CONFIG_SETTINGS(tursettings) \
+ #define TUR_ADD_CVAR(turret,name) TUR_CONFIG_WRITE_CVARS(turret,name) \
+ tursettings \
+ #undef TUR_ADD_CVAR
++
++#endif
++
++#endif
--- /dev/null
- // =========================
- // SVQC Turret Properties
- // =========================
-
++#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_respawn;
+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_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce)
+{
- // Enougth allready!
++ // 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;
++ 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();
+}
+
+void turret_projectile_damage(entity inflictor, entity attacker, float damage, float 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_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_target.vehicle_flags & VHF_ISVEHICLE)
+ {
+ 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);
++ 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 (e.turret_flags & TUR_FLAG_ISTURRET)
+ {
+ 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;
++ return false;
+
+ entity e;
+ entity tur = get_turretinfo(tur_id);
+ if(tur.turretid == 0)
- return FALSE; // invalid turret
++ 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.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))
- return FALSE;
++ return false;
+
- return TRUE;
++ 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!
+
+/// 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
- entity get_turretinfo(float id);
++#ifndef TURRETS_H
++#define TURRETS_H
++
+// turret requests
+#define TR_SETUP 1 // (BOTH) setup turret data
+#define TR_THINK 2 // (SERVER) logic to run every frame
+#define TR_DEATH 3 // (SERVER) called when turret dies
+#define TR_PRECACHE 4 // (BOTH) precaches models/sounds used by this turret
+#define TR_ATTACK 5 // (SERVER) called when turret attacks
+#define TR_CONFIG 6 // (ALL)
+
+// functions:
- .float target_select_flags;
- .float target_validate_flags;
- const float TFL_TARGETSELECT_NO = 2; // don't automatically find targets
- const float TFL_TARGETSELECT_LOS = 4; // require line of sight to find targets
- const float TFL_TARGETSELECT_PLAYERS = 8; // target players
- const float TFL_TARGETSELECT_MISSILES = 16; // target projectiles
- const float TFL_TARGETSELECT_TRIGGERTARGET = 32; // respond to turret_trigger_target events
- const float TFL_TARGETSELECT_ANGLELIMITS = 64; // apply extra angular limits to target selection
- const float TFL_TARGETSELECT_RANGELIMITS = 128; // limit target selection range
- const float TFL_TARGETSELECT_TEAMCHECK = 256; // don't attack teammates
- const float TFL_TARGETSELECT_NOBUILTIN = 512; // only attack targets when triggered
- const float TFL_TARGETSELECT_OWNTEAM = 1024; // only attack teammates
- const float TFL_TARGETSELECT_NOTURRETS = 2048; // don't attack other turrets
- const float TFL_TARGETSELECT_FOV = 4096; // extra limits to attack range
- const float TFL_TARGETSELECT_MISSILESONLY = 8192; // only attack missiles
++entity get_turretinfo(int id);
+
+// fields:
+.entity tur_head;
+
+// target selection flags
- .float aim_flags;
- const float TFL_AIM_NO = 1; // no aiming
- const float TFL_AIM_SPLASH = 2; // aim for ground around the target's feet
- const float TFL_AIM_LEAD = 4; // try to predict target movement
- const float TFL_AIM_SHOTTIMECOMPENSATE = 8; // compensate for shot traveltime when leading
- const float TFL_AIM_ZPREDICT = 16; // predict target's z position at impact
- const float TFL_AIM_SIMPLE = 32; // aim at player's current location
++.int target_select_flags;
++.int target_validate_flags;
++const int TFL_TARGETSELECT_NO = 2; // don't automatically find targets
++const int TFL_TARGETSELECT_LOS = 4; // require line of sight to find targets
++const int TFL_TARGETSELECT_PLAYERS = 8; // target players
++const int TFL_TARGETSELECT_MISSILES = 16; // target projectiles
++const int TFL_TARGETSELECT_TRIGGERTARGET = 32; // respond to turret_trigger_target events
++const int TFL_TARGETSELECT_ANGLELIMITS = 64; // apply extra angular limits to target selection
++const int TFL_TARGETSELECT_RANGELIMITS = 128; // limit target selection range
++const int TFL_TARGETSELECT_TEAMCHECK = 256; // don't attack teammates
++const int TFL_TARGETSELECT_NOBUILTIN = 512; // only attack targets when triggered
++const int TFL_TARGETSELECT_OWNTEAM = 1024; // only attack teammates
++const int TFL_TARGETSELECT_NOTURRETS = 2048; // don't attack other turrets
++const int TFL_TARGETSELECT_FOV = 4096; // extra limits to attack range
++const int TFL_TARGETSELECT_MISSILESONLY = 8192; // only attack missiles
+
+// aim flags
- .float track_flags;
- const float TFL_TRACK_NO = 2; // don't move head
- const float TFL_TRACK_PITCH = 4; // pitch head
- const float TFL_TRACK_ROTATE = 8; // rotate head
++.int aim_flags;
++const int TFL_AIM_NO = 1; // no aiming
++const int TFL_AIM_SPLASH = 2; // aim for ground around the target's feet
++const int TFL_AIM_LEAD = 4; // try to predict target movement
++const int TFL_AIM_SHOTTIMECOMPENSATE = 8; // compensate for shot traveltime when leading
++const int TFL_AIM_ZPREDICT = 16; // predict target's z position at impact
++const int TFL_AIM_SIMPLE = 32; // aim at player's current location
+
+// tracking flags
- .float firecheck_flags;
- const float TFL_FIRECHECK_DEAD = 4; // don't attack dead targets (zombies?)
- const float TFL_FIRECHECK_DISTANCES = 8; // another range check
- const float TFL_FIRECHECK_LOS = 16; // line of sight
- const float TFL_FIRECHECK_AIMDIST = 32; // consider distance impactpoint<->aimspot
- const float TFL_FIRECHECK_REALDIST = 64; // consider enemy origin<->impactpoint
- const float TFL_FIRECHECK_ANGLEDIST = 128; // consider angular diff head<->aimspot
- const float TFL_FIRECHECK_TEAMCHECK = 256; // don't attack teammates
- const float TFL_FIRECHECK_AFF = 512; // try to avoid any friendly fire
- const float TFL_FIRECHECK_AMMO_OWN = 1024; // own ammo needs to be larger than damage dealt
- const float TFL_FIRECHECK_AMMO_OTHER = 2048; // target's ammo needs to be less than max
- const float TFL_FIRECHECK_REFIRE = 4096; // check single attack finished delays
- const float TFL_FIRECHECK_NO = 16384; // no prefire checks
++.int track_flags;
++const int TFL_TRACK_NO = 2; // don't move head
++const int TFL_TRACK_PITCH = 4; // pitch head
++const int TFL_TRACK_ROTATE = 8; // rotate head
+
+// prefire checks
- .float shoot_flags;
- const float TFL_SHOOT_NO = 64; // no attacking
- const float TFL_SHOOT_VOLLY = 2; // fire in vollies
- const float TFL_SHOOT_VOLLYALWAYS = 4; // always do a full volly, even if target is lost
- const float TFL_SHOOT_HITALLVALID = 8; // loop through all valid targets
- const float TFL_SHOOT_CLEARTARGET = 16; // lose target after attack (after volly is done if in volly mode)
- const float TFL_SHOOT_CUSTOM = 32; // custom attacking
++.int firecheck_flags;
++const int TFL_FIRECHECK_DEAD = 4; // don't attack dead targets (zombies?)
++const int TFL_FIRECHECK_DISTANCES = 8; // another range check
++const int TFL_FIRECHECK_LOS = 16; // line of sight
++const int TFL_FIRECHECK_AIMDIST = 32; // consider distance impactpoint<->aimspot
++const int TFL_FIRECHECK_REALDIST = 64; // consider enemy origin<->impactpoint
++const int TFL_FIRECHECK_ANGLEDIST = 128; // consider angular diff head<->aimspot
++const int TFL_FIRECHECK_TEAMCHECK = 256; // don't attack teammates
++const int TFL_FIRECHECK_AFF = 512; // try to avoid any friendly fire
++const int TFL_FIRECHECK_AMMO_OWN = 1024; // own ammo needs to be larger than damage dealt
++const int TFL_FIRECHECK_AMMO_OTHER = 2048; // target's ammo needs to be less than max
++const int TFL_FIRECHECK_REFIRE = 4096; // check single attack finished delays
++const int TFL_FIRECHECK_NO = 16384; // no prefire checks
+
+// attack flags
- .float turret_flags;
- const float TUR_FLAG_NONE = 0; // no abilities
- const float TUR_FLAG_SNIPER = 2; // sniping turret
- const float TUR_FLAG_SPLASH = 4; // can deal splash damage
- const float TUR_FLAG_HITSCAN = 8; // hit scan
- const float TUR_FLAG_MULTIGUN = 16; // multiple guns
- const float TUR_FLAG_GUIDED = 32; // laser guided projectiles
- const float TUR_FLAG_SLOWPROJ = 64; // turret fires slow projectiles
- const float TUR_FLAG_MEDPROJ = 128; // turret fires medium projectiles
- const float TUR_FLAG_FASTPROJ = 256; // turret fires fast projectiles
- const float TUR_FLAG_PLAYER = 512; // can damage players
- const float TUR_FLAG_MISSILE = 1024; // can damage missiles
- const float TUR_FLAG_SUPPORT = 2048; // supports other units
- const float TUR_FLAG_AMMOSOURCE = 4096; // can provide ammunition
- const float TUR_FLAG_RECIEVETARGETS = 8192; // can recieve targets from external sources
- const float TUR_FLAG_MOVE = 16384; // can move
- const float TUR_FLAG_ROAM = 32768; // roams around if not attacking
- const float TUR_FLAG_ISTURRET = 65536; // identifies this unit as a turret
++.int shoot_flags;
++const int TFL_SHOOT_NO = 64; // no attacking
++const int TFL_SHOOT_VOLLY = 2; // fire in vollies
++const int TFL_SHOOT_VOLLYALWAYS = 4; // always do a full volly, even if target is lost
++const int TFL_SHOOT_HITALLVALID = 8; // loop through all valid targets
++const int TFL_SHOOT_CLEARTARGET = 16; // lose target after attack (after volly is done if in volly mode)
++const int TFL_SHOOT_CUSTOM = 32; // custom attacking
+
+// turret capabilities
- const float TFL_AMMO_NONE = 64; // doesn't use ammo
- const float TFL_AMMO_ENERGY = 2; // uses power
- const float TFL_AMMO_BULLETS = 4; // uses bullets
- const float TFL_AMMO_ROCKETS = 8; // uses explosives
- const float TFL_AMMO_RECHARGE = 16; // regenerates ammo
- const float TFL_AMMO_RECIEVE = 32; // can recieve ammo from support units
++.int turret_flags;
++const int TUR_FLAG_NONE = 0; // no abilities
++const int TUR_FLAG_SNIPER = 2; // sniping turret
++const int TUR_FLAG_SPLASH = 4; // can deal splash damage
++const int TUR_FLAG_HITSCAN = 8; // hit scan
++const int TUR_FLAG_MULTIGUN = 16; // multiple guns
++const int TUR_FLAG_GUIDED = 32; // laser guided projectiles
++const int TUR_FLAG_SLOWPROJ = 64; // turret fires slow projectiles
++const int TUR_FLAG_MEDPROJ = 128; // turret fires medium projectiles
++const int TUR_FLAG_FASTPROJ = 256; // turret fires fast projectiles
++const int TUR_FLAG_PLAYER = 512; // can damage players
++const int TUR_FLAG_MISSILE = 1024; // can damage missiles
++const int TUR_FLAG_SUPPORT = 2048; // supports other units
++const int TUR_FLAG_AMMOSOURCE = 4096; // can provide ammunition
++const int TUR_FLAG_RECIEVETARGETS = 8192; // can recieve targets from external sources
++const int TUR_FLAG_MOVE = 16384; // can move
++const int TUR_FLAG_ROAM = 32768; // roams around if not attacking
++const int TUR_FLAG_ISTURRET = 65536; // identifies this unit as a turret
+
+// ammo types
+#define ammo_flags currentammo
- .float damage_flags;
- const float TFL_DMG_NO = 256; // doesn't take damage
- const float TFL_DMG_YES = 2; // can be damaged
- const float TFL_DMG_TEAM = 4; // can be damaged by teammates
- const float TFL_DMG_RETALIATE = 8; // target attackers
- const float TFL_DMG_RETALIATE_TEAM = 16; // target attackers, even if on same team
- const float TFL_DMG_TARGETLOSS = 32; // loses target when damaged
- const float TFL_DMG_AIMSHAKE = 64; // damage throws off aim
- const float TFL_DMG_HEADSHAKE = 128; // damage shakes head
- const float TFL_DMG_DEATH_NORESPAWN = 256; // no re-spawning
++const int TFL_AMMO_NONE = 64; // doesn't use ammo
++const int TFL_AMMO_ENERGY = 2; // uses power
++const int TFL_AMMO_BULLETS = 4; // uses bullets
++const int TFL_AMMO_ROCKETS = 8; // uses explosives
++const int TFL_AMMO_RECHARGE = 16; // regenerates ammo
++const int TFL_AMMO_RECIEVE = 32; // can recieve ammo from support units
+
+// damage flags
- const float TSF_SUSPENDED = 1;
- const float TSF_TERRAINBASE = 2; // currently unused
- const float TSF_NO_AMMO_REGEN = 4; // disable builtin ammo regeneration
- const float TSF_NO_PATHBREAK = 8; // don't break path to chase enemies, will still fire at them if possible
- const float TSL_NO_RESPAWN = 16; // don't re-spawn
- const float TSL_ROAM = 32; // roam while idle
++.int damage_flags;
++const int TFL_DMG_NO = 256; // doesn't take damage
++const int TFL_DMG_YES = 2; // can be damaged
++const int TFL_DMG_TEAM = 4; // can be damaged by teammates
++const int TFL_DMG_RETALIATE = 8; // target attackers
++const int TFL_DMG_RETALIATE_TEAM = 16; // target attackers, even if on same team
++const int TFL_DMG_TARGETLOSS = 32; // loses target when damaged
++const int TFL_DMG_AIMSHAKE = 64; // damage throws off aim
++const int TFL_DMG_HEADSHAKE = 128; // damage shakes head
++const int TFL_DMG_DEATH_NORESPAWN = 256; // no re-spawning
+
+// spawn flags
- const float TNSF_UPDATE = 2;
- const float TNSF_STATUS = 4;
- const float TNSF_SETUP = 8;
- const float TNSF_ANG = 16;
- const float TNSF_AVEL = 32;
- const float TNSF_MOVE = 64;
++const int TSF_SUSPENDED = 1;
++const int TSF_TERRAINBASE = 2; // currently unused
++const int TSF_NO_AMMO_REGEN = 4; // disable builtin ammo regeneration
++const int TSF_NO_PATHBREAK = 8; // don't break path to chase enemies, will still fire at them if possible
++const int TSL_NO_RESPAWN = 16; // don't re-spawn
++const int TSL_ROAM = 32; // roam while idle
+
+// send flags
- const float TNSF_ANIM = 128;
++const int TNSF_UPDATE = 2;
++const int TNSF_STATUS = 4;
++const int TNSF_SETUP = 8;
++const int TNSF_ANG = 16;
++const int TNSF_AVEL = 32;
++const int TNSF_MOVE = 64;
+.float anim_start_time;
- const float TNSF_FULL_UPDATE = 16777215;
++const int TNSF_ANIM = 128;
+
- .float turretid; // TUR_...
++const int TNSF_FULL_UPDATE = 16777215;
+
+
+// entity properties of turretinfo:
++.int turretid; // TUR_...
+.string netname; // short name
+.string turret_name; // human readable name
+.float(float) turret_func; // m_...
+.string mdl; // currently a copy of the model
+.string model; // full name of model
+.string head_model; // full name of tur_head model
+.string cvar_basename; // TODO: deprecate!
+.float spawnflags;
+.vector mins, maxs; // turret hitbox size
+
+// other useful macros
+#define TUR_ACTION(turrettype,mrequest) (get_turretinfo(turrettype)).turret_func(mrequest)
+#define TUR_NAME(turrettype) (get_turretinfo(turrettype)).turret_name
+
+// =====================
+// Turret Registration
+// =====================
+
+float t_null(float dummy);
+void register_turret(float id, float(float) func, float turretflags, vector min_s, vector max_s, string modelname, string headmodelname, string shortname, string mname);
+void register_turrets_done();
+
+const float TUR_MAXCOUNT = 24;
+#define TUR_FIRST 1
+float TUR_COUNT;
+float TUR_LAST;
+
+#define REGISTER_TURRET_2(id,func,turretflags,min_s,max_s,modelname,headmodelname,shortname,mname) \
+ float id; \
+ float func(float); \
+ void RegisterTurrets_##id() \
+ { \
+ TUR_LAST = (id = TUR_FIRST + TUR_COUNT); \
+ ++TUR_COUNT; \
+ register_turret(id,func,turretflags,min_s,max_s,modelname,headmodelname,shortname,mname); \
+ } \
+ ACCUMULATE_FUNCTION(RegisterTurrets, RegisterTurrets_##id)
+#ifdef MENUQC
+#define REGISTER_TURRET(id,func,turretflags,min_s,max_s,modelname,headmodelname,shortname,mname) \
+ REGISTER_TURRET_2(TUR_##id,t_null,turretflags,min_s,max_s,modelname,headmodelname,shortname,mname)
+#else
+#define REGISTER_TURRET(id,func,turretflags,min_s,max_s,modelname,headmodelname,shortname,mname) \
+ REGISTER_TURRET_2(TUR_##id,func,turretflags,min_s,max_s,modelname,headmodelname,shortname,mname)
+#endif
+
+#define TUR_DUPECHECK(dupecheck,cvar) \
+ #ifndef dupecheck \
+ #define dupecheck \
+ float cvar; \
+ #else \
+ #error DUPLICATE TURRET CVAR: cvar \
+ #endif
+
+#define TUR_ADD_CVAR(turret,name) \
+ TUR_DUPECHECK(TUR_CVAR_##turret##_##name, autocvar_g_turrets_unit_##turret##_##name)
+
+#define TUR_CVAR(turret,name) autocvar_g_turrets_unit_##turret##_##name
+
+#include "all.qh"
+
+#undef TUR_ADD_CVAR
+#undef REGISTER_TURRET
+ACCUMULATE_FUNCTION(RegisterTurrets, register_turrets_done);
++
++#endif
--- /dev/null
- turrets_setframe(newframe, FALSE);
+#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
+ // 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 (vlen(self.origin - self.pathcurrent.origin) < 64)
+ self.pathcurrent = self.pathcurrent.enemy;
+#endif
+
+ if (self.pathcurrent)
+ {
+
+ self.moveto = self.pathcurrent.origin;
+ self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
+
+ movelib_move_simple(v_forward, (autocvar_g_turrets_unit_ewheel_speed_fast), 0.4);
+ }
+}
+
+void ewheel_move_enemy()
+{
+ 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));
+ }
+
- return TRUE;
++ turrets_setframe(newframe, false);
+}
+
+void ewheel_move_idle()
+{
+ 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)
+{
+ 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;
++ 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;
++ return true;
+ }
+ case TR_DEATH:
+ {
+ self.velocity = '0 0 0';
+
+#ifdef EWHEEL_FANCYPATH
+ if (self.pathcurrent)
+ pathlib_deletepath(self.pathcurrent.owner);
+#endif
+ self.pathcurrent = world;
+
- self.iscreature = TRUE;
++ 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 = WALKER_PATH(self.origin,e.origin);
+ self.pathgoal = e;
+#else
+ self.pathcurrent = e;
+#endif
+ }
+ }
+ }
+
- self.damagedbycontents = TRUE;
++ self.iscreature = true;
+ self.teleportable = TELEPORT_NORMAL;
- return TRUE;
++ 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;
++ return true;
+ }
+ case TR_PRECACHE:
+ {
+ precache_model ("models/turrets/ewheel-base2.md3");
+ precache_model ("models/turrets/ewheel-gun1.md3");
- return TRUE;
++ return true;
+ }
+ }
+
- return TRUE;
++ return true;
+}
+
+#endif // SVQC
+#ifdef CSQC
+
+void ewheel_draw()
+{
+ float dt;
+
+ dt = time - self.move_time;
+ self.move_time = time;
+ if(dt <= 0)
+ return;
+
+ 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;
+
+ 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;
++ return true;
+ }
+ case TR_PRECACHE:
+ {
- return TRUE;
++ return true;
+ }
+ }
+
++ return true;
+}
+
+#endif // CSQC
+#endif // REGISTER_TURRET
--- /dev/null
- return TRUE;
+#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()
+{
+ 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
+ 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
+ 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
+ remove(self);
+}
+
+void spawnfunc_turret_flac() { if(!turret_initialize(TUR_FLAC)) remove(self); }
+
+float t_flac(float req)
+{
+ switch(req)
+ {
+ case TR_ATTACK:
+ {
+ entity proj;
+
+ turret_tag_fire_update();
+
+ 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;
+
+ self.tur_head.frame = self.tur_head.frame + 1;
+ if (self.tur_head.frame >= 4)
+ self.tur_head.frame = 0;
+
- return TRUE;
++ return true;
+ }
+ case TR_THINK:
+ {
- return TRUE;
++ return true;
+ }
+ case TR_DEATH:
+ {
- return TRUE;
++ 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;
++ return true;
+ }
+ case TR_PRECACHE:
+ {
+ precache_model ("models/turrets/base.md3");
+ precache_model ("models/turrets/flac.md3");
- return TRUE;
++ return true;
+ }
+ }
+
- return TRUE;
++ return true;
+}
+
+#endif // SVQC
+#ifdef CSQC
+float t_flac(float req)
+{
+ switch(req)
+ {
+ case TR_SETUP:
+ {
- return TRUE;
++ return true;
+ }
+ case TR_PRECACHE:
+ {
- return TRUE;
++ return true;
+ }
+ }
+
++ return true;
+}
+
+#endif // CSQC
+#endif // REGISTER_TURRET
--- /dev/null
- return TRUE;
+#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.attack_finished_single > time)
+ return 0;
+
+ if (self.enemy.deadflag != DEAD_NO)
+ return 0;
+
+ if (self.enemy == world)
+ return 0;
+
+ if (self.ammo < self.shot_dmg)
+ return 0;
+
+ if (self.enemy.ammo >= self.enemy.ammo_max)
+ return 0;
+
+ if (vlen(self.enemy.origin - self.origin) > self.target_range)
+ return 0;
+
+ if(self.team != self.enemy.team)
+ return 0;
+
+ if(!(self.enemy.ammo_flags & TFL_AMMO_ENERGY))
+ return 0;
+
+ return 1;
+}
+
+void spawnfunc_turret_fusionreactor() { if(!turret_initialize(TUR_FUSIONREACTOR)) remove(self); }
+
+float t_fusionreactor(float req)
+{
+ 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;
++ return true;
+ }
+ case TR_THINK:
+ {
+ self.tur_head.avelocity = '0 250 0' * (self.ammo / self.ammo_max);
+
- return TRUE;
++ return true;
+ }
+ case TR_DEATH:
+ {
- return TRUE;
++ 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;
++ return true;
+ }
+ case TR_PRECACHE:
+ {
+ precache_model ("models/turrets/base.md3");
+ precache_model ("models/turrets/reactor.md3");
- return TRUE;
++ return true;
+ }
+ }
+
- return TRUE;
++ return true;
+}
+
+#endif // SVQC
+#ifdef CSQC
+float t_fusionreactor(float req)
+{
+ switch(req)
+ {
+ case TR_SETUP:
+ {
- return TRUE;
++ return true;
+ }
+ case TR_PRECACHE:
+ {
- return TRUE;
++ return true;
+ }
+ }
+
++ return true;
+}
+
+#endif // CSQC
+#endif // REGISTER_TURRET
--- /dev/null
- return TRUE;
+#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()
+{
+ vector olddir,newdir;
+ vector pre_pos;
+ float itime;
+
+ self.nextthink = time + 0.05;
+
+ olddir = normalize(self.velocity);
+
+ if(self.max_health < time)
+ turret_projectile_explode();
+
+ // Enemy dead? just keep on the current heading then.
+ if ((self.enemy == world) || (self.enemy.deadflag != DEAD_NO))
+ {
+
+ // Make sure we dont return to tracking a respawned player
+ self.enemy = world;
+
+ // Turn model
+ self.angles = vectoangles(self.velocity);
+
+ if ( (vlen(self.origin - self.owner.origin)) > (self.owner.shot_radius * 5) )
+ turret_projectile_explode();
+
+ // Accelerate
+ self.velocity = olddir * min(vlen(self.velocity) * (autocvar_g_turrets_unit_hellion_shot_speed_gain), (autocvar_g_turrets_unit_hellion_shot_speed_max));
+
+ UpdateCSQCProjectile(self);
+
+ return;
+ }
+
+ // Enemy in range?
+ if (vlen(self.origin - self.enemy.origin) < self.owner.shot_radius * 0.2)
+ turret_projectile_explode();
+
+ // Predict enemy position
+ itime = vlen(self.enemy.origin - self.origin) / vlen(self.velocity);
+ pre_pos = self.enemy.origin + self.enemy.velocity * itime;
+
+ pre_pos = (pre_pos + self.enemy.origin) * 0.5;
+
+ // Find out the direction to that place
+ newdir = normalize(pre_pos - self.origin);
+
+ // Turn
+ newdir = normalize(olddir + newdir * 0.35);
+
+ // Turn model
+ self.angles = vectoangles(self.velocity);
+
+ // Accelerate
+ self.velocity = newdir * min(vlen(self.velocity) * (autocvar_g_turrets_unit_hellion_shot_speed_gain), (autocvar_g_turrets_unit_hellion_shot_speed_max));
+
+ if (itime < 0.05)
+ self.think = turret_projectile_explode;
+
+ UpdateCSQCProjectile(self);
+}
+
+void spawnfunc_turret_hellion() { if(!turret_initialize(TUR_HELLION)) remove(self); }
+
+float t_hellion(float req)
+{
+ 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;
++ 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;
++ return true;
+ }
+ case TR_DEATH:
+ {
- return TRUE;
++ 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;
++ return true;
+ }
+ case TR_PRECACHE:
+ {
+ precache_model ("models/turrets/base.md3");
+ precache_model ("models/turrets/hellion.md3");
- return TRUE;
++ return true;
+ }
+ }
+
- return TRUE;
++ return true;
+}
+
+#endif // SVQC
+#ifdef CSQC
+float t_hellion(float req)
+{
+ switch(req)
+ {
+ case TR_SETUP:
+ {
- return TRUE;
++ return true;
+ }
+ case TR_PRECACHE:
+ {
- return TRUE;
++ return true;
+ }
+ }
+
++ return true;
+}
+
+#endif // CSQC
+#endif // REGISTER_TURRET
--- /dev/null
- traceline(self.origin, pre_pos,TRUE,self.enemy);
+#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 (e_target == world)
+ return 0;
+
+ // If only this was used more..
+ if (e_target.flags & FL_NOTARGET)
+ return 0;
+
+ // Cant touch this
+ if ((e_target.takedamage == DAMAGE_NO) || (e_target.health < 0))
+ return 0;
+
+ // player
+ if (IS_CLIENT(e_target))
+ {
+ if (self.owner.target_select_playerbias < 0)
+ return 0;
+
+ if (e_target.deadflag != DEAD_NO)
+ return 0;
+ }
+
+ // Missile
+ if ((e_target.flags & FL_PROJECTILE) && (self.owner.target_select_missilebias < 0))
+ return 0;
+
+ // Team check
+ if ((e_target.team == self.owner.team) || (self.owner.team == e_target.owner.team))
+ return 0;
+
+ return 1;
+}
+
+void turret_hk_missile_think()
+{
+ 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, self.origin + v_forward * lt_for,FALSE,self);
++ 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 + (-1 * (v_right * pt_seek) + (v_forward * ff)) * lt_seek,FALSE,self);
++ 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 + ((v_right * pt_seek) + (v_forward * ff)) * lt_seek ,FALSE,self);
++ 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_up * pt_seek) + (v_forward * ff)) * lt_seek ,FALSE,self);
++ 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 + (-1 * (v_up * pt_seek) + (v_forward * ff)) * lt_seek ,FALSE,self);
++ traceline(self.origin, self.origin + ((v_up * pt_seek) + (v_forward * ff)) * lt_seek ,false,self);
+ vu = trace_endpos;
+ fu = trace_fraction;
+
+ // Trace down
- return TRUE;
++ 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
+ //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
+
+ UpdateCSQCProjectile(self);
+}
+
+float turret_hk_addtarget(entity e_target,entity e_sender)
+{
+ 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_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;
++ 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;
++ return true;
+ }
+ case TR_DEATH:
+ {
- return TRUE;
++ 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;
++ return true;
+ }
+ case TR_PRECACHE:
+ {
+ precache_model ("models/turrets/base.md3");
+ precache_model ("models/turrets/hk.md3");
- return TRUE;
++ return true;
+ }
+ }
+
- return TRUE;
++ return true;
+}
+
+#endif // SVQC
+#ifdef CSQC
+float t_hk(float req)
+{
+ switch(req)
+ {
+ case TR_SETUP:
+ {
- return TRUE;
++ return true;
+ }
+ case TR_PRECACHE:
+ {
- return TRUE;
++ return true;
+ }
+ }
+
++ return true;
+}
+
+#endif // CSQC
+#endif // REGISTER_TURRET
--- /dev/null
- return TRUE;
+#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); }
+
+float t_machinegun(float req)
+{
+ 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);
+
+ W_MachineGun_MuzzleFlash();
+ setattachment(self.muzzle_flash, self.tur_head, "tag_fire");
+
- return TRUE;
++ return true;
+ }
+ case TR_THINK:
+ {
- return TRUE;
++ return true;
+ }
+ case TR_DEATH:
+ {
- return TRUE;
++ 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;
++ return true;
+ }
+ }
+
- return TRUE;
++ return true;
+}
+
+#endif // SVQC
+#ifdef CSQC
+float t_machinegun(float req)
+{
+ switch(req)
+ {
+ case TR_SETUP:
+ {
- return TRUE;
++ return true;
+ }
+ case TR_PRECACHE:
+ {
- return TRUE;
++ return true;
+ }
+ }
+
++ return true;
+}
+
+#endif // CSQC
+#endif // REGISTER_TURRET
--- /dev/null
- return TRUE;
+#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)
+{
+ switch(req)
+ {
+ case TR_ATTACK:
+ {
+ entity missile;
+
+ 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;
++ 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;
++ 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;
+
- return TRUE;
++ return true;
+ }
+ case TR_PRECACHE:
+ {
+ precache_model ("models/turrets/base.md3");
+ precache_model ("models/turrets/mlrs.md3");
- return TRUE;
++ return true;
+ }
+ }
+
- return TRUE;
++ return true;
+}
+
+#endif // SVQC
+#ifdef CSQC
+float t_mlrs(float req)
+{
+ switch(req)
+ {
+ case TR_SETUP:
+ {
- return TRUE;
++ return true;
+ }
+ case TR_PRECACHE:
+ {
- return TRUE;
++ return true;
+ }
+ }
+
++ return true;
+}
+
+#endif // CSQC
+#endif // REGISTER_TURRET
--- /dev/null
- beam.bot_dodge = TRUE;
+#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 (self.fireflag != 0) return 0;
+ return turret_firecheck();
+}
+
+void beam_think()
+{
+ 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_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;
- return TRUE;
++ 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;
++ 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;
++ return true;
+ }
+ case TR_DEATH:
+ {
- return TRUE;
++ 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;
++ 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;
+ }
+ }
+
- return TRUE;
++ return true;
+}
+
+#endif // SVQC
+#ifdef CSQC
+float t_phaser(float req)
+{
+ switch(req)
+ {
+ case TR_SETUP:
+ {
- return TRUE;
++ return true;
+ }
+ case TR_PRECACHE:
+ {
- return TRUE;
++ return true;
+ }
+ }
+
++ return true;
+}
+
+#endif // CSQC
+#endif // REGISTER_TURRET
--- /dev/null
- 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_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;
++ 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;
++ return true;
+ }
+ case TR_DEATH:
+ {
- return TRUE;
++ 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;
++ return true;
+ }
+ case TR_PRECACHE:
+ {
+ precache_model ("models/turrets/base.md3");
+ precache_model ("models/turrets/plasma.md3");
- return TRUE;
++ return true;
+ }
+ }
+
- return TRUE;
++ return true;
+}
+
+#endif // SVQC
+#ifdef CSQC
+float t_plasma(float req)
+{
+ switch(req)
+ {
+ case TR_SETUP:
+ {
- return TRUE;
++ return true;
+ }
+ case TR_PRECACHE:
+ {
- return TRUE;
++ return true;
+ }
+ }
+
++ return true;
+}
+
+#endif // CSQC
+#endif // REGISTER_TURRET
--- /dev/null
- 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_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;
++ 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;
++ return true;
+ }
+ case TR_DEATH:
+ {
- return TRUE;
++ 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;
++ return true;
+ }
+ case TR_PRECACHE:
+ {
+ precache_model ("models/turrets/base.md3");
+ precache_model ("models/turrets/plasmad.md3");
- return TRUE;
++ return true;
+ }
+ }
+
- return TRUE;
++ return true;
+}
+
+#endif // SVQC
+#ifdef CSQC
+float t_plasma_dual(float req)
+{
+ switch(req)
+ {
+ case TR_SETUP:
+ {
- return TRUE;
++ return true;
+ }
+ case TR_PRECACHE:
+ {
- return TRUE;
++ return true;
+ }
+ }
+
++ return true;
+}
+
+#endif // CSQC
+#endif // REGISTER_TURRET
--- /dev/null
- if (t == world) return TRUE;
+#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)
+{
+ 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()
+{
+ // 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_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);
+
- return TRUE;
++ 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;
++ return true;
+ }
+ case TR_THINK:
+ {
+ if(!self.active)
+ {
+ self.tur_head.avelocity = '0 0 0';
- return TRUE;
++ 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;
++ 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;
++ return true;
+ }
+ case TR_DEATH:
+ {
- return TRUE;
++ 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;
++ return true;
+ }
+ case TR_PRECACHE:
+ {
+ precache_model ("models/turrets/tesla_base.md3");
+ precache_model ("models/turrets/tesla_head.md3");
- return TRUE;
++ return true;
+ }
+ }
+
- return TRUE;
++ return true;
+}
+
+#endif // SVQC
+#ifdef CSQC
+float t_tesla(float req)
+{
+ switch(req)
+ {
+ case TR_SETUP:
+ {
- return TRUE;
++ return true;
+ }
+ case TR_PRECACHE:
+ {
- return TRUE;
++ return true;
+ }
+ }
+
++ return true;
+}
+
+#endif // CSQC
+#endif // REGISTER_TURRET
--- /dev/null
- turrets_setframe(ANIM_NO, FALSE);
+#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()
+{
+ if (self.animflag == ANIM_MELEE)
+ return 0;
+
+ return turret_firecheck();
+}
+
+void walker_melee_do_dmg()
+{
+ vector where;
+ entity e;
+
+ makevectors(self.angles);
+ where = self.origin + v_forward * 128;
+
+ 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));
+
+ e = e.chain;
+ }
+}
+
+void walker_setnoanim()
+{
- rocket.bot_dodge = TRUE;
++ turrets_setframe(ANIM_NO, false);
+ self.animflag = self.frame;
+}
+void walker_rocket_explode()
+{
+ 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)
+{
+ self.health = self.health - damage;
+ self.velocity = self.velocity + vforce;
+
+ 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;
+ 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()
+{
+ vector newdir;
+ self.nextthink = time;
+
+ if (self.max_health < time)
+ {
+ self.think = walker_rocket_explode;
+ return;
+ }
+
+ if (vlen(self.origin - self.tur_shotorg) < 100 )
+ {
+ self.think = walker_rocket_think;
+ return;
+ }
+
+ newdir = steerlib_pull(self.tur_shotorg);
+ WALKER_ROCKET_MOVE;
+
+ self.angles = vectoangles(self.velocity);
+}
+
+void walker_rocket_loop2()
+{
+ vector newdir;
+
+ self.nextthink = time;
+
+ if (self.max_health < time)
+ {
+ self.think = walker_rocket_explode;
+ return;
+ }
+
+ if (vlen(self.origin - self.tur_shotorg) < 100 )
+ {
+ self.tur_shotorg = self.origin - '0 0 200';
+ self.think = walker_rocket_loop3;
+ return;
+ }
+
+ newdir = steerlib_pull(self.tur_shotorg);
+ WALKER_ROCKET_MOVE;
+}
+
+void walker_rocket_loop()
+{
+ 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)
+{
+ 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;
- CSQCProjectile(rocket, FALSE, PROJECTILE_ROCKET, FALSE); // no culling, has fly sound
++ 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;
+
- return TRUE;
++ 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)
+{
+ 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
+ // 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 (vlen(self.origin - self.pathcurrent.origin) < 64)
+ self.pathcurrent = self.pathcurrent.enemy;
+
+ if(!self.pathcurrent)
+ return;
+
+ 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)
+{
+ 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);
+
- turrets_setframe(self.animflag, FALSE);
++ 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;
- return TRUE;
++ turrets_setframe(self.animflag, false);
+
- return TRUE;
++ return true;
+ }
+ case TR_DEATH:
+ {
+#ifdef WALKER_FANCYPATHING
+ if (self.pathcurrent)
+ pathlib_deletepath(self.pathcurrent.owner);
+#endif
+ self.pathcurrent = world;
+
- self.iscreature = TRUE;
++ 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.damagedbycontents = TRUE;
++ self.iscreature = true;
+ self.teleportable = TELEPORT_NORMAL;
- return TRUE;
++ 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 = WALKER_PATH(self.origin, e.origin);
+ self.pathgoal = e;
+#else
+ self.pathcurrent = e;
+#endif
+ }
+ }
+
- return TRUE;
++ 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;
+ }
+ }
+
- return TRUE;
++ return true;
+}
+
+#endif // SVQC
+#ifdef CSQC
+
++#include "../../../server/movelib.qh"
++
+void walker_draw()
+{
+ 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;
++ return true;
+ }
+ case TR_PRECACHE:
+ {
- return TRUE;
++ return true;
+ }
+ }
+
++ return true;
+}
+
+#endif // CSQC
+#endif // REGISTER_TURRET
--- /dev/null
- #define turret_tag_fire_update() self.tur_shotorg = gettaginfo(self.tur_head, gettagindex(self.tur_head, "tag_fire"));v_forward = normalize(v_forward)
- float turret_tag_fire_update_s()
+/*
+* 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.
+*/
- return FALSE;
++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 TRUE;
++ return false;
+ }
+
+ self.tur_shotorg = gettaginfo(self.tur_head, gettagindex(self.tur_head, "tag_fire"));
+ v_forward = normalize(v_forward);
+
- tracebox(start, smin, smax, end, FALSE, self);
++ 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, float 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)
+ {
- trace_ent.railgunhit = TRUE;
++ 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
- ent = findfloat(world, railgunhit, TRUE);
++ 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(ent, railgunhit, TRUE);
++ ent = findfloat(world, railgunhit, true);
+ while (ent)
+ {
+ // restore their solid type
+ ent.solid = ent.railgunhitsolidbackup;
- ent = findfloat(world, railgunhit, TRUE);
++ ent = findfloat(ent, railgunhit, true);
+ }
+
+ // find all the entities the railgun hit and hurt them
- ent.railgunhit = FALSE;
++ 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 = findfloat(ent, railgunhit, TRUE);
++ 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
--- /dev/null
++#ifndef TURRETS_UTIL_H
++#define TURRETS_UTIL_H
++
++vector real_origin(entity ent);
++float shortangle_f(float ang1, float ang2);
++float anglemods(float v);
++float turret_tag_fire_update();
++vector shortangle_vxy(vector ang1, vector ang2);
++vector angleofs(entity from, entity to);
++vector angleofs3(vector from, vector from_a, entity to);
++void FireImoBeam (vector start, vector end, vector smin, vector smax, float bforce, float f_dmg, float f_velfactor, float deathtype);
++
++#endif
- float autocvar__notarget;
- float autocvar__independent_players;
- float autocvar__campaign_testrun;
- float autocvar__campaign_index;
+ #ifndef SERVER_AUTOCVARS_H
+ #define SERVER_AUTOCVARS_H
+
+ bool autocvar__notarget;
+ bool autocvar__independent_players;
+ bool autocvar__campaign_testrun;
+ int autocvar__campaign_index;
string autocvar__campaign_name;
- float autocvar__sv_init;
+ bool autocvar__sv_init;
float autocvar_bot_ai_aimskill_blendrate;
float autocvar_bot_ai_aimskill_firetolerance_distdegrees;
float autocvar_bot_ai_aimskill_firetolerance_maxdegrees;
float autocvar_bot_ai_navigation_jetpack_mindistance;
float autocvar_bot_ai_strategyinterval;
float autocvar_bot_ai_thinkinterval;
- float autocvar_bot_ai_weapon_combo;
+ bool autocvar_bot_ai_weapon_combo;
float autocvar_bot_ai_weapon_combo_threshold;
string autocvar_bot_config_file;
- float autocvar_bot_god;
- float autocvar_bot_ignore_bots;
- float autocvar_bot_join_empty;
- float autocvar_bot_navigation_ignoreplayers;
- float autocvar_bot_nofire;
+ bool autocvar_bot_god;
+ bool autocvar_bot_ignore_bots;
+ bool autocvar_bot_join_empty;
+ bool autocvar_bot_navigation_ignoreplayers;
+ bool autocvar_bot_nofire;
#define autocvar_bot_number cvar("bot_number")
#define autocvar_bot_prefix cvar_string("bot_prefix")
- float autocvar_bot_sound_monopoly;
+ bool autocvar_bot_sound_monopoly;
#define autocvar_bot_suffix cvar_string("bot_suffix")
- float autocvar_bot_usemodelnames;
- float autocvar_bot_vs_human;
- float autocvar_bot_debug;
- float autocvar_bot_debug_tracewalk;
- float autocvar_bot_debug_goalstack;
- float autocvar_bot_wander_enable;
- float autocvar_captureleadlimit_override;
+ bool autocvar_bot_usemodelnames;
+ int autocvar_bot_vs_human;
+ int autocvar_bot_debug;
+ bool autocvar_bot_debug_tracewalk;
+ bool autocvar_bot_debug_goalstack;
+ bool autocvar_bot_wander_enable;
+ int autocvar_captureleadlimit_override;
#define autocvar_capturelimit_override cvar("capturelimit_override")
#define autocvar_developer cvar("developer")
float autocvar_ekg;
#define autocvar_fraglimit cvar("fraglimit")
#define autocvar_fraglimit_override cvar("fraglimit_override")
- float autocvar_g_allow_oldvortexbeam;
- float autocvar_g_antilag;
+ bool autocvar_g_allow_oldvortexbeam;
+ int autocvar_g_antilag;
float autocvar_g_antilag_nudge;
float autocvar_g_balance_armor_blockpercent;
- float autocvar_g_balance_armor_limit;
+ int autocvar_g_balance_armor_limit;
float autocvar_g_balance_armor_regen;
- float autocvar_g_balance_armor_regenlinear;
- float autocvar_g_balance_armor_regenstable;
+ float autocvar_g_balance_armor_regenlinear; // TODO: int/bool?
+ int autocvar_g_balance_armor_regenstable;
float autocvar_g_balance_armor_rot;
float autocvar_g_balance_armor_rotlinear;
- float autocvar_g_balance_armor_rotstable;
- float autocvar_g_balance_armor_start;
+ int autocvar_g_balance_armor_rotstable;
+ int autocvar_g_balance_armor_start;
float autocvar_g_balance_cloaked_alpha;
float autocvar_g_balance_contents_damagerate;
float autocvar_g_balance_contents_drowndelay;
- float autocvar_g_balance_contents_playerdamage_drowning;
- float autocvar_g_balance_contents_playerdamage_lava;
- float autocvar_g_balance_contents_playerdamage_slime;
- float autocvar_g_balance_contents_projectiledamage;
+ int autocvar_g_balance_contents_playerdamage_drowning;
+ int autocvar_g_balance_contents_playerdamage_lava;
+ int autocvar_g_balance_contents_playerdamage_slime;
+ int autocvar_g_balance_contents_projectiledamage;
float autocvar_g_balance_damagepush_speedfactor;
float autocvar_g_balance_falldamage_deadminspeed;
float autocvar_g_balance_falldamage_factor;
- float autocvar_g_balance_falldamage_maxdamage;
+ int autocvar_g_balance_falldamage_maxdamage;
float autocvar_g_balance_falldamage_minspeed;
- float autocvar_g_balance_firetransfer_damage;
- float autocvar_g_balance_firetransfer_time;
+ int autocvar_g_balance_firetransfer_damage;
+ int autocvar_g_balance_firetransfer_time;
float autocvar_g_balance_fuel_limit;
float autocvar_g_balance_fuel_regen;
float autocvar_g_balance_fuel_regenlinear;
- float autocvar_g_balance_fuel_regenstable;
+ int autocvar_g_balance_fuel_regenstable;
float autocvar_g_balance_fuel_rot;
float autocvar_g_balance_fuel_rotlinear;
- float autocvar_g_balance_fuel_rotstable;
+ int autocvar_g_balance_fuel_rotstable;
float autocvar_g_balance_grapplehook_airfriction;
float autocvar_g_balance_grapplehook_force_rubber;
float autocvar_g_balance_grapplehook_force_rubber_overstretch;
#define autocvar_g_mirrordamage cvar("g_mirrordamage")
#define autocvar_g_mirrordamage_virtual cvar("g_mirrordamage_virtual")
- var float autocvar_g_movement_highspeed = 1;
+ float autocvar_g_movement_highspeed = 1;
float autocvar_g_multijump;
float autocvar_g_multijump_add;
float autocvar_g_multijump_speed;
float autocvar_g_turrets_reloadcvars;
float autocvar_g_turrets_targetscan_maxdelay;
float autocvar_g_turrets_targetscan_mindelay;
-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;
float autocvar_g_use_ammunition;
float autocvar_g_waypointeditor;
float autocvar_g_waypointeditor_auto;
float autocvar_spawn_debug;
float autocvar_speedmeter;
float autocvar_sv_accelerate;
- var float autocvar_sv_accuracy_data_share = 1;
+ float autocvar_sv_accuracy_data_share = 1;
string autocvar_sv_adminnick;
float autocvar_sv_airaccel_qw;
float autocvar_sv_airaccel_qw_stretchfactor;
float autocvar_g_random_gravity_negative;
float autocvar_g_random_gravity_delay;
float 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;
float autocvar_g_nades_nade_radius;
float autocvar_g_nades_nade_force;
float autocvar_g_nades_nade_newton_style;
- float autocvar_g_nades_napalm_ball_count;
+ 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_buffs_invisible_alpha;
float autocvar_g_buffs_flight_gravity;
float autocvar_g_buffs_jump_height;
-
+ #endif
- .float dmg;
- .float dmg_edge;
- .float dmg_force;
- .float dmg_radius;
+ #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 "tturrets/include/turrets_early.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)
{
WriteByte(MSG_ENTITY, ENT_CLIENT_DAMAGEINFO);
WriteShort(MSG_ENTITY, self.projectiledeathtype);
- WriteCoord(MSG_ENTITY, floor(self.origin_x));
- WriteCoord(MSG_ENTITY, floor(self.origin_y));
- WriteCoord(MSG_ENTITY, floor(self.origin_z));
+ WriteCoord(MSG_ENTITY, floor(self.origin.x));
+ WriteCoord(MSG_ENTITY, floor(self.origin.y));
+ WriteCoord(MSG_ENTITY, floor(self.origin.z));
WriteByte(MSG_ENTITY, bound(1, self.dmg, 255));
WriteByte(MSG_ENTITY, bound(0, self.dmg_radius, 255));
WriteByte(MSG_ENTITY, bound(1, self.dmg_edge, 255));
- WriteShort(MSG_ENTITY, self.oldorigin_x);
+ WriteShort(MSG_ENTITY, self.oldorigin.x);
WriteByte(MSG_ENTITY, self.species);
- return TRUE;
+ return true;
}
void Damage_DamageInfo(vector org, float coredamage, float edgedamage, float rad, vector force, float deathtype, float bloodtype, entity dmgowner)
e.oldorigin_x = compressShortVector(e.velocity);
e.species = bloodtype;
- Net_LinkEntity(e, FALSE, 0.2, Damage_DamageInfo_SendEntity);
+ Net_LinkEntity(e, false, 0.2, Damage_DamageInfo_SendEntity);
}
- float checkrules_firstblood;
-
- float yoda;
- float damage_goodhits;
- float damage_gooddamage;
-
- .float dmg_team;
- .float teamkill_complain;
- .float teamkill_soundtime;
- .entity teamkill_soundsource;
- .entity pusher;
- .float istypefrag;
- .float taunt_soundtime;
-
float IsFlying(entity a)
{
if(a.flags & FL_ONGROUND)
PlayerTeamScore_AddScore(player, f);
}
- // 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)
{
// TODO route through PlayerScores instead
else { backtrace("Obituary_SpecialDeath called without a special deathtype?\n"); return; }
}
- float w_deathtype;
float Obituary_WeaponDeath(
entity notif_target,
float murder,
{
w_deathtype = deathtype;
float death_message = WEP_ACTION(death_weapon, ((murder) ? WR_KILLMESSAGE : WR_SUICIDEMESSAGE));
- w_deathtype = FALSE;
+ w_deathtype = false;
if(death_message)
{
);
}
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
void Obituary(entity attacker, entity inflictor, entity targ, float deathtype)
if (!IS_PLAYER(targ)) { backtrace("Obituary called on non-player?!\n"); return; }
// Declarations
- float notif_firstblood = FALSE;
+ float notif_firstblood = false;
float kill_count_to_attacker, kill_count_to_target;
// Set final information for the death
{
if(deathtype == DEATH_TEAMCHANGE || deathtype == DEATH_AUTOTEAMCHANGE)
{
- Obituary_SpecialDeath(targ, FALSE, deathtype, targ.netname, deathlocation, "", targ.team, 0, 0);
+ Obituary_SpecialDeath(targ, false, deathtype, targ.netname, deathlocation, "", targ.team, 0, 0);
}
else
{
{
case DEATH_MIRRORDAMAGE:
{
- Obituary_SpecialDeath(targ, FALSE, deathtype, targ.netname, deathlocation, "", targ.killcount, 0, 0);
+ Obituary_SpecialDeath(targ, false, deathtype, targ.netname, deathlocation, "", targ.killcount, 0, 0);
break;
}
default:
{
- Obituary_SpecialDeath(targ, FALSE, deathtype, targ.netname, deathlocation, "", targ.killcount, 0, 0);
+ Obituary_SpecialDeath(targ, false, deathtype, targ.netname, deathlocation, "", targ.killcount, 0, 0);
break;
}
}
}
}
- else if (!Obituary_WeaponDeath(targ, FALSE, deathtype, targ.netname, deathlocation, "", targ.killcount, 0))
+ else if (!Obituary_WeaponDeath(targ, false, deathtype, targ.netname, deathlocation, "", targ.killcount, 0))
{
backtrace("SUICIDE: what the hell happened here?\n");
return;
if(!checkrules_firstblood)
{
- checkrules_firstblood = TRUE;
- notif_firstblood = TRUE; // modify the current messages so that they too show firstblood information
+ checkrules_firstblood = true;
+ notif_firstblood = true; // modify the current messages so that they too show firstblood information
PS_GR_P_ADDVAL(attacker, PLAYERSTATS_ACHIEVEMENT_FIRSTBLOOD, 1);
PS_GR_P_ADDVAL(targ, PLAYERSTATS_ACHIEVEMENT_FIRSTVICTIM, 1);
);
}
- 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);
+ 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);
}
}
case DEATH_CUSTOM:
{
- Obituary_SpecialDeath(targ, FALSE, deathtype,
+ Obituary_SpecialDeath(targ, false, deathtype,
targ.netname,
((strstrofs(deathmessage, "%", 0) < 0) ? strcat("%s ", deathmessage) : deathmessage),
deathlocation,
default:
{
- Obituary_SpecialDeath(targ, FALSE, deathtype, targ.netname, deathlocation, "", targ.killcount, 0, 0);
+ Obituary_SpecialDeath(targ, false, deathtype, targ.netname, deathlocation, "", targ.killcount, 0, 0);
break;
}
}
RemoveGrapplingHook(head);
// add waypoint
- if(show_waypoint)
- WaypointSprite_Spawn("frozen", 0, 0, targ, '0 0 64', world, targ.team, targ, waypointsprite_attached, TRUE, RADARICON_WAYPOINT, '0.25 0.90 1');
+ if(show_waypoint)
+ WaypointSprite_Spawn("frozen", 0, 0, targ, '0 0 64', world, targ.team, targ, waypointsprite_attached, true, RADARICON_WAYPOINT, '0.25 0.90 1');
}
void Unfreeze (entity targ)
targ.frozen = 0;
targ.revive_progress = 0;
targ.revival_time = time;
-
+
WaypointSprite_Kill(targ.waypointsprite_attached);
-
+
FOR_EACH_PLAYER(head)
if(head.hook.aiment == targ)
RemoveGrapplingHook(head);
targ.iceblock = world;
}
- // these are updated by each Damage call for use in button triggering and such
- entity damage_targ;
- entity damage_inflictor;
- entity damage_attacker;
-
void Damage (entity targ, entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
{
float mirrordamage;
if(autocvar_g_mirrordamage_virtual)
{
vector v = healtharmor_applydamage(attacker.armorvalue, autocvar_g_balance_armor_blockpercent, deathtype, mirrordamage);
- attacker.dmg_take += v_x;
- attacker.dmg_save += v_y;
+ attacker.dmg_take += v.x;
+ attacker.dmg_save += v.y;
attacker.dmg_inflictor = inflictor;
- mirrordamage = v_z;
+ mirrordamage = v.z;
mirrorforce = 0;
}
if(autocvar_g_friendlyfire_virtual)
{
vector v = healtharmor_applydamage(targ.armorvalue, autocvar_g_balance_armor_blockpercent, deathtype, damage);
- targ.dmg_take += v_x;
- targ.dmg_save += v_y;
+ targ.dmg_take += v.x;
+ targ.dmg_save += v.y;
targ.dmg_inflictor = inflictor;
damage = 0;
if(!autocvar_g_friendlyfire_virtual_force)
damage = 0;
force *= autocvar_g_freezetag_frozen_force;
}
-
+
if(targ.frozen && deathtype == DEATH_HURTTRIGGER && !autocvar_g_freezetag_frozen_damage_trigger)
{
pointparticles(particleeffectnum("teleport"), targ.origin, '0 0 0', 1);
-
+
entity oldself = self;
self = targ;
- entity spot = SelectSpawnPoint (FALSE);
-
+ entity spot = SelectSpawnPoint (false);
+
if(spot)
{
damage = 0;
self.deadflag = DEAD_NO;
self.angles = spot.angles;
-
+
self.effects = 0;
self.effects |= EF_TELEPORT_BIT;
self.angles_z = 0; // never spawn tilted even if the spot says to
- self.fixangle = TRUE; // turn this way immediately
+ self.fixangle = true; // turn this way immediately
self.velocity = '0 0 0';
self.avelocity = '0 0 0';
self.punchangle = '0 0 0';
self.punchvector = '0 0 0';
self.oldvelocity = self.velocity;
-
+
self.spawnorigin = spot.origin;
- setorigin (self, spot.origin + '0 0 1' * (1 - self.mins_z - 24));
+ setorigin (self, spot.origin + '0 0 1' * (1 - self.mins.z - 24));
// don't reset back to last position, even if new position is stuck in solid
self.oldorigin = self.origin;
self.prevorigin = self.origin;
-
+
pointparticles(particleeffectnum("teleport"), self.origin, '0 0 0', 1);
}
-
+
self = oldself;
}
else
victim = targ;
- if(IS_PLAYER(victim) || (victim.turrcaps_flags & TFL_TURRCAPS_ISTURRET) || (victim.flags & FL_MONSTER))
+ if(IS_PLAYER(victim) || ((victim.turret_flags & TUR_FLAG_ISTURRET) && victim.active == ACTIVE_ACTIVE) || (victim.flags & FL_MONSTER))
{
if(DIFF_TEAM(victim, attacker) && !victim.frozen)
{
}
}
- 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)
// Returns total damage applies to creatures
{
stat_damagedone = 0;
- targ = WarpZone_FindRadius (inflictororigin, rad + MAX_DAMAGEEXTRARADIUS, FALSE);
+ targ = WarpZone_FindRadius (inflictororigin, rad + MAX_DAMAGEEXTRARADIUS, false);
while (targ)
{
next = targ.chain;
else
hitloc = nearest;
}
- nearest_x = targ.origin_x + targ.mins_x + random() * targ.size_x;
- nearest_y = targ.origin_y + targ.mins_y + random() * targ.size_y;
- nearest_z = targ.origin_z + targ.mins_z + random() * targ.size_z;
+ nearest.x = targ.origin.x + targ.mins.x + random() * targ.size.x;
+ nearest.y = targ.origin.y + targ.mins.y + random() * targ.size.y;
+ nearest.z = targ.origin.z + targ.mins.z + random() * targ.size.z;
}
nearest = hitloc * (1 / max(1, hits));
float RadiusDamage (entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float forceintensity, float 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);
+ return RadiusDamageForSource (inflictor, (inflictor.origin + (inflictor.mins + inflictor.maxs) * 0.5), inflictor.velocity, attacker, coredamage, edgedamage, rad, cantbe, mustbe, false, forceintensity, deathtype, directhitentity);
}
- .float fire_damagepersec;
- .float fire_endtime;
- .float fire_deathtype;
- .entity fire_owner;
- .float fire_hitsound;
- .entity fire_burner;
-
- void fireburner_think();
-
float Fire_IsBurning(entity e)
{
return (time < e.fire_endtime);
if(e.fire_owner != o)
{
e.fire_owner = o;
- e.fire_hitsound = FALSE;
+ e.fire_hitsound = false;
}
}
if(accuracy_isgooddamage(o, e))
e.fire_endtime = time + t;
e.fire_deathtype = dt;
e.fire_owner = o;
- e.fire_hitsound = FALSE;
+ e.fire_hitsound = false;
if(accuracy_isgooddamage(o, e))
accuracy_add(o, DEATH_WEAPONOFWEAPONDEATH(dt), 0, d);
return d;
e.fire_owner.damage_dealt = hi;
e.fire_owner.typehitsound = ty;
}
- e.fire_hitsound = TRUE;
+ e.fire_hitsound = true;
if (!IS_INDEPENDENT_PLAYER(e))
if(!e.frozen)
--- /dev/null
- #include "tturrets/include/turrets_early.qh"
+ #ifndef G_DAMAGE_H
+ #define G_DAMAGE_H
+
+ #if defined(CSQC)
+ #elif defined(MENUQC)
+ #elif defined(SVQC)
+ #include "../dpdefs/progsdefs.qh"
+ #include "../dpdefs/dpextensions.qh"
+ #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 "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 dmg;
+ .float dmg_edge;
+ .float dmg_force;
+ .float dmg_radius;
+
+ float Damage_DamageInfo_SendEntity(entity to, float sf);
+
+ void Damage_DamageInfo(vector org, float coredamage, float edgedamage, float rad, vector force, float deathtype, float bloodtype, entity dmgowner);
+
+ float checkrules_firstblood;
+
+ float yoda;
+ float damage_goodhits;
+ float damage_gooddamage;
+
+ .float dmg_team;
+ .float teamkill_complain;
+ .float teamkill_soundtime;
+ .entity teamkill_soundsource;
+ .entity pusher;
+ .float istypefrag;
+ .float taunt_soundtime;
+
+ float IsFlying(entity a);
+
+ void UpdateFrags(entity player, float f);
+
+ // 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);
+
+ string AppendItemcodes(string s, entity player);
+
+ void LogDeath(string mode, float deathtype, entity killer, entity killed);
+
+ void Obituary_SpecialDeath(
+ entity notif_target,
+ float murder,
+ float deathtype,
+ string s1, string s2, string s3,
+ float f1, float f2, float f3);
+
+ float w_deathtype;
+ float Obituary_WeaponDeath(
+ entity notif_target,
+ float murder,
+ float deathtype,
+ string s1, string s2, string s3,
+ float f1, float f2);
+
+ void Obituary(entity attacker, entity inflictor, entity targ, float deathtype);
+
+ void Ice_Think();
+
+ void Freeze (entity targ, float freeze_time, float frozen_type, float show_waypoint);
+
+ void Unfreeze (entity targ);
+
+ // these are updated by each Damage call for use in button triggering and such
+ entity damage_targ;
+ entity damage_inflictor;
+ entity damage_attacker;
+
+ void Damage (entity targ, entity inflictor, entity attacker, float damage, float 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);
+ // 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 fire_damagepersec;
+ .float fire_endtime;
+ .float fire_deathtype;
+ .entity fire_owner;
+ .float fire_hitsound;
+ .entity fire_burner;
+
+ void fireburner_think();
+
+ float Fire_IsBurning(entity e);
+
+ float Fire_AddDamage(entity e, entity o, float d, float t, float dt);
+
+ void Fire_ApplyDamage(entity e);
+
+ void Fire_ApplyEffect(entity e);
+
+ void fireburner_think();
+ #endif
- #define LATENCY_THINKRATE 10
+ #include "g_world.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
+
+ const float LATENCY_THINKRATE = 10;
.float latency_sum;
.float latency_cnt;
.float latency_time;
buf_cvarlist(h, "", "_"); // exclude all _ cvars as they are temporary
n = buf_getsize(h);
- adding = TRUE;
- pureadding = TRUE;
+ adding = true;
+ pureadding = true;
for(i = 0; i < n; ++i)
{
// does nothing visible
BADCVAR("captureleadlimit_override");
BADCVAR("g_balance_kill_delay");
+ BADCVAR("g_ca_point_limit");
BADCVAR("g_ca_point_leadlimit");
BADCVAR("g_ctf_captimerecord_always");
BADCVAR("g_ctf_flag_glowtrails");
BADCVAR("g_ctf_flag_pickup_verbosename");
BADCVAR("g_domination_point_leadlimit");
BADCVAR("g_forced_respawn");
+ BADCVAR("g_freezetag_point_limit");
+ BADCVAR("g_freezetag_point_leadlimit");
BADCVAR("g_keyhunt_point_leadlimit");
BADPREFIX("g_mod_");
+ BADCVAR("g_invasion_point_limit");
BADCVAR("g_nexball_goalleadlimit");
+ BADCVAR("g_tdm_point_limit");
+ BADCVAR("g_tdm_point_leadlimit");
BADCVAR("leadlimit_and_fraglimit");
BADCVAR("leadlimit_override");
BADCVAR("pausable");
vector o, v;
float i;
- for(;;)
+ for (;;)
{
o = world.mins;
- o_x += random() * (world.maxs_x - world.mins_x);
- o_y += random() * (world.maxs_y - world.mins_y);
- o_z += random() * (world.maxs_z - world.mins_z);
+ o.x += random() * (world.maxs.x - world.mins.x);
+ o.y += random() * (world.maxs.y - world.mins.y);
+ o.z += random() * (world.maxs.z - world.mins.z);
tracebox(o, PL_MIN, PL_MAX, o - '0 0 32768', MOVE_WORLDONLY, world);
if(trace_fraction == 1)
{
WriteByte(MSG_ENTITY, ENT_CLIENT_RANDOMSEED);
WriteShort(MSG_ENTITY, self.cnt);
- return TRUE;
+ return true;
}
void RandomSeed_Think()
{
{
randomseed = spawn();
randomseed.think = RandomSeed_Think;
- Net_LinkEntity(randomseed, FALSE, 0, RandomSeed_Send);
+ Net_LinkEntity(randomseed, false, 0, RandomSeed_Send);
entity oldself;
oldself = self;
// needs to be done so early because of the constants they create
CALL_ACCUMULATED_FUNCTION(RegisterWeapons);
+ CALL_ACCUMULATED_FUNCTION(RegisterTurrets);
CALL_ACCUMULATED_FUNCTION(RegisterMonsters);
CALL_ACCUMULATED_FUNCTION(RegisterGametypes);
CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
if(world_already_spawned)
error("world already spawned - you may have EXACTLY ONE worldspawn!");
- world_already_spawned = TRUE;
+ world_already_spawned = true;
remove = remove_safely; // during spawning, watch what you remove!
head = nextent(head);
}
- server_is_dedicated = (stof(cvar_defstring("is_dedicated")) ? TRUE : FALSE);
+ 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);
+ CALL_ACCUMULATED_FUNCTION(RegisterTurrets);
CALL_ACCUMULATED_FUNCTION(RegisterMonsters);
CALL_ACCUMULATED_FUNCTION(RegisterGametypes);
CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
// 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", ftos(autocvar_sv_eventlog_files_counter), strftime(false, "%s"), floor(random() * 1000000));
matchid = strzone(s);
GameLogEcho(strcat(":gamestart:", GetGametype(), "_", GetMapname(), ":", s));
addstat(STAT_VORTEX_CHARGEPOOL, AS_FLOAT, vortex_chargepool_ammo);
addstat(STAT_HAGAR_LOAD, AS_INT, hagar_load);
-
+
addstat(STAT_ARC_HEAT, AS_FLOAT, arc_heat_percent);
// freeze attacks
if(substring(argv(i), -18, -1) != "-serverpackage.txt")
if(substring(argv(i), -14, -1) != ".serverpackage") // OLD legacy
s = strcat(s, " ", argv(i));
- fd = search_begin("*-serverpackage.txt", TRUE, FALSE);
+ fd = search_begin("*-serverpackage.txt", true, false);
if(fd >= 0)
{
j = search_getsize(fd);
s = strcat(s, " ", search_getfilename(fd, i));
search_end(fd);
}
- fd = search_begin("*.serverpackage", TRUE, FALSE);
+ fd = search_begin("*.serverpackage", true, false);
if(fd >= 0)
{
j = search_getsize(fd);
if(!fexists(strcat("maps/", map, ".waypoints")))
{
dprint(": no waypoints\n");
- return FALSE;
+ return false;
}
dprint(": has waypoints\n");
}
if(player_count < mapmin)
{
dprint("not enough\n");
- return FALSE;
+ return false;
}
if(player_count > mapmax)
{
dprint("too many\n");
- return FALSE;
+ return false;
}
dprint("right size\n");
- return TRUE;
+ return true;
}
dprint(": not found\n");
- return TRUE;
+ return true;
}
string Map_Filename(float position)
if(autocvar_g_campaign)
{
CampaignPostIntermission();
- alreadychangedlevel = TRUE;
- return TRUE;
+ alreadychangedlevel = true;
+ return true;
}
if(autocvar_quit_when_empty)
{
if(player_count <= currentbots)
{
localcmd("quit\n");
- alreadychangedlevel = TRUE;
- return TRUE;
+ alreadychangedlevel = true;
+ return true;
}
}
if(autocvar_quit_and_redirect != "")
{
redirection_target = strzone(autocvar_quit_and_redirect);
- alreadychangedlevel = TRUE;
- return TRUE;
+ alreadychangedlevel = true;
+ return true;
}
if (!reinit && autocvar_samelevel) // if samelevel is set, stay on same level
{
localcmd("restart\n");
- alreadychangedlevel = TRUE;
- return TRUE;
+ alreadychangedlevel = true;
+ return true;
}
if(autocvar_nextmap != "")
{
string m;
m = GameTypeVote_MapInfo_FixName(autocvar_nextmap);
cvar_set("nextmap",m);
-
+
if(!m || gametypevote)
- return FALSE;
+ return false;
if(autocvar_sv_vote_gametype)
{
Map_Goto_SetStr(m);
- return FALSE;
+ return false;
}
-
+
if(MapInfo_CheckMap(m))
{
Map_Goto_SetStr(m);
Map_Goto(reinit);
- alreadychangedlevel = TRUE;
- return TRUE;
+ alreadychangedlevel = true;
+ return true;
}
}
if(!reinit && autocvar_lastlevel)
{
cvar_settemp_restore();
localcmd("set lastlevel 0\ntogglemenu 1\n");
- alreadychangedlevel = TRUE;
- return TRUE;
+ alreadychangedlevel = true;
+ return true;
}
- return FALSE;
+ return false;
}
void GotoNextMap(float reinit)
//string s;
if (alreadychangedlevel)
return;
- alreadychangedlevel = TRUE;
+ alreadychangedlevel = true;
string nextMap;
&& ((self.autoscreenshot > 0) && (time > self.autoscreenshot)) )
{
self.autoscreenshot = -1;
- if(IS_REAL_CLIENT(self)) { stuffcmd(self, sprintf("\nscreenshot screenshots/autoscreenshot/%s-%s.jpg; echo \"^5A screenshot has been taken at request of the server.\"\n", GetMapname(), strftime(FALSE, "%s"))); }
+ if(IS_REAL_CLIENT(self)) { stuffcmd(self, sprintf("\nscreenshot screenshots/autoscreenshot/%s-%s.jpg; echo \"^5A screenshot has been taken at request of the server.\"\n", GetMapname(), strftime(false, "%s"))); }
return;
}
if(!final)
{
- to_console = TRUE; // always print printstats replies
- to_eventlog = FALSE; // but never print them to the event log
+ to_console = true; // always print printstats replies
+ to_eventlog = false; // but never print them to the event log
}
if(to_eventlog)
if(autocvar_sv_eventlog_console)
- to_console = FALSE; // otherwise we get the output twice
+ to_console = false; // otherwise we get the output twice
if(final)
s = ":scores:";
{
file = fopen(autocvar_sv_logscores_filename, FILE_APPEND);
if(file == -1)
- to_file = FALSE;
+ to_file = false;
else
fputs(file, strcat(s, "\n"));
}
*/
void NextLevel()
{
- gameover = TRUE;
+ gameover = true;
intermission_running = 1;
VoteReset();
- DumpStats(TRUE);
+ DumpStats(true);
// send statistics
- PlayerStats_GameReport(TRUE);
+ PlayerStats_GameReport(true);
WeaponStats_Shutdown();
Kill_Notification(NOTIF_ALL, world, MSG_CENTER, 0); // kill all centerprints now
// (div0: and that in CheckRules_World please)
}
- float checkrules_equality;
- float checkrules_suddendeathwarning;
- float checkrules_suddendeathend;
- float checkrules_overtimesadded; //how many overtimes have been already added
-
- const float WINNING_NO = 0; // no winner, but time limits may terminate the game
- const float WINNING_YES = 1; // winner found
- const float WINNING_NEVER = 2; // no winner, enter overtime if time limit is reached
- const float WINNING_STARTSUDDENDEATHOVERTIME = 3; // no winner, enter suddendeath overtime NOW
float InitiateSuddenDeath()
{
float have_players;
float l;
- have_player = FALSE;
- have_players = FALSE;
+ have_player = false;
+ have_players = false;
l = LMS_NewPlayerLives();
head = find(world, classname, "player");
if(head)
- have_player = TRUE;
+ have_player = true;
head2 = find(head, classname, "player");
if(head2)
- have_players = TRUE;
+ have_players = true;
if(have_player)
{
ClearWinners();
if(WinningConditionHelper_winner)
- WinningConditionHelper_winner.winning = TRUE;
+ WinningConditionHelper_winner.winning = true;
if(WinningConditionHelper_topscore == WinningConditionHelper_secondscore)
return WINNING_NEVER;
}
}
- limitreached = FALSE;
+ limitreached = false;
if(limit)
if(WinningConditionHelper_topscore >= limit)
- limitreached = TRUE;
+ limitreached = true;
if(leadlimit)
{
float leadlimitreached;
ClearWinners();
if(team1_score + team2_score + team3_score + team4_score == 0)
{
- checkrules_equality = TRUE;
+ checkrules_equality = true;
return WINNING_YES;
}
else if(team1_score + team2_score + team3_score + team4_score == 1)
{
if(!checkrules_suddendeathwarning)
{
- checkrules_suddendeathwarning = TRUE;
+ checkrules_suddendeathwarning = true;
if(g_race && !g_race_qualifying)
Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_RACE_FINISHLAP);
else
// needed!
FOR_EACH_CLIENT(self)
{
- self.typehitsound = FALSE;
+ self.typehitsound = false;
self.damage_dealt = 0;
antilag_record(self, altime);
}
/*
* RedirectionThink:
- * returns TRUE if redirecting
+ * returns true if redirecting
*/
float redirection_timeout;
float redirection_nextthink;
float clients_found;
if(redirection_target == "")
- return FALSE;
+ return false;
if(!redirection_timeout)
{
}
if(time < redirection_nextthink)
- return TRUE;
+ return true;
redirection_nextthink = time + 1;
if(time > redirection_timeout || clients_found == 0)
localcmd("\nwait; wait; wait; quit\n");
- return TRUE;
+ return true;
}
void TargetMusic_RestoreGame();
Ban_SaveBans();
// playerstats with unfinished match
- PlayerStats_GameReport(FALSE);
+ PlayerStats_GameReport(false);
if(!cheatcount_total)
{
- var void remove(entity e);
- void objerror(string s);
- void droptofloor();
- .vector dropped_origin;
+ #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 "tturrets/include/turrets_early.qh"
+ #include "../common/mapinfo.qh"
+ #include "command/common.qh"
+ #include "../csqcmodellib/sv_model.qh"
+ #include "ipban.qh"
+ #endif
- void traceline_antilag (entity source, vector v1, vector v2, float nomonst, entity forent, float lag);
void crosshair_trace(entity pl)
{
traceline_antilag(pl, pl.cursor_trace_start, pl.cursor_trace_start + normalize(pl.cursor_trace_endpos - pl.cursor_trace_start) * MAX_SHOT_DISTANCE, MOVE_NORMAL, pl, ANTILAG_LATENCY(pl));
for (e = first; e; e = e.chain)
e.solid = SOLID_TRIGGER;
}
- void WarpZone_traceline_antilag (entity source, vector v1, vector v2, float nomonst, entity forent, float lag);
void WarpZone_crosshair_trace(entity pl)
{
WarpZone_traceline_antilag(pl, pl.cursor_trace_start, pl.cursor_trace_start + normalize(pl.cursor_trace_endpos - pl.cursor_trace_start) * MAX_SHOT_DISTANCE, MOVE_NORMAL, pl, ANTILAG_LATENCY(pl));
}
- void() spawnfunc_info_player_deathmatch; // needed for the other spawnpoints
- void() spawnpoint_use;
- string GetMapname();
string admin_name(void)
{
return "SERVER ADMIN";
}
- float DistributeEvenly_amount;
- float DistributeEvenly_totalweight;
void DistributeEvenly_Init(float amount, float totalweight)
{
if (DistributeEvenly_amount)
return f;
}
- #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_PLAYER(v) (v.classname == STR_PLAYER)
- #define IS_SPEC(v) (v.classname == STR_SPECTATOR)
- #define IS_OBSERVER(v) (v.classname == STR_OBSERVER)
- #define IS_CLIENT(v) (v.flags & FL_CLIENT)
- #define IS_BOT_CLIENT(v) (clienttype(v) == CLIENTTYPE_BOT)
- #define IS_REAL_CLIENT(v) (clienttype(v) == CLIENTTYPE_REAL)
- #define IS_NOT_A_CLIENT(v) (clienttype(v) == CLIENTTYPE_NOTACLIENT)
-
- #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))
-
- #define FOR_EACH_PLAYER(v) FOR_EACH_CLIENT(v) if(IS_PLAYER(v))
- #define FOR_EACH_SPEC(v) FOR_EACH_CLIENT(v) if (!IS_PLAYER(v)) // Samual: shouldn't this be IS_SPEC(v)? and rather create a separate macro to include observers too
- #define FOR_EACH_REALPLAYER(v) FOR_EACH_REALCLIENT(v) if(IS_PLAYER(v))
-
- #define FOR_EACH_MONSTER(v) for(v = world; (v = findflags(v, flags, FL_MONSTER)) != world; )
-
- #define CENTER_OR_VIEWOFS(ent) (ent.origin + (IS_PLAYER(ent) ? ent.view_ofs : ((ent.mins + ent.maxs) * 0.5)))
-
- // copies a string to a tempstring (so one can strunzone it)
- string strcat1(string s) = #115; // FRIK_FILE
-
- float logfile_open;
- float logfile;
void GameLogEcho(string s)
{
{
if (!logfile_open)
{
- logfile_open = TRUE;
+ logfile_open = true;
matches = autocvar_sv_eventlog_files_counter + 1;
cvar_set("sv_eventlog_files_counter", ftos(matches));
fn = ftos(matches);
if (logfile >= 0)
{
if (autocvar_sv_eventlog_files_timestamps)
- fputs(logfile, strcat(":time:", strftime(TRUE, "%Y-%m-%d %H:%M:%S", "\n", s, "\n")));
+ fputs(logfile, strcat(":time:", strftime(true, "%Y-%m-%d %H:%M:%S", "\n", s, "\n")));
else
fputs(logfile, strcat(s, "\n"));
}
}
}
- #define strstr strstrofs
- /*
- // NOTE: DO NOT USE THIS FUNCTION TOO OFTEN.
- // IT WILL MOST PROBABLY DESTROY _ALL_ OTHER TEMP
- // STRINGS AND TAKE QUITE LONG. haystack and needle MUST
- // BE CONSTANT OR strzoneD!
- float strstr(string haystack, string needle, float offset)
- {
- float len, endpos;
- string found;
- len = strlen(needle);
- endpos = strlen(haystack) - len;
- while(offset <= endpos)
- {
- found = substring(haystack, offset, len);
- if(found == needle)
- return offset;
- offset = offset + 1;
- }
- return -1;
- }
- */
-
- const float NUM_NEAREST_ENTITIES = 4;
- entity nearest_entity[NUM_NEAREST_ENTITIES];
- float nearest_length[NUM_NEAREST_ENTITIES];
entity findnearest(vector point, .string field, string value, vector axismod)
{
entity localhead;
else
dist = localhead.origin;
dist = dist - point;
- dist = dist_x * axismod_x * '1 0 0' + dist_y * axismod_y * '0 1 0' + dist_z * axismod_z * '0 0 1';
+ dist = dist.x * axismod.x * '1 0 0' + dist.y * axismod.y * '0 1 0' + dist.z * axismod.z * '0 0 1';
len = vlen(dist);
for (i = 0; i < num_nearest; ++i)
// now use the first one from our list that we can see
for (i = 0; i < num_nearest; ++i)
{
- traceline(point, nearest_entity[i].origin, TRUE, world);
+ traceline(point, nearest_entity[i].origin, true, world);
if (trace_fraction == 1)
{
if (i != 0)
if (replacement == "" || !cursor_ent)
replacement = "nothing";
} else if (escape == "s")
- replacement = ftos(vlen(self.velocity - self.velocity_z * '0 0 1'));
+ replacement = ftos(vlen(self.velocity - self.velocity.z * '0 0 1'));
else if (escape == "S")
replacement = ftos(vlen(self.velocity));
return msg;
}
- float boolean(float value) { // if value is 0 return FALSE (0), otherwise return TRUE (1)
- return (value == 0) ? FALSE : TRUE;
+ float boolean(float value) { // if value is 0 return false (0), otherwise return true (1)
+ return (value == 0) ? false : true;
}
/*
{
vector v;
m2 = m2 - m1;
- v_x = m2_x * random() + m1_x;
- v_y = m2_y * random() + m1_y;
- v_z = m2_z * random() + m1_z;
+ v.x = m2_x * random() + m1_x;
+ v.y = m2_y * random() + m1_y;
+ v.z = m2_z * random() + m1_z;
return v;
}
- //#NO AUTOCVARS START
-
- float g_pickup_shells;
- float g_pickup_shells_max;
- float g_pickup_nails;
- float g_pickup_nails_max;
- float g_pickup_rockets;
- float g_pickup_rockets_max;
- float g_pickup_cells;
- float g_pickup_cells_max;
- float g_pickup_plasma;
- float g_pickup_plasma_max;
- float g_pickup_fuel;
- float g_pickup_fuel_jetpack;
- float g_pickup_fuel_max;
- float g_pickup_armorsmall;
- float g_pickup_armorsmall_max;
- float g_pickup_armorsmall_anyway;
- float g_pickup_armormedium;
- float g_pickup_armormedium_max;
- float g_pickup_armormedium_anyway;
- float g_pickup_armorbig;
- float g_pickup_armorbig_max;
- float g_pickup_armorbig_anyway;
- float g_pickup_armorlarge;
- float g_pickup_armorlarge_max;
- float g_pickup_armorlarge_anyway;
- float g_pickup_healthsmall;
- float g_pickup_healthsmall_max;
- float g_pickup_healthsmall_anyway;
- float g_pickup_healthmedium;
- float g_pickup_healthmedium_max;
- float g_pickup_healthmedium_anyway;
- float g_pickup_healthlarge;
- float g_pickup_healthlarge_max;
- float g_pickup_healthlarge_anyway;
- float g_pickup_healthmega;
- float g_pickup_healthmega_max;
- float g_pickup_healthmega_anyway;
- float g_pickup_ammo_anyway;
- float g_pickup_weapons_anyway;
- float g_weaponarena;
- WepSet g_weaponarena_weapons;
- float g_weaponarena_random;
- float g_weaponarena_random_with_blaster;
- string g_weaponarena_list;
- float g_weaponspeedfactor;
- float g_weaponratefactor;
- float g_weapondamagefactor;
- float g_weaponforcefactor;
- float g_weaponspreadfactor;
-
- WepSet start_weapons;
- WepSet start_weapons_default;
- WepSet start_weapons_defaultmask;
- float start_items;
- float start_ammo_shells;
- float start_ammo_nails;
- float start_ammo_rockets;
- float start_ammo_cells;
- float start_ammo_plasma;
- float start_ammo_fuel;
- float start_health;
- float start_armorvalue;
- WepSet warmup_start_weapons;
- WepSet warmup_start_weapons_default;
- WepSet warmup_start_weapons_defaultmask;
- #define WARMUP_START_WEAPONS ((g_warmup_allguns == 1) ? (warmup_start_weapons & (weaponsInMap | start_weapons)) : warmup_start_weapons)
- float warmup_start_ammo_shells;
- float warmup_start_ammo_nails;
- float warmup_start_ammo_rockets;
- float warmup_start_ammo_cells;
- float warmup_start_ammo_plasma;
- float warmup_start_ammo_fuel;
- float warmup_start_health;
- float warmup_start_armorvalue;
- float g_weapon_stay;
-
- float want_weapon(entity weaponinfo, float allguns) // WEAPONTODO: what still needs done?
- {
- var float i = weaponinfo.weapon;
- var float d = 0;
+ float want_weapon(entity weaponinfo, float allguns) // WEAPONTODO: what still needs done?
+ {
+ int i = weaponinfo.weapon;
+ int d = 0;
if (!i)
return 0;
if (g_lms || g_ca || allguns)
{
if(weaponinfo.spawnflags & WEP_FLAG_NORMAL)
- d = TRUE;
+ d = true;
else
- d = FALSE;
+ d = false;
}
else if (g_cts)
d = (i == WEP_SHOTGUN);
if(!g_cts && (weaponinfo.spawnflags & WEP_FLAG_MUTATORBLOCKED)) // never default mutator blocked guns
d = 0;
- var float t = weaponinfo.weaponstartoverride;
+ float t = weaponinfo.weaponstartoverride;
//print(strcat("want_weapon: ", weaponinfo.netname, " - d: ", ftos(d), ", t: ", ftos(t), ". \n"));
for (i = WEP_FIRST; i <= WEP_LAST; ++i)
{
e = get_weaponinfo(i);
- float w = want_weapon(e, FALSE);
+ int w = want_weapon(e, false);
if(w & 1)
start_weapons |= WepSet_FromWeapon(i);
if(w & 2)
for (i = WEP_FIRST; i <= WEP_LAST; ++i)
{
e = get_weaponinfo(i);
- float w = want_weapon(e, g_warmup_allguns);
+ int w = want_weapon(e, g_warmup_allguns);
if(w & 1)
warmup_start_weapons |= WepSet_FromWeapon(i);
if(w & 2)
warmup_start_ammo_fuel = max(0, warmup_start_ammo_fuel);
}
- float g_bugrigs;
- float g_bugrigs_planar_movement;
- float g_bugrigs_planar_movement_car_jumping;
- float g_bugrigs_reverse_spinning;
- float g_bugrigs_reverse_speeding;
- float g_bugrigs_reverse_stopping;
- float g_bugrigs_air_steering;
- float g_bugrigs_angle_smoothing;
- float g_bugrigs_friction_floor;
- float g_bugrigs_friction_brake;
- float g_bugrigs_friction_air;
- float g_bugrigs_accel;
- float g_bugrigs_speed_ref;
- float g_bugrigs_speed_pow;
- float g_bugrigs_steer;
-
- float sv_autotaunt;
- float sv_taunt;
-
- string GetGametype(); // g_world.qc
- void mutators_add(); // mutators.qc
- void readlevelcvars(void)
- {
- // load mutators
- mutators_add();
-
- if(cvar("sv_allow_fullbright"))
- serverflags |= SERVERFLAG_ALLOW_FULLBRIGHT;
-
- g_bugrigs = cvar("g_bugrigs");
- g_bugrigs_planar_movement = cvar("g_bugrigs_planar_movement");
- g_bugrigs_planar_movement_car_jumping = cvar("g_bugrigs_planar_movement_car_jumping");
- g_bugrigs_reverse_spinning = cvar("g_bugrigs_reverse_spinning");
- g_bugrigs_reverse_speeding = cvar("g_bugrigs_reverse_speeding");
- g_bugrigs_reverse_stopping = cvar("g_bugrigs_reverse_stopping");
- g_bugrigs_air_steering = cvar("g_bugrigs_air_steering");
- g_bugrigs_angle_smoothing = cvar("g_bugrigs_angle_smoothing");
- g_bugrigs_friction_floor = cvar("g_bugrigs_friction_floor");
- g_bugrigs_friction_brake = cvar("g_bugrigs_friction_brake");
- g_bugrigs_friction_air = cvar("g_bugrigs_friction_air");
- g_bugrigs_accel = cvar("g_bugrigs_accel");
- g_bugrigs_speed_ref = cvar("g_bugrigs_speed_ref");
- g_bugrigs_speed_pow = cvar("g_bugrigs_speed_pow");
- g_bugrigs_steer = cvar("g_bugrigs_steer");
-
- g_instagib = cvar("g_instagib");
-
- sv_clones = cvar("sv_clones");
- sv_foginterval = cvar("sv_foginterval");
- g_cloaked = cvar("g_cloaked");
- g_footsteps = cvar("g_footsteps");
- g_grappling_hook = cvar("g_grappling_hook");
- g_jetpack = cvar("g_jetpack");
- sv_maxidle = cvar("sv_maxidle");
- sv_maxidle_spectatorsareidle = cvar("sv_maxidle_spectatorsareidle");
- sv_autotaunt = cvar("sv_autotaunt");
- sv_taunt = cvar("sv_taunt");
-
- warmup_stage = cvar("g_warmup");
- g_warmup_limit = cvar("g_warmup_limit");
- g_warmup_allguns = cvar("g_warmup_allguns");
- g_warmup_allow_timeout = cvar("g_warmup_allow_timeout");
-
- if ((g_race && g_race_qualifying == 2) || g_assault || cvar("g_campaign"))
- warmup_stage = 0; // these modes cannot work together, sorry
-
- g_pickup_respawntime_weapon = cvar("g_pickup_respawntime_weapon");
- g_pickup_respawntime_superweapon = cvar("g_pickup_respawntime_superweapon");
- g_pickup_respawntime_ammo = cvar("g_pickup_respawntime_ammo");
- g_pickup_respawntime_short = cvar("g_pickup_respawntime_short");
- g_pickup_respawntime_medium = cvar("g_pickup_respawntime_medium");
- g_pickup_respawntime_long = cvar("g_pickup_respawntime_long");
- g_pickup_respawntime_powerup = cvar("g_pickup_respawntime_powerup");
- g_pickup_respawntimejitter_weapon = cvar("g_pickup_respawntimejitter_weapon");
- g_pickup_respawntimejitter_superweapon = cvar("g_pickup_respawntimejitter_superweapon");
- g_pickup_respawntimejitter_ammo = cvar("g_pickup_respawntimejitter_ammo");
- g_pickup_respawntimejitter_short = cvar("g_pickup_respawntimejitter_short");
- g_pickup_respawntimejitter_medium = cvar("g_pickup_respawntimejitter_medium");
- g_pickup_respawntimejitter_long = cvar("g_pickup_respawntimejitter_long");
- g_pickup_respawntimejitter_powerup = cvar("g_pickup_respawntimejitter_powerup");
-
- g_weaponspeedfactor = cvar("g_weaponspeedfactor");
- g_weaponratefactor = cvar("g_weaponratefactor");
- g_weapondamagefactor = cvar("g_weapondamagefactor");
- g_weaponforcefactor = cvar("g_weaponforcefactor");
- g_weaponspreadfactor = cvar("g_weaponspreadfactor");
-
- g_pickup_shells = cvar("g_pickup_shells");
- g_pickup_shells_max = cvar("g_pickup_shells_max");
- g_pickup_nails = cvar("g_pickup_nails");
- g_pickup_nails_max = cvar("g_pickup_nails_max");
- g_pickup_rockets = cvar("g_pickup_rockets");
- g_pickup_rockets_max = cvar("g_pickup_rockets_max");
- g_pickup_cells = cvar("g_pickup_cells");
- g_pickup_cells_max = cvar("g_pickup_cells_max");
- g_pickup_plasma = cvar("g_pickup_plasma");
- g_pickup_plasma_max = cvar("g_pickup_plasma_max");
- g_pickup_fuel = cvar("g_pickup_fuel");
- g_pickup_fuel_jetpack = cvar("g_pickup_fuel_jetpack");
- g_pickup_fuel_max = cvar("g_pickup_fuel_max");
- g_pickup_armorsmall = cvar("g_pickup_armorsmall");
- g_pickup_armorsmall_max = cvar("g_pickup_armorsmall_max");
- g_pickup_armorsmall_anyway = cvar("g_pickup_armorsmall_anyway");
- g_pickup_armormedium = cvar("g_pickup_armormedium");
- g_pickup_armormedium_max = cvar("g_pickup_armormedium_max");
- g_pickup_armormedium_anyway = cvar("g_pickup_armormedium_anyway");
- g_pickup_armorbig = cvar("g_pickup_armorbig");
- g_pickup_armorbig_max = cvar("g_pickup_armorbig_max");
- g_pickup_armorbig_anyway = cvar("g_pickup_armorbig_anyway");
- g_pickup_armorlarge = cvar("g_pickup_armorlarge");
- g_pickup_armorlarge_max = cvar("g_pickup_armorlarge_max");
- g_pickup_armorlarge_anyway = cvar("g_pickup_armorlarge_anyway");
- g_pickup_healthsmall = cvar("g_pickup_healthsmall");
- g_pickup_healthsmall_max = cvar("g_pickup_healthsmall_max");
- g_pickup_healthsmall_anyway = cvar("g_pickup_healthsmall_anyway");
- g_pickup_healthmedium = cvar("g_pickup_healthmedium");
- g_pickup_healthmedium_max = cvar("g_pickup_healthmedium_max");
- g_pickup_healthmedium_anyway = cvar("g_pickup_healthmedium_anyway");
- g_pickup_healthlarge = cvar("g_pickup_healthlarge");
- g_pickup_healthlarge_max = cvar("g_pickup_healthlarge_max");
- g_pickup_healthlarge_anyway = cvar("g_pickup_healthlarge_anyway");
- g_pickup_healthmega = cvar("g_pickup_healthmega");
- g_pickup_healthmega_max = cvar("g_pickup_healthmega_max");
- g_pickup_healthmega_anyway = cvar("g_pickup_healthmega_anyway");
-
- g_pickup_ammo_anyway = cvar("g_pickup_ammo_anyway");
- g_pickup_weapons_anyway = cvar("g_pickup_weapons_anyway");
-
- g_weapon_stay = cvar(strcat("g_", GetGametype(), "_weapon_stay"));
- if(!g_weapon_stay)
- g_weapon_stay = cvar("g_weapon_stay");
-
- if (!warmup_stage)
- game_starttime = time + cvar("g_start_delay");
-
- readplayerstartcvars();
- }
-
- //#NO AUTOCVARS END
-
- // Sound functions
- string precache_sound (string s) = #19;
- float precache_sound_index (string s) = #19;
-
- #define SND_VOLUME 1
- #define SND_ATTENUATION 2
- #define SND_LARGEENTITY 8
- #define SND_LARGESOUND 16
-
- float sound_allowed(float dest, entity e)
+ float sound_allowed(float _dest, entity e)
{
// sounds from world may always pass
for (;;)
break;
}
// sounds to self may always pass
- if (dest == MSG_ONE)
+ if (_dest == MSG_ONE)
if (e == msg_entity)
- return TRUE;
+ return true;
// sounds by players can be removed
if (autocvar_bot_sound_monopoly)
if (IS_REAL_CLIENT(e))
- return FALSE;
+ return false;
// anything else may pass
- return TRUE;
+ return true;
}
#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 _atten)
{
if (!sound_allowed(MSG_BROADCAST, e))
return;
- sound7(e, chan, samp, vol, atten, 0, 0);
+ sound7(e, chan, samp, vol, _atten, 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 _atten)
{
float entno, idx;
- if (!sound_allowed(dest, e))
+ if (!sound_allowed(_dest, e))
return;
entno = num_for_edict(e);
float sflags;
sflags = 0;
- atten = floor(atten * 64);
+ _atten = floor(_atten * 64);
vol = floor(vol * 255);
if (vol != 255)
sflags |= SND_VOLUME;
- if (atten != 64)
+ if (_atten != 64)
sflags |= SND_ATTENUATION;
if (entno >= 8192 || chan < 0 || chan > 7)
sflags |= SND_LARGEENTITY;
if (idx >= 256)
sflags |= SND_LARGESOUND;
- WriteByte(dest, SVC_SOUND);
- WriteByte(dest, sflags);
+ WriteByte(_dest, SVC_SOUND);
+ WriteByte(_dest, sflags);
if (sflags & SND_VOLUME)
- WriteByte(dest, vol);
+ WriteByte(_dest, vol);
if (sflags & SND_ATTENUATION)
- WriteByte(dest, atten);
+ WriteByte(_dest, _atten);
if (sflags & SND_LARGEENTITY)
{
- WriteShort(dest, entno);
- WriteByte(dest, chan);
+ WriteShort(_dest, entno);
+ WriteByte(_dest, chan);
}
else
{
- WriteShort(dest, entno * 8 + chan);
+ WriteShort(_dest, entno * 8 + chan);
}
if (sflags & SND_LARGESOUND)
- WriteShort(dest, idx);
+ WriteShort(_dest, idx);
else
- WriteByte(dest, idx);
+ WriteByte(_dest, idx);
- WriteCoord(dest, o_x);
- WriteCoord(dest, o_y);
- WriteCoord(dest, o_z);
+ WriteCoord(_dest, o.x);
+ WriteCoord(_dest, o.y);
+ WriteCoord(_dest, o.z);
}
- void soundto(float dest, entity e, float chan, string samp, float vol, float atten)
+ void soundto(float _dest, entity e, float chan, string samp, float vol, float _atten)
{
vector o;
- if (!sound_allowed(dest, e))
+ if (!sound_allowed(_dest, e))
return;
o = e.origin + 0.5 * (e.mins + e.maxs);
- soundtoat(dest, e, o, chan, samp, vol, atten);
+ soundtoat(_dest, e, o, chan, samp, vol, _atten);
}
- void soundat(entity e, vector o, float chan, string samp, float vol, float atten)
+ void soundat(entity e, vector o, float chan, string samp, float vol, float _atten)
{
- soundtoat(((chan & 8) ? MSG_ALL : MSG_BROADCAST), e, o, chan, samp, vol, atten);
+ soundtoat(((chan & 8) ? MSG_ALL : MSG_BROADCAST), e, o, chan, samp, vol, _atten);
}
- void stopsoundto(float dest, entity e, float chan)
+ void stopsoundto(float _dest, entity e, float chan)
{
float entno;
- if (!sound_allowed(dest, e))
+ if (!sound_allowed(_dest, e))
return;
entno = num_for_edict(e);
sflags = SND_LARGEENTITY;
if (idx >= 256)
sflags |= SND_LARGESOUND;
- WriteByte(dest, SVC_SOUND);
- WriteByte(dest, sflags);
- WriteShort(dest, entno);
- WriteByte(dest, chan);
+ WriteByte(_dest, SVC_SOUND);
+ WriteByte(_dest, sflags);
+ WriteShort(_dest, entno);
+ WriteByte(_dest, chan);
if (sflags & SND_LARGESOUND)
- WriteShort(dest, idx);
+ WriteShort(_dest, idx);
else
- WriteByte(dest, idx);
- WriteCoord(dest, e.origin_x);
- WriteCoord(dest, e.origin_y);
- WriteCoord(dest, e.origin_z);
+ WriteByte(_dest, idx);
+ WriteCoord(_dest, e.origin.x);
+ WriteCoord(_dest, e.origin.y);
+ WriteCoord(_dest, e.origin.z);
}
else
{
- WriteByte(dest, SVC_STOPSOUND);
- WriteShort(dest, entno * 8 + chan);
+ WriteByte(_dest, SVC_STOPSOUND);
+ WriteShort(_dest, entno * 8 + chan);
}
}
void stopsound(entity e, float chan)
// use this one if you might be causing spam (e.g. from touch functions that might get called more than once per frame)
.float spamtime;
- float spamsound(entity e, float chan, string samp, float vol, float atten)
+ float spamsound(entity e, float chan, string samp, float vol, float _atten)
{
if (!sound_allowed(MSG_BROADCAST, e))
- return FALSE;
+ return false;
if (time > e.spamtime)
{
e.spamtime = time;
- sound(e, chan, samp, vol, atten);
- return TRUE;
+ sound(e, chan, samp, vol, _atten);
+ return true;
}
- return FALSE;
+ return false;
}
void play2team(float t, string filename)
if(fexists(f))
precache_model(f);
- globhandle = search_begin(strcat(m, "_*.sounds"), TRUE, FALSE);
+ globhandle = search_begin(strcat(m, "_*.sounds"), true, false);
if (globhandle < 0)
return;
n = search_getsize(globhandle);
float globhandle, i, n;
string f;
- globhandle = search_begin(pattern, TRUE, FALSE);
+ globhandle = search_begin(pattern, true, false);
if (globhandle < 0)
return;
n = search_getsize(globhandle);
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)
{
#include "precache-for-csqc.inc"
}
- // WARNING: this kills the trace globals
- #define EXACTTRIGGER_TOUCH if(WarpZoneLib_ExactTrigger_Touch()) return
- #define EXACTTRIGGER_INIT WarpZoneLib_ExactTrigger_Init()
-
- #define INITPRIO_FIRST 0
- #define INITPRIO_GAMETYPE 0
- #define INITPRIO_GAMETYPE_FALLBACK 1
- #define INITPRIO_FINDTARGET 10
- #define INITPRIO_DROPTOFLOOR 20
- #define INITPRIO_SETLOCATION 90
- #define INITPRIO_LINKDOORS 91
- #define INITPRIO_LAST 99
-
- .void(void) initialize_entity;
- .float initialize_entity_order;
- .entity initialize_entity_next;
- entity initialize_entity_first;
void make_safe_for_remove(entity e)
{
remove = remove_unsafely;
}
- .float uncustomizeentityforclient_set;
- .void(void) uncustomizeentityforclient;
void UncustomizeEntitiesRun()
{
entity oldself;
e.uncustomizeentityforclient_set = !!uncustomizer;
}
- .float nottargeted;
- #define IFTARGETED if(!self.nottargeted && self.targetname != "")
- void() SUB_Remove;
void Net_LinkEntity(entity e, float docull, float dt, float(entity, float) sendfunc)
{
vector mi, ma;
}
}
- return TRUE;
+ return true;
}
void EliminatedPlayers_Init(float(entity) isEliminated_func)
backtrace("Can't spawn eliminatedPlayers again!");
return;
}
- Net_LinkEntity(eliminatedPlayers = spawn(), FALSE, 0, EliminatedPlayers_SendEntity);
+ Net_LinkEntity(eliminatedPlayers = spawn(), false, 0, EliminatedPlayers_SendEntity);
eliminatedPlayers.isEliminated = isEliminated_func;
}
{
// just check if x is in range
if (0 < thmi)
- return FALSE;
+ return false;
if (0 > thma)
- return FALSE;
+ return false;
}
else
{
trace_hits_box_a0 = max(trace_hits_box_a0, min(thmi / end, thma / end));
trace_hits_box_a1 = min(trace_hits_box_a1, max(thmi / end, thma / end));
if (trace_hits_box_a0 > trace_hits_box_a1)
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
float trace_hits_box(vector start, vector end, vector thmi, vector thma)
trace_hits_box_a0 = 0;
trace_hits_box_a1 = 1;
- if (!trace_hits_box_1d(end_x, thmi_x, thma_x))
- return FALSE;
- if (!trace_hits_box_1d(end_y, thmi_y, thma_y))
- return FALSE;
- if (!trace_hits_box_1d(end_z, thmi_z, thma_z))
- return FALSE;
+ if (!trace_hits_box_1d(end.x, thmi.x, thma.x))
+ return false;
+ if (!trace_hits_box_1d(end.y, thmi.y, thma.y))
+ return false;
+ if (!trace_hits_box_1d(end.z, thmi.z, thma.z))
+ return false;
- return TRUE;
+ return true;
}
float tracebox_hits_box(vector start, vector mi, vector ma, vector end, vector thmi, vector thma)
float WarpZone_Projectile_Touch_ImpactFilter_Callback()
{
if(SUB_OwnerCheck())
- return TRUE;
+ return true;
if(SUB_NoImpactCheck())
{
if(self.classname == "nade")
- return FALSE; // no checks here
+ return false; // no checks here
else if(self.classname == "grapplinghook")
RemoveGrapplingHook(self.realowner);
else if(self.classname == "spike")
}
else
remove(self);
- return TRUE;
+ return true;
}
if(trace_ent && trace_ent.solid > SOLID_TRIGGER)
UpdateCSQCProjectile(self);
- return FALSE;
+ return false;
}
- #define PROJECTILE_TOUCH if(WarpZone_Projectile_Touch()) return
- #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))
void URI_Get_Callback(float id, float status, string data)
{
for (i = 0; i < attempts; ++i)
{
- start_x = org_x + random() * delta_x;
- start_y = org_y + random() * delta_y;
- start_z = org_z + random() * delta_z;
+ start.x = org.x + random() * delta.x;
+ start.y = org.y + random() * delta.y;
+ start.z = org.z + random() * delta.z;
// rule 1: start inside world bounds, and outside
// solid, and don't start from somewhere where you can
// fall down to evil
- tracebox(start, e.mins, e.maxs, start - '0 0 1' * delta_z, MOVE_NORMAL, e);
+ tracebox(start, e.mins, e.maxs, start - '0 0 1' * delta.z, MOVE_NORMAL, e);
if (trace_fraction >= 1)
continue;
if (trace_startsolid)
continue;
// rule 2: if we are too high, lower the point
- if (trace_fraction * delta_z > maxaboveground)
+ if (trace_fraction * delta.z > maxaboveground)
start = trace_endpos + '0 0 1' * maxaboveground;
enddown = trace_endpos;
// the map should have a convex outside hull.
// these can be traceLINES as we already verified the starting box
mstart = start + 0.5 * (e.mins + e.maxs);
- traceline(mstart, mstart + '1 0 0' * delta_x, MOVE_NORMAL, e);
+ traceline(mstart, mstart + '1 0 0' * delta.x, MOVE_NORMAL, e);
if (trace_fraction >= 1 || trace_dphittexturename == "common/caulk")
continue;
- traceline(mstart, mstart - '1 0 0' * delta_x, MOVE_NORMAL, e);
+ traceline(mstart, mstart - '1 0 0' * delta.x, MOVE_NORMAL, e);
if (trace_fraction >= 1 || trace_dphittexturename == "common/caulk")
continue;
- traceline(mstart, mstart + '0 1 0' * delta_y, MOVE_NORMAL, e);
+ traceline(mstart, mstart + '0 1 0' * delta.y, MOVE_NORMAL, e);
if (trace_fraction >= 1 || trace_dphittexturename == "common/caulk")
continue;
- traceline(mstart, mstart - '0 1 0' * delta_y, MOVE_NORMAL, e);
+ traceline(mstart, mstart - '0 1 0' * delta.y, MOVE_NORMAL, e);
if (trace_fraction >= 1 || trace_dphittexturename == "common/caulk")
continue;
- traceline(mstart, mstart + '0 0 1' * delta_z, MOVE_NORMAL, e);
+ traceline(mstart, mstart + '0 0 1' * delta.z, MOVE_NORMAL, e);
if (trace_fraction >= 1 || trace_dphittexturename == "common/caulk")
continue;
}
// find a random vector to "look at"
- end_x = org_x + random() * delta_x;
- end_y = org_y + random() * delta_y;
- end_z = org_z + random() * delta_z;
+ end.x = org.x + random() * delta.x;
+ end.y = org.y + random() * delta.y;
+ end.z = org.z + random() * delta.z;
end = start + normalize(end - start) * vlen(delta);
// rule 4: start TO end must not be too short
setorigin(e, start);
e.angles = vectoangles(end - start);
dprint("Needed ", ftos(i + 1), " attempts\n");
- return TRUE;
+ return true;
}
else
- return FALSE;
+ return false;
}
void write_recordmarker(entity pl, float tstart, float dt)
break;
case 4: // left
- vecs_y = -vecs_y;
+ vecs.y = -vecs.y;
break;
case 1:
if(allowcenter) // 2: allow center handedness
{
// center
- vecs_y = 0;
- vecs_z -= 2;
+ vecs.y = 0;
+ vecs.z -= 2;
}
else
{
if(allowcenter) // 2: allow center handedness
{
// center
- vecs_y = 0;
- vecs_z -= 2;
+ vecs.y = 0;
+ vecs.z -= 2;
}
else
{
// left
- vecs_y = -vecs_y;
+ vecs.y = -vecs.y;
}
break;
}
if (visual)
{
if (autocvar_g_shootfromclient) { vecs = shotorg_adjustfromclient(vecs, y_is_right, (autocvar_g_shootfromclient >= 2), algn); }
- else { vecs_y = 0; vecs_z -= 2; }
+ else { vecs.y = 0; vecs.z -= 2; }
}
else
{
- vecs_y = 0;
- vecs_z = 0;
+ vecs.y = 0;
+ vecs.z = 0;
}
}
else if (autocvar_g_shootfromcenter)
{
- vecs_y = 0;
- vecs_z -= 2;
+ vecs.y = 0;
+ vecs.z -= 2;
}
else if ((s = autocvar_g_shootfromfixedorigin) != "")
{
v = stov(s);
if (y_is_right)
- v_y = -v_y;
- if (v_x != 0)
- vecs_x = v_x;
- vecs_y = v_y;
- vecs_z = v_z;
+ v.y = -v.y;
+ if (v.x != 0)
+ vecs.x = v.x;
+ vecs.y = v.y;
+ vecs.z = v.z;
}
else if (autocvar_g_shootfromclient)
{
fixedmakevectors(e.angles);
// untransform forward, up!
- e_forward_x = v_forward * t_forward;
- e_forward_y = v_forward * t_left;
- e_forward_z = v_forward * t_up;
- e_up_x = v_up * t_forward;
- e_up_y = v_up * t_left;
- e_up_z = v_up * t_up;
+ e_forward.x = v_forward * t_forward;
+ e_forward.y = v_forward * t_left;
+ e_forward.z = v_forward * t_up;
+ e_up.x = v_up * t_forward;
+ e_up.y = v_up * t_left;
+ e_up.z = v_up * t_up;
e.angles = fixedvectoangles2(e_forward, e_up);
if (substring(e.model, 0, 1) == "*") // bmodels have their own rules
WriteShort(MSG_ENTITY, self.modelindex);
WriteByte(MSG_ENTITY, self.skin);
WriteByte(MSG_ENTITY, self.frame);
- WriteCoord(MSG_ENTITY, self.origin_x);
- WriteCoord(MSG_ENTITY, self.origin_y);
- WriteCoord(MSG_ENTITY, self.origin_z);
+ WriteCoord(MSG_ENTITY, self.origin.x);
+ WriteCoord(MSG_ENTITY, self.origin.y);
+ WriteCoord(MSG_ENTITY, self.origin.z);
if(f & 1)
{
- WriteCoord(MSG_ENTITY, self.velocity_x);
- WriteCoord(MSG_ENTITY, self.velocity_y);
- WriteCoord(MSG_ENTITY, self.velocity_z);
+ WriteCoord(MSG_ENTITY, self.velocity.x);
+ WriteCoord(MSG_ENTITY, self.velocity.y);
+ WriteCoord(MSG_ENTITY, self.velocity.z);
}
if(f & 2)
{
- WriteCoord(MSG_ENTITY, self.angles_x);
- WriteCoord(MSG_ENTITY, self.angles_y);
- WriteCoord(MSG_ENTITY, self.angles_z);
+ WriteCoord(MSG_ENTITY, self.angles.x);
+ WriteCoord(MSG_ENTITY, self.angles.y);
+ WriteCoord(MSG_ENTITY, self.angles.z);
}
if(f & 4)
{
- WriteCoord(MSG_ENTITY, self.avelocity_x);
- WriteCoord(MSG_ENTITY, self.avelocity_y);
- WriteCoord(MSG_ENTITY, self.avelocity_z);
+ WriteCoord(MSG_ENTITY, self.avelocity.x);
+ WriteCoord(MSG_ENTITY, self.avelocity.y);
+ WriteCoord(MSG_ENTITY, self.avelocity.z);
}
WriteShort(MSG_ENTITY, self.scale * 256.0);
WriteShort(MSG_ENTITY, self.scale2 * 256.0);
WriteByte(MSG_ENTITY, self.fade_time * 100.0);
WriteByte(MSG_ENTITY, self.alpha * 255.0);
- return TRUE;
+ return true;
}
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)
e.fade_time = t2;
e.skin = s;
if(s0 >= 0)
- e.scale = s0 / max6(-e.mins_x, -e.mins_y, -e.mins_z, e.maxs_x, e.maxs_y, e.maxs_z);
+ e.scale = s0 / max6(-e.mins.x, -e.mins.y, -e.mins.z, e.maxs.x, e.maxs.y, e.maxs.z);
else
e.scale = -s0;
if(s2 >= 0)
- e.scale2 = s2 / max6(-e.mins_x, -e.mins_y, -e.mins_z, e.maxs_x, e.maxs_y, e.maxs_z);
+ e.scale2 = s2 / max6(-e.mins.x, -e.mins.y, -e.mins.z, e.maxs.x, e.maxs.y, e.maxs.z);
else
e.scale2 = -s2;
sz = max(e.scale, e.scale2);
setsize(e, e.mins * sz, e.maxs * sz);
- Net_LinkEntity(e, FALSE, 0.1, modeleffect_SendEntity);
+ Net_LinkEntity(e, false, 0.1, modeleffect_SendEntity);
}
void shockwave_spawn(string m, vector org, float sz, float t1, float t2)
}
-
-
- #ifdef RELEASE
- #define cvar_string_normal builtin_cvar_string
- #define cvar_normal builtin_cvar
- #else
- string cvar_string_normal(string n)
- {
- if (!(cvar_type(n) & 1))
- backtrace(strcat("Attempt to access undefined cvar: ", n));
- return builtin_cvar_string(n);
- }
-
- float cvar_normal(string n)
- {
- return stof(cvar_string_normal(n));
- }
- #endif
- #define cvar_set_normal builtin_cvar_set
-
void defer_think()
{
entity oself;
float isPushable(entity e)
{
if(e.iscreature)
- return TRUE;
+ return true;
if(e.pushable)
- return TRUE;
+ return true;
switch(e.classname)
{
case "body":
case "keepawayball":
case "nexball_basketball":
case "nexball_football":
- return TRUE;
+ return true;
case "bullet": // antilagged bullets can't hit this either
- return FALSE;
+ return false;
}
if (e.projectiledeathtype)
- return TRUE;
- return FALSE;
+ return true;
+ return false;
}
decreaser = self.assault_decreaser;
if(decreaser.enemy.health >= ASSAULT_VALUE_INACTIVE)
- return FALSE;
+ return false;
- return TRUE;
+ return true;
}
void target_objective_decrease_activate()
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()
if (!ad.bot_attack)
continue;
- found = FALSE;
+ found = false;
for(tod = world; (tod = find(tod, targetname, ad.target)); )
{
if(tod.classname == "target_objective_decrease")
if(tod.enemy.health > 0 && tod.enemy.health < ASSAULT_VALUE_INACTIVE)
{
// dprint(etos(ad),"\n");
- found = TRUE;
+ found = true;
break;
}
}
// te_lightning2(world, '0 0 0', p);
// Find and rate waypoints around it
- found = FALSE;
+ found = false;
best = world;
bestvalue = 99999999999;
for(radius=0; radius<1500 && !found; radius+=500)
if(wp.classname=="waypoint")
if(checkpvs(wp.origin, ad))
{
- found = TRUE;
+ found = true;
if(wp.cnt<bestvalue)
{
best = wp;
else
Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_ASSAULT_DEFENDING);
- return FALSE;
+ return false;
}
MUTATOR_HOOKFUNCTION(assault_TurretSpawn)
if (!self.team)
self.team = 14;
- return FALSE;
+ return false;
}
MUTATOR_HOOKFUNCTION(assault_VehicleSpawn)
{
self.nextthink = time + 0.5;
- return FALSE;
+ return false;
}
MUTATOR_HOOKFUNCTION(assault_BotRoles)
{
havocbot_ast_reset_role(self);
- return TRUE;
+ return true;
}
// scoreboard setup
void assault_ScoreRules()
{
- ScoreRules_basics(2, SFL_SORT_PRIO_SECONDARY, SFL_SORT_PRIO_SECONDARY, TRUE);
+ ScoreRules_basics(2, SFL_SORT_PRIO_SECONDARY, SFL_SORT_PRIO_SECONDARY, true);
ScoreInfo_SetLabel_TeamScore( ST_ASSAULT_OBJECTIVES, "objectives", SFL_SORT_PRIO_PRIMARY);
ScoreInfo_SetLabel_PlayerScore(SP_ASSAULT_OBJECTIVES, "objectives", SFL_SORT_PRIO_PRIMARY);
ScoreRules_basics_end();
float autocvar_g_onslaught_spawn_at_controlpoints;
float autocvar_g_onslaught_spawn_at_generator;
float autocvar_g_onslaught_cp_proxydecap;
- var float autocvar_g_onslaught_cp_proxydecap_distance = 512;
- var float autocvar_g_onslaught_cp_proxydecap_dps = 100;
+ float autocvar_g_onslaught_cp_proxydecap_distance = 512;
+ float autocvar_g_onslaught_cp_proxydecap_dps = 100;
void onslaught_generator_updatesprite(entity e);
void onslaught_controlpoint_updatesprite(entity e);
l = findchain(classname, "onslaught_controlpoint");
while (l)
{
- l.islinked = FALSE;
- l.isshielded = TRUE;
- l.isgenneighbor_red = FALSE;
- l.isgenneighbor_blue = FALSE;
- l.iscpneighbor_red = FALSE;
- l.iscpneighbor_blue = FALSE;
+ l.islinked = false;
+ l.isshielded = true;
+ l.isgenneighbor_red = false;
+ l.isgenneighbor_blue = false;
+ l.iscpneighbor_red = false;
+ l.iscpneighbor_blue = false;
dprint(etos(l), " (point) belongs to team ", ftos(l.team), "\n");
l = l.chain;
}
dprint(etos(l), " (link) connects ", etos(l.goalentity), " with ", etos(l.enemy), "\n");
l = l.chain;
}
- stop = FALSE;
+ stop = false;
while (!stop)
{
- stop = TRUE;
+ stop = true;
l = links;
while (l)
{
{
if (!l.goalentity.islinked)
{
- stop = FALSE;
- l.goalentity.islinked = TRUE;
+ stop = false;
+ l.goalentity.islinked = true;
dprint(etos(l), " (link) is marking ", etos(l.goalentity), " (point) because its team matches ", etos(l.enemy), " (point)\n");
}
else if (!l.enemy.islinked)
{
- stop = FALSE;
- l.enemy.islinked = TRUE;
+ stop = false;
+ l.enemy.islinked = true;
dprint(etos(l), " (link) is marking ", etos(l.enemy), " (point) because its team matches ", etos(l.goalentity), " (point)\n");
}
}
if (l.goalentity.team != l.enemy.team)
{
dprint(etos(l), " (link) is unshielding ", etos(l.enemy), " (point) because its team does not match ", etos(l.goalentity), " (point)\n");
- l.enemy.isshielded = FALSE;
+ l.enemy.isshielded = false;
}
if(l.goalentity.classname == "onslaught_generator")
{
if(l.goalentity.team == NUM_TEAM_1)
- l.enemy.isgenneighbor_red = TRUE;
+ l.enemy.isgenneighbor_red = true;
else if(l.goalentity.team == NUM_TEAM_2)
- l.enemy.isgenneighbor_blue = TRUE;
+ l.enemy.isgenneighbor_blue = true;
}
else
{
if(l.goalentity.team == NUM_TEAM_1)
- l.enemy.iscpneighbor_red = TRUE;
+ l.enemy.iscpneighbor_red = true;
else if(l.goalentity.team == NUM_TEAM_2)
- l.enemy.iscpneighbor_blue = TRUE;
+ l.enemy.iscpneighbor_blue = true;
}
}
if (l.enemy.islinked)
if (l.goalentity.team != l.enemy.team)
{
dprint(etos(l), " (link) is unshielding ", etos(l.goalentity), " (point) because its team does not match ", etos(l.enemy), " (point)\n");
- l.goalentity.isshielded = FALSE;
+ l.goalentity.isshielded = false;
}
if(l.enemy.classname == "onslaught_generator")
{
if(l.enemy.team == NUM_TEAM_1)
- l.goalentity.isgenneighbor_red = TRUE;
+ l.goalentity.isgenneighbor_red = true;
else if(l.enemy.team == NUM_TEAM_2)
- l.goalentity.isgenneighbor_blue = TRUE;
+ l.goalentity.isgenneighbor_blue = true;
}
else
{
if(l.enemy.team == NUM_TEAM_1)
- l.goalentity.iscpneighbor_red = TRUE;
+ l.goalentity.iscpneighbor_red = true;
else if(l.enemy.team == NUM_TEAM_2)
- l.goalentity.iscpneighbor_blue = TRUE;
+ l.goalentity.iscpneighbor_blue = true;
}
}
l = l.chain;
dprint(etos(l), " (generator) is shielded\n");
l.enemy.alpha = 1;
l.takedamage = DAMAGE_NO;
- l.bot_attack = FALSE;
+ l.bot_attack = false;
}
else
{
dprint(etos(l), " (generator) is not shielded\n");
l.enemy.alpha = -1;
l.takedamage = DAMAGE_AIM;
- l.bot_attack = TRUE;
+ l.bot_attack = true;
}
l = l.chain;
}
if (l.goalentity)
{
l.goalentity.takedamage = DAMAGE_NO;
- l.goalentity.bot_attack = FALSE;
+ l.goalentity.bot_attack = false;
}
}
else
if (l.goalentity)
{
l.goalentity.takedamage = DAMAGE_AIM;
- l.goalentity.bot_attack = TRUE;
+ l.goalentity.bot_attack = true;
}
}
onslaught_controlpoint_updatesprite(l);
{
i = random();
if(i < 0.3)
- ons_throwgib(self.origin + '0 0 40', (100 * randomvec() - '1 1 1') * 11 + '0 0 20', "models/onslaught/gen_gib1.md3", 6, TRUE);
+ ons_throwgib(self.origin + '0 0 40', (100 * randomvec() - '1 1 1') * 11 + '0 0 20', "models/onslaught/gen_gib1.md3", 6, true);
else if(i > 0.7)
- ons_throwgib(self.origin + '0 0 40', (100 * randomvec() - '1 1 1') * 12 + '0 0 20', "models/onslaught/gen_gib2.md3", 6, TRUE);
+ ons_throwgib(self.origin + '0 0 40', (100 * randomvec() - '1 1 1') * 12 + '0 0 20', "models/onslaught/gen_gib2.md3", 6, true);
else
- ons_throwgib(self.origin + '0 0 40', (100 * randomvec() - '1 1 1') * 13 + '0 0 20', "models/onslaught/gen_gib3.md3", 6, TRUE);
+ ons_throwgib(self.origin + '0 0 40', (100 * randomvec() - '1 1 1') * 13 + '0 0 20', "models/onslaught/gen_gib3.md3", 6, true);
}
// Spawn fire balls
t = Team_ColoredFullName(attacker.team);
bprint(Team_ColoredFullName(self.team), " generator destroyed by ", t, "!\n");
}
- self.iscaptured = FALSE;
- self.islinked = FALSE;
- self.isshielded = FALSE;
+ self.iscaptured = false;
+ self.islinked = false;
+ self.isshielded = false;
self.takedamage = DAMAGE_NO; // can't be hurt anymore
self.event_damage = func_null; // won't do anything if hurt
self.count = 0; // reset counter
sound(self, CH_TRIGGER, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM);
i = random();
if(i < 0.3)
- ons_throwgib(hitloc + '0 0 20', force * -1, "models/onslaught/gen_gib1.md3", 5, TRUE);
+ ons_throwgib(hitloc + '0 0 20', force * -1, "models/onslaught/gen_gib1.md3", 5, true);
else if(i > 0.7)
- ons_throwgib(hitloc + '0 0 20', force * -1, "models/onslaught/gen_gib2.md3", 5, TRUE);
+ ons_throwgib(hitloc + '0 0 20', force * -1, "models/onslaught/gen_gib2.md3", 5, true);
else
- ons_throwgib(hitloc + '0 0 20', force * -1, "models/onslaught/gen_gib3.md3", 5, TRUE);
+ ons_throwgib(hitloc + '0 0 20', force * -1, "models/onslaught/gen_gib3.md3", 5, true);
}
else
{
//throw some gibs on damage
if(random() < damage/200+0.2)
if(random() < 0.5)
- ons_throwgib(hitloc + '0 0 20', randomvec()*360, "models/onslaught/gen_gib1.md3", 5, FALSE);
+ ons_throwgib(hitloc + '0 0 20', randomvec()*360, "models/onslaught/gen_gib1.md3", 5, false);
}
// update links after a delay
if(e.lastshielded)
{
if(e.team == NUM_TEAM_1 || e.team == NUM_TEAM_2)
- WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_GENERATOR, 0.5 * colormapPaletteColor(e.team - 1, FALSE));
+ WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_GENERATOR, 0.5 * colormapPaletteColor(e.team - 1, false));
else
WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_GENERATOR, '0.5 0.5 0.5');
}
else
{
if(e.team == NUM_TEAM_1 || e.team == NUM_TEAM_2)
- WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_GENERATOR, colormapPaletteColor(e.team - 1, FALSE));
+ WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_GENERATOR, colormapPaletteColor(e.team - 1, false));
else
WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_GENERATOR, '0.75 0.75 0.75');
}
if(e.lastshielded)
{
if(e.team == NUM_TEAM_1 || e.team == NUM_TEAM_2)
- WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_CONTROLPOINT, 0.5 * colormapPaletteColor(e.team - 1, FALSE));
+ WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_CONTROLPOINT, 0.5 * colormapPaletteColor(e.team - 1, false));
else
WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_CONTROLPOINT, '0.5 0.5 0.5');
}
else
{
if(e.team == NUM_TEAM_1 || e.team == NUM_TEAM_2)
- WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_CONTROLPOINT, colormapPaletteColor(e.team - 1, FALSE));
+ WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_CONTROLPOINT, colormapPaletteColor(e.team - 1, false));
else
WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_CONTROLPOINT, '0.75 0.75 0.75');
}
self.team = self.team_saved;
self.lasthealth = self.max_health = self.health = autocvar_g_onslaught_gen_health;
self.takedamage = DAMAGE_AIM;
- self.bot_attack = TRUE;
- self.iscaptured = TRUE;
- self.islinked = TRUE;
- self.isshielded = TRUE;
+ self.bot_attack = true;
+ self.iscaptured = true;
+ self.islinked = true;
+ self.isshielded = true;
self.enemy.solid = SOLID_NOT;
self.think = onslaught_generator_delayed;
self.nextthink = time + 0.2;
setsize(self, '-52 -52 -14', '52 52 75');
setorigin(self, self.origin);
self.takedamage = DAMAGE_AIM;
- self.bot_attack = TRUE;
+ self.bot_attack = true;
self.event_damage = onslaught_generator_damage;
- self.iscaptured = TRUE;
- self.islinked = TRUE;
- self.isshielded = TRUE;
+ self.iscaptured = true;
+ self.islinked = true;
+ self.isshielded = true;
// helper entity that create fx when generator is damaged
onslaught_generator_damage_spawn(self);
// spawn shield model which indicates whether this can be damaged
if (IS_PLAYER(attacker))
{
- nag = FALSE;
+ nag = false;
if(self.team == NUM_TEAM_1)
{
if(time - ons_notification_time_team1 > 10)
{
- nag = TRUE;
+ nag = true;
ons_notification_time_team1 = time;
}
}
{
if(time - ons_notification_time_team2 > 10)
{
- nag = TRUE;
+ nag = true;
ons_notification_time_team2 = time;
}
}
else
- nag = TRUE;
+ nag = true;
if(nag)
play2team(self.team, "onslaught/controlpoint_underattack.wav");
string t;
t = Team_ColoredFullName(attacker.team);
bprint(Team_ColoredFullName(self.team), " ", self.message, " control point destroyed by ", t, "\n");
- ons_throwgib(self.origin, (2 * randomvec() - '1 1 1') * 25, "models/onslaught/controlpoint_icon_gib1.md3", 3, FALSE);
- ons_throwgib(self.origin, (2 * randomvec() - '1 1 1') * 45, "models/onslaught/controlpoint_icon_gib2.md3", 3, FALSE);
- ons_throwgib(self.origin, (2 * randomvec() - '1 1 1') * 45, "models/onslaught/controlpoint_icon_gib2.md3", 3, FALSE);
- ons_throwgib(self.origin, (2 * randomvec() - '1 1 1') * 75, "models/onslaught/controlpoint_icon_gib4.md3", 3, FALSE);
- ons_throwgib(self.origin, (2 * randomvec() - '1 1 1') * 75, "models/onslaught/controlpoint_icon_gib4.md3", 3, FALSE);
- ons_throwgib(self.origin, (2 * randomvec() - '1 1 1') * 75, "models/onslaught/controlpoint_icon_gib4.md3", 3, FALSE);
- ons_throwgib(self.origin, (2 * randomvec() - '1 1 1') * 75, "models/onslaught/controlpoint_icon_gib4.md3", 3, FALSE);
+ ons_throwgib(self.origin, (2 * randomvec() - '1 1 1') * 25, "models/onslaught/controlpoint_icon_gib1.md3", 3, false);
+ ons_throwgib(self.origin, (2 * randomvec() - '1 1 1') * 45, "models/onslaught/controlpoint_icon_gib2.md3", 3, false);
+ ons_throwgib(self.origin, (2 * randomvec() - '1 1 1') * 45, "models/onslaught/controlpoint_icon_gib2.md3", 3, false);
+ ons_throwgib(self.origin, (2 * randomvec() - '1 1 1') * 75, "models/onslaught/controlpoint_icon_gib4.md3", 3, false);
+ ons_throwgib(self.origin, (2 * randomvec() - '1 1 1') * 75, "models/onslaught/controlpoint_icon_gib4.md3", 3, false);
+ ons_throwgib(self.origin, (2 * randomvec() - '1 1 1') * 75, "models/onslaught/controlpoint_icon_gib4.md3", 3, false);
+ ons_throwgib(self.origin, (2 * randomvec() - '1 1 1') * 75, "models/onslaught/controlpoint_icon_gib4.md3", 3, false);
}
self.owner.goalentity = world;
- self.owner.islinked = FALSE;
- self.owner.iscaptured = FALSE;
+ self.owner.islinked = false;
+ self.owner.iscaptured = false;
self.owner.team = 0;
self.owner.colormap = 1024;
self.owner.waslinked = self.owner.islinked;
}
- if (self.punchangle_x > 0)
+ if (self.punchangle.x > 0)
{
- self.punchangle_x = self.punchangle_x - 60 * sys_frametime;
- if (self.punchangle_x < 0)
+ self.punchangle_x = self.punchangle.x - 60 * sys_frametime;
+ if (self.punchangle.x < 0)
self.punchangle_x = 0;
}
- else if (self.punchangle_x < 0)
+ else if (self.punchangle.x < 0)
{
- self.punchangle_x = self.punchangle_x + 60 * sys_frametime;
- if (self.punchangle_x > 0)
+ self.punchangle_x = self.punchangle.x + 60 * sys_frametime;
+ if (self.punchangle.x > 0)
self.punchangle_x = 0;
}
- if (self.punchangle_y > 0)
+ if (self.punchangle.y > 0)
{
- self.punchangle_y = self.punchangle_y - 60 * sys_frametime;
- if (self.punchangle_y < 0)
+ self.punchangle_y = self.punchangle.y - 60 * sys_frametime;
+ if (self.punchangle.y < 0)
self.punchangle_y = 0;
}
- else if (self.punchangle_y < 0)
+ else if (self.punchangle.y < 0)
{
- self.punchangle_y = self.punchangle_y + 60 * sys_frametime;
- if (self.punchangle_y > 0)
+ self.punchangle_y = self.punchangle.y + 60 * sys_frametime;
+ if (self.punchangle.y > 0)
self.punchangle_y = 0;
}
- if (self.punchangle_z > 0)
+ if (self.punchangle.z > 0)
{
- self.punchangle_z = self.punchangle_z - 60 * sys_frametime;
- if (self.punchangle_z < 0)
+ self.punchangle_z = self.punchangle.z - 60 * sys_frametime;
+ if (self.punchangle.z < 0)
self.punchangle_z = 0;
}
- else if (self.punchangle_z < 0)
+ else if (self.punchangle.z < 0)
{
- self.punchangle_z = self.punchangle_z + 60 * sys_frametime;
- if (self.punchangle_z > 0)
+ self.punchangle_z = self.punchangle.z + 60 * sys_frametime;
+ if (self.punchangle.z > 0)
self.punchangle_z = 0;
}
- self.angles_x = self.punchangle_x;
- self.angles_y = self.punchangle_y + self.mangle_y;
- self.angles_z = self.punchangle_z;
- self.mangle_y = self.mangle_y + 45 * sys_frametime;
+ self.angles_x = self.punchangle.x;
+ self.angles_y = self.punchangle.y + self.mangle.y;
+ self.angles_z = self.punchangle.z;
+ self.mangle_y = self.mangle.y + 45 * sys_frametime;
self.cp_bob_origin_z = 4 * PI * (1 - cos(self.cp_bob_spd));
self.cp_bob_spd = self.cp_bob_spd + 1.875 * sys_frametime;
- if(self.cp_bob_dmg_z > 0)
- self.cp_bob_dmg_z = self.cp_bob_dmg_z - 3 * sys_frametime;
+ if(self.cp_bob_dmg.z > 0)
+ self.cp_bob_dmg_z = self.cp_bob_dmg.z - 3 * sys_frametime;
else
self.cp_bob_dmg_z = 0;
setorigin(self,self.cp_origin + self.cp_bob_origin + self.cp_bob_dmg);
self.think = onslaught_controlpoint_icon_think;
sound(self, CH_TRIGGER, "onslaught/controlpoint_built.wav", VOL_BASE, ATTEN_NORM);
bprint(Team_ColoredFullName(self.team), " captured ", self.owner.message, " control point\n");
- self.owner.iscaptured = TRUE;
+ self.owner.iscaptured = true;
WaypointSprite_UpdateMaxHealth(self.owner.sprite, self.max_health);
WaypointSprite_UpdateHealth(self.owner.sprite, self.health);
setsize(e, '-32 -32 -32', '32 32 32');
setorigin(e, self.origin + '0 0 96');
e.takedamage = DAMAGE_AIM;
- e.bot_attack = TRUE;
+ e.bot_attack = true;
e.event_damage = onslaught_controlpoint_icon_damage;
e.team = other.team;
e.colormap = 1024 + (e.team - 1) * 17;
self.goalentity = world;
self.team = 0;
self.colormap = 1024;
- self.iscaptured = FALSE;
- self.islinked = FALSE;
- self.isshielded = TRUE;
+ self.iscaptured = false;
+ self.islinked = false;
+ self.isshielded = true;
self.enemy.solid = SOLID_NOT;
self.enemy.colormap = self.colormap;
self.think = onslaught_controlpoint_think;
activator = self;
SUB_UseTargets(); // to reset the structures, playerspawns etc.
-
+
CSQCMODEL_AUTOUPDATE();
}
self.touch = onslaught_controlpoint_touch;
self.team = 0;
self.colormap = 1024;
- self.iscaptured = FALSE;
- self.islinked = FALSE;
- self.isshielded = TRUE;
+ self.iscaptured = false;
+ self.islinked = false;
+ self.isshielded = true;
// spawn shield model which indicates whether this can be damaged
self.enemy = spawn();
self.enemy.colormap = self.colormap;
waypoint_spawnforitem(self);
-
+
self.think = onslaught_controlpoint_think;
self.nextthink = time;
onslaught_updatelinks();
self.reset = onslaught_controlpoint_reset;
-
+
CSQCMODEL_AUTOINIT();
}
WriteByte(MSG_ENTITY, sendflags);
if(sendflags & 1)
{
- WriteCoord(MSG_ENTITY, self.goalentity.origin_x);
- WriteCoord(MSG_ENTITY, self.goalentity.origin_y);
- WriteCoord(MSG_ENTITY, self.goalentity.origin_z);
+ WriteCoord(MSG_ENTITY, self.goalentity.origin.x);
+ WriteCoord(MSG_ENTITY, self.goalentity.origin.y);
+ WriteCoord(MSG_ENTITY, self.goalentity.origin.z);
}
if(sendflags & 2)
{
- WriteCoord(MSG_ENTITY, self.enemy.origin_x);
- WriteCoord(MSG_ENTITY, self.enemy.origin_y);
- WriteCoord(MSG_ENTITY, self.enemy.origin_z);
+ WriteCoord(MSG_ENTITY, self.enemy.origin.x);
+ WriteCoord(MSG_ENTITY, self.enemy.origin.y);
+ WriteCoord(MSG_ENTITY, self.enemy.origin.z);
}
if(sendflags & 4)
{
WriteByte(MSG_ENTITY, self.clientcolors); // which is goalentity's color + enemy's color * 16
}
- return TRUE;
+ return true;
}
void onslaught_link_checkupdate()
if (self.target == "" || self.target2 == "")
objerror("target and target2 must be set\n");
InitializeEntity(self, onslaught_link_delayed, INITPRIO_FINDTARGET);
- Net_LinkEntity(self, FALSE, 0, onslaught_link_send);
+ Net_LinkEntity(self, false, 0, onslaught_link_send);
}
MUTATOR_HOOKFUNCTION(ons_BuildMutatorsString)
{
/*
- float _neer_home = (random() > 0.5 ? TRUE : FALSE);
+ float _neer_home = (random() > 0.5 ? true : false);
RandomSelection_Init();
if(random() < 0.5) // 50/50 chane to use default spawnsystem.
return 0;
- float _close_to_home = ((random() > 0.5) ? TRUE : FALSE);
+ float _close_to_home = ((random() > 0.5) ? true : false);
entity _best = world, _trg_gen = world;
float _score, _best_score = MAX_SHOT_DISTANCE;
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 (e != world)
self.team = e.team;
- return FALSE;
+ return false;
}
MUTATOR_HOOKFUNCTION(ons_MonsterSpawn)
{
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;
+ return false;
}
MUTATOR_DEFINITION(gamemode_onslaught)
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 "../tturrets/include/turrets_early.qh"
+ #if defined(CSQC)
+ #elif defined(MENUQC)
+ #elif defined(SVQC)
+ #include "../../dpdefs/progsdefs.qh"
+ #include "../../dpdefs/dpextensions.qh"
+ #include "../../warpzonelib/anglestransform.qh"
+ #include "../../warpzonelib/mathlib.qh"
+ #include "../../warpzonelib/common.qh"
+ #include "../../warpzonelib/util_server.qh"
+ #include "../../warpzonelib/server.qh"
+ #include "../../common/constants.qh"
+ #include "../../common/stats.qh"
+ #include "../../common/teams.qh"
+ #include "../../common/util.qh"
+ #include "../../common/nades.qh"
+ #include "../../common/buffs.qh"
+ #include "../../common/test.qh"
+ #include "../../common/counting.qh"
+ #include "../../common/urllib.qh"
+ #include "../../common/command/markup.qh"
+ #include "../../common/command/rpn.qh"
+ #include "../../common/command/generic.qh"
+ #include "../../common/command/shared_defs.qh"
+ #include "../../common/net_notice.qh"
+ #include "../../common/animdecide.qh"
+ #include "../../common/monsters/monsters.qh"
+ #include "../../common/monsters/sv_monsters.qh"
+ #include "../../common/monsters/spawn.qh"
+ #include "../../common/weapons/config.qh"
+ #include "../../common/weapons/weapons.qh"
+ #include "../weapons/accuracy.qh"
+ #include "../weapons/common.qh"
+ #include "../weapons/csqcprojectile.qh"
+ #include "../weapons/hitplot.qh"
+ #include "../weapons/selection.qh"
+ #include "../weapons/spawning.qh"
+ #include "../weapons/throwing.qh"
+ #include "../weapons/tracing.qh"
+ #include "../weapons/weaponstats.qh"
+ #include "../weapons/weaponsystem.qh"
+ #include "../t_items.qh"
+ #include "../autocvars.qh"
+ #include "../constants.qh"
+ #include "../defs.qh"
+ #include "../../common/notifications.qh"
+ #include "../../common/deathtypes.qh"
+ #include "mutators_include.qh"
- #include "../tturrets/include/turrets.qh"
+ #include "../vehicles/vehicles_def.qh"
+ #include "../campaign.qh"
+ #include "../../common/campaign_common.qh"
+ #include "../../common/mapinfo.qh"
+ #include "../command/common.qh"
+ #include "../command/banning.qh"
+ #include "../command/radarmap.qh"
+ #include "../command/vote.qh"
+ #include "../command/getreplies.qh"
+ #include "../command/cmd.qh"
+ #include "../command/sv_cmd.qh"
+ #include "../../common/csqcmodel_settings.qh"
+ #include "../../csqcmodellib/common.qh"
+ #include "../../csqcmodellib/sv_model.qh"
+ #include "../anticheat.qh"
+ #include "../cheats.qh"
+ #include "../../common/playerstats.qh"
+ #include "../portals.qh"
+ #include "../g_hook.qh"
+ #include "../scores.qh"
+ #include "../spawnpoints.qh"
+ #include "../mapvoting.qh"
+ #include "../ipban.qh"
+ #include "../race.qh"
+ #include "../antilag.qh"
+ #include "../playerdemo.qh"
+ #include "../round_handler.qh"
+ #include "../item_key.qh"
+ #include "../secret.qh"
+ #include "../pathlib/pathlib.qh"
+ #include "../vehicles/vehicles.qh"
+ #endif
+
#include "base.qc"
#include "gamemode_assault.qc"
#include "gamemode_ca.qc"
- ../../progs.dat // output filename
+ ../../progs.dat
../common/util-pre.qh
sys-pre.qh
- ../dpdefs/progsdefs.qc
- ../dpdefs/dpextensions.qc
+ ../dpdefs/progsdefs.qh
+ ../dpdefs/dpextensions.qh
sys-post.qh
- ../warpzonelib/anglestransform.qh
- ../warpzonelib/mathlib.qh
- ../warpzonelib/common.qh
- ../warpzonelib/util_server.qh
- ../warpzonelib/server.qh
- ../common/constants.qh
- ../common/stats.qh
- ../common/teams.qh
- ../common/util.qh
- ../common/nades.qh
- ../common/buffs.qh
- ../common/test.qh
- ../common/counting.qh
- ../common/urllib.qh
- ../common/command/markup.qh
- ../common/command/rpn.qh
- ../common/command/generic.qh
- ../common/command/shared_defs.qh
- ../common/net_notice.qh
- ../common/animdecide.qh
- ../common/monsters/monsters.qh
- ../common/monsters/sv_monsters.qh
- ../common/monsters/spawn.qh
-
- ../common/weapons/config.qh
- ../common/weapons/weapons.qh // TODO
- weapons/accuracy.qh
- weapons/common.qh
- weapons/csqcprojectile.qh // TODO
- weapons/hitplot.qh
- weapons/selection.qh
- weapons/spawning.qh
- weapons/throwing.qh
- weapons/tracing.qh
- weapons/weaponstats.qh
- weapons/weaponsystem.qh
-
- t_items.qh
-
- autocvars.qh
- constants.qh
- defs.qh // Should rename this, it has fields and globals
-
- ../common/notifications.qh // must be after autocvars
- ../common/deathtypes.qh // must be after notifications
-
- ../common/turrets/config.qh
- ../common/turrets/turrets.qh
- ../common/turrets/sv_turrets.qh
- ../common/turrets/util.qc
-
- mutators/mutators_include.qh
-
- //// tZork Vehicles ////
- vehicles/vehicles_def.qh
-
- campaign.qh
- ../common/campaign_common.qh
- ../common/mapinfo.qh
-
- command/common.qh
- command/banning.qh
- command/radarmap.qh
- command/vote.qh
- command/getreplies.qh
- command/cmd.qh
- command/sv_cmd.qh
-
-
- ../common/csqcmodel_settings.qh
- ../csqcmodellib/common.qh
- ../csqcmodellib/sv_model.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
-
- anticheat.qh
- cheats.qh
- ../common/playerstats.qh
-
- portals.qh
-
- g_hook.qh // TODO
-
- scores.qh
-
- spawnpoints.qh
-
- mapvoting.qh
-
- ipban.qh
-
- race.qh
-
- antilag.qh
-
- playerdemo.qh
-
- round_handler.qh
-
- // singleplayer stuff
- item_key.qh
- secret.qh
-
- scores_rules.qc
-
- miscfunctions.qc
-
- mutators/mutators.qc
-
- waypointsprites.qc
-
- bot/bot.qc
-
+ // ctf.qc
+ // domination.qc
+ ent_cs.qc
+ func_breakable.qc
+ g_casings.qc
+ g_damage.qc
+ g_hook.qc
+ g_models.qc
g_subs.qc
-
g_tetris.qc
-
- //runematch.qc
-
+ g_triggers.qc
g_violence.qc
- g_damage.qc
-
- teamplay.qc
-
- cl_physics.qc
-
- // tZork's libs
- movelib.qc
- steerlib.qc
- pathlib/pathlib.qh
-
g_world.qc
- g_casings.qc
-
+ ipban.qc
+ item_key.qc
mapvoting.qc
-
+ miscfunctions.qc
+ // mode_onslaught.qc
+ movelib.qc
+ // nexball.qc
+ 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
- sv_main.qc
+ bot/bot.qc
- g_triggers.qc
- g_models.qc
+ command/banning.qc
+ command/cmd.qc
+ command/common.qc
+ command/getreplies.qc
+ command/radarmap.qc
+ command/sv_cmd.qc
+ command/vote.qc
- // singleplayer stuff
- item_key.qc
- secret.qc
+ mutators/mutators_include.qc
+ mutators/mutators.qc
weapons/accuracy.qc
weapons/common.qc
weapons/tracing.qc
weapons/weaponstats.qc
weapons/weaponsystem.qc
- ../common/weapons/config.qc
- ../common/weapons/weapons.qc // TODO
- t_items.qc
- cl_impulse.qc
-
- ent_cs.qc
-
- cl_player.qc
- cl_client.qc
- t_plats.qc
- antilag.qc
-
- //ctf.qc
- //domination.qc
- //mode_onslaught.qc
- //nexball.qc
- g_hook.qc
-
- t_swamp.qc
-
- campaign.qc
+ ../common/animdecide.qc
+ ../common/buffs.qc
../common/campaign_file.qc
../common/campaign_setup.qc
- ../common/urllib.qc
-
+ ../common/command/generic.qc
../common/command/markup.qc
../common/command/rpn.qc
- ../common/command/generic.qc
- ../common/net_notice.qc
-
- command/common.qc
- command/banning.qc
- command/radarmap.qc
- command/vote.qc
- command/getreplies.qc
- command/cmd.qc
- command/sv_cmd.qc
-
- //assault.qc
-
- ipban.qc
-
../common/mapinfo.qc
-
- t_quake3.qc
- t_halflife.qc
- t_quake.qc
-
- race.qc
-
-
- //// tZork Vehicles ////
- vehicles/vehicles.qh
-
- scores.qc
-
- spawnpoints.qc
-
- portals.qc
-
- target_spawn.qc
- func_breakable.qc
- target_music.qc
-
+ ../common/monsters/monsters.qc
+ ../common/monsters/spawn.qc
+ ../common/monsters/sv_monsters.qc
../common/nades.qc
- ../common/buffs.qc
-
- ../csqcmodellib/sv_model.qc
-
- playerdemo.qc
-
- anticheat.qc
- cheats.qc
+ ../common/net_notice.qc
+ ../common/notifications.qc
../common/playerstats.qc
-
- round_handler.qc
-
+ ../common/test.qc
+ ../common/urllib.qc
+ ../common/util.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/monsters/sv_monsters.qc
- ../common/monsters/monsters.qc
-
- ../common/monsters/spawn.qc
-
- mutators/mutators_include.qc
+ ../csqcmodellib/sv_model.qc
../warpzonelib/anglestransform.qc
- ../warpzonelib/mathlib.qc
../warpzonelib/common.qc
- ../warpzonelib/util_server.qc
+ ../warpzonelib/mathlib.qc
../warpzonelib/server.qc
-
- ../common/animdecide.qc
- ../common/test.qc
- ../common/util.qc
- ../common/notifications.qc
+ ../warpzonelib/util_server.qc
- #include "tturrets/include/turrets_early.qh"
+ #include "t_teleporters.qh"
+
+ #if defined(CSQC)
+ #elif defined(MENUQC)
+ #elif defined(SVQC)
+ #include "../warpzonelib/common.qh"
+ #include "../warpzonelib/util_server.qh"
+ #include "../warpzonelib/server.qh"
+ #include "../common/constants.qh"
+ #include "../common/util.qh"
+ #include "weapons/csqcprojectile.qh"
+ #include "autocvars.qh"
+ #include "constants.qh"
+ #include "defs.qh"
+ #include "../common/deathtypes.qh"
+ #include "vehicles/vehicles_def.qh"
+ #include "../common/mapinfo.qh"
+ #include "anticheat.qh"
+ #endif
+
void trigger_teleport_use()
{
if(teamplay)
self.team = activator.team;
}
- #define TDEATHLOOP(o) \
- entity head; \
- vector deathmin; \
- vector deathmax; \
- float deathradius; \
- deathmin = (o) + player.mins; \
- deathmax = (o) + player.maxs; \
- if(telefragmin != telefragmax) \
- { \
- if(deathmin_x > telefragmin_x) deathmin_x = telefragmin_x; \
- if(deathmin_y > telefragmin_y) deathmin_y = telefragmin_y; \
- if(deathmin_z > telefragmin_z) deathmin_z = telefragmin_z; \
- if(deathmax_x < telefragmax_x) deathmax_x = telefragmax_x; \
- if(deathmax_y < telefragmax_y) deathmax_y = telefragmax_y; \
- if(deathmax_z < telefragmax_z) deathmax_z = telefragmax_z; \
- } \
- deathradius = max(vlen(deathmin), vlen(deathmax)); \
- for(head = findradius(o, deathradius); head; head = head.chain) \
- if(head != player) \
- if(head.takedamage) \
- if(boxesoverlap(deathmin, deathmax, head.absmin, head.absmax))
-
-
float check_tdeath(entity player, vector org, vector telefragmin, vector telefragmax)
{
if (IS_PLAYER(player) && player.health >= 1)
}
return 0;
}
- float tdeath_hit;
+
void tdeath(entity player, entity teleporter, entity telefragger, vector telefragmin, vector telefragmax)
{
TDEATHLOOP(player.origin)
tdeath(e, e, e, '0 0 0', '0 0 0');
}
- .entity pusher;
- #define TELEPORT_FLAG_SOUND 1
- #define TELEPORT_FLAG_PARTICLES 2
- #define TELEPORT_FLAG_TDEATH 4
- #define TELEPORT_FLAG_FORCE_TDEATH 8
-
- #define TELEPORT_FLAGS_WARPZONE 0
- #define TELEPORT_FLAGS_PORTAL (TELEPORT_FLAG_SOUND | TELEPORT_FLAG_PARTICLES | TELEPORT_FLAG_TDEATH | TELEPORT_FLAG_FORCE_TDEATH)
- #define TELEPORT_FLAGS_TELEPORTER (TELEPORT_FLAG_SOUND | TELEPORT_FLAG_PARTICLES | TELEPORT_FLAG_TDEATH)
-
- // types for .teleportable entity setting
- #define TELEPORT_NORMAL 1 // play sounds/effects etc
- #define TELEPORT_SIMPLE 2 // only do teleport, nothing special
-
- void Reset_ArcBeam(entity player, vector forward);
void TeleportPlayer(entity teleporter, entity player, vector to, vector to_angles, vector to_velocity, vector telefragmin, vector telefragmax, float tflags)
{
entity telefragger;
setorigin (player, to);
player.oldorigin = to; // don't undo the teleport by unsticking
player.angles = to_angles;
- player.fixangle = TRUE;
+ player.fixangle = true;
player.velocity = to_velocity;
BITXOR_ASSIGN(player.effects, EF_TELEPORT_BIT);
p = 1;
if(autocvar_g_telefrags_avoid)
{
- locout = e.origin + '0 0 1' * (1 - player.mins_z - 24);
+ locout = e.origin + '0 0 1' * (1 - player.mins.z - 24);
if(check_tdeath(player, locout, '0 0 0', '0 0 0'))
p = 0;
}
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);
+ 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;
if(!other.vehicle.teleportable)
return;
- if(other.turrcaps_flags & TFL_TURRCAPS_ISTURRET)
+ if(other.turret_flags & TUR_FLAG_ISTURRET)
return;
if(other.deadflag != DEAD_NO)
return world;
}
- entity teleport_first;
- .entity teleport_next;
void spawnfunc_trigger_teleport (void)
{
self.angles = '0 0 0';
+++ /dev/null
--#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.turret_type);
--
- WriteCoord(MSG_ENTITY, self.origin_x);
- WriteCoord(MSG_ENTITY, self.origin_y);
- WriteCoord(MSG_ENTITY, self.origin_z);
- 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);
- 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));
- 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));
- 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.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.velocity.x));
- WriteShort(MSG_ENTITY, rint(self.velocity.y));
- WriteShort(MSG_ENTITY, rint(self.velocity.z));
--
- WriteShort(MSG_ENTITY, rint(self.angles_y));
- 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.tur_health) * 255));
-- }
--
- return TRUE;
- 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_maxrot = 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_rot = cvar(strcat(sbase,"_track_accel_rot"));
-- ent.track_blendrate = cvar(strcat(sbase,"_track_blendrate"));
--
-- if(is_reload)
-- if(ent.turret_respawnhook)
-- ent.turret_respawnhook();
--}
--
--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_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
-- 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();
--}
--
--void turret_projectile_damage(entity inflictor, entity attacker, float damage, float 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_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;
--}
--
--/*
--vector turret_fovsearch_pingpong()
--{
-- vector wish_angle;
-- if(self.phase < time)
-- {
-- if( self.tur_head.phase )
-- self.tur_head.phase = 0;
-- else
-- self.tur_head.phase = 1;
-- self.phase = time + 5;
-- }
--
-- if( self.tur_head.phase)
-- wish_angle = self.idle_aim + '0 1 0' * (self.aim_maxrot * (self.target_select_fov / 360));
-- else
-- wish_angle = self.idle_aim - '0 1 0' * (self.aim_maxrot * (self.target_select_fov / 360));
--
-- return wish_angle;
--}
--
--vector turret_fovsearch_steprot()
--{
-- vector wish_angle;
-- //float rot_add;
--
-- wish_angle = self.tur_head.angles;
-- wish_angle_x = self.idle_aim_x;
--
-- if (self.phase < time)
-- {
-- //rot_add = self.aim_maxrot / self.target_select_fov;
-- wish_angle_y += (self.target_select_fov * 2);
--
-- if(wish_angle_y > 360)
-- wish_angle_y = wish_angle_y - 360;
--
-- self.phase = time + 1.5;
-- }
--
-- return wish_angle;
--}
--
--vector turret_fovsearch_random()
--{
-- vector wish_angle;
--
-- if (self.phase < time)
-- {
-- wish_angle_y = random() * self.aim_maxrot;
-- if(random() < 0.5)
-- wish_angle_y *= -1;
--
-- wish_angle_x = random() * self.aim_maxpitch;
-- if(random() < 0.5)
-- wish_angle_x *= -1;
--
-- self.phase = time + 5;
--
-- self.tur_aimpos = wish_angle;
-- }
--
-- return self.idle_aim + self.tur_aimpos;
--}
--*/
--
--/**
--** Handles head rotation according to
--** the units .track_type and .track_flags
--**/
--.float turret_framecounter;
--void turret_stdproc_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);
- 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 += 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)
- if(self.tur_head.angles.x < -self.aim_maxpitch)
-- self.tur_head.angles_x = self.aim_maxpitch;
-- }
--
-- if (self.track_flags & TFL_TRACK_ROT)
-- {
- self.tur_head.angles_y += bound(-f_tmp, move_angle_y, f_tmp);
- if(self.tur_head.angles_y > self.aim_maxrot)
- self.tur_head.angles_y += bound(-f_tmp, move_angle.y, f_tmp);
- if(self.tur_head.angles.y > self.aim_maxrot)
-- self.tur_head.angles_y = self.aim_maxrot;
--
- if(self.tur_head.angles_y < -self.aim_maxrot)
- if(self.tur_head.angles.y < -self.aim_maxrot)
-- self.tur_head.angles_y = self.aim_maxrot;
-- }
--
-- // 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_rot * f_tmp, self.aim_speed);
- 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_rot * 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);
- 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 = 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)
- 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_ROT)
-- {
- self.tur_head.avelocity_y = move_angle_y;
- self.tur_head.avelocity_y = move_angle.y;
--
- if((self.tur_head.angles_y + self.tur_head.avelocity_y * self.ticrate) > self.aim_maxrot)
- if((self.tur_head.angles.y + self.tur_head.avelocity.y * self.ticrate) > self.aim_maxrot)
-- {
-- self.tur_head.avelocity_y = 0;
-- self.tur_head.angles_y = self.aim_maxrot;
--
-- self.SendFlags |= TNSF_ANG;
-- }
--
- if((self.tur_head.angles_y + self.tur_head.avelocity_y * self.ticrate) < -self.aim_maxrot)
- if((self.tur_head.angles.y + self.tur_head.avelocity.y * self.ticrate) < -self.aim_maxrot)
-- {
-- self.tur_head.avelocity_y = 0;
-- self.tur_head.angles_y = -self.aim_maxrot;
--
-- 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;
-- }
--}
--
--
--/*
-- + = 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_OWM_AMMO
-- + TFL_FIRECHECK_OTHER_AMMO
-- + TFL_FIRECHECK_REFIRE
--*/
--
--/**
--** Preforms pre-fire checks based on the uints firecheck_flags
--**/
--float turret_stdproc_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_OWM_AMMO)
-- if (self.ammo < self.shot_dmg)
-- return 0;
--
-- // Other's ammo? (support-supply units)
-- if (self.firecheck_flags & TFL_FIRECHECK_OTHER_AMMO)
-- 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;
--}
--
--/*
-- + TFL_TARGETSELECT_NO
-- + TFL_TARGETSELECT_LOS
-- + TFL_TARGETSELECT_PLAYERS
-- + TFL_TARGETSELECT_MISSILES
-- - TFL_TARGETSELECT_TRIGGERTARGET
-- + TFL_TARGETSELECT_ANGLELIMITS
-- + TFL_TARGETSELECT_RANGELIMTS
-- + 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.owner == e_turret)
-- return -0.5;
--
-- if (!checkpvs(e_target.origin, e_turret))
-- return -1;
--
-- if (!e_target)
-- return -2;
--
-- 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_target.vehicle_flags & VHF_ISVEHICLE)
-- {
-- if (e_target.vehicle_health <= 0)
-- return -6;
-- }
-- else if (e_target.health <= 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.turret_firefunc || 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_RANGELIMTS)
-- {
-- 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)
- if (fabs(tvt_tadv.x) > e_turret.aim_maxpitch)
-- return -17;
--
- if (fabs(tvt_tadv_y) > e_turret.aim_maxrot)
- if (fabs(tvt_tadv.y) > e_turret.aim_maxrot)
-- 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;
--}
--
--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_stdproc_respawn();
-- }
--
--#ifdef TURRET_DEBUG
-- if (self.tur_dbg_tmr1 < time)
-- {
-- if (self.enemy) paint_target (self.enemy,128,self.tur_dbg_rvec,0.9);
-- paint_target(self,256,self.tur_dbg_rvec,0.9);
-- self.tur_dbg_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_stdproc_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_stdproc_aim_generic();
--
-- // Turn & pitch?
-- if (!(self.track_flags & TFL_TRACK_NO))
-- turret_stdproc_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_stdproc_aim_generic();
--
-- // Turn & pitch
-- if (!(self.track_flags & TFL_TRACK_NO))
-- turret_stdproc_track();
--
-- turret_do_updates(self);
--
-- // Fire!
-- if (self.turret_firecheckfunc() != 0)
-- turret_fire();
--
-- if(self.turret_postthink)
-- self.turret_postthink();
--
-- 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_stdproc_track();
--
-- // do any per-turret stuff
-- if(self.turret_postthink)
-- self.turret_postthink();
--
-- // 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_stdproc_aim_generic();
--
-- // Turn & pitch?
-- if (!(self.track_flags & TFL_TRACK_NO))
-- turret_stdproc_track();
--
-- turret_do_updates(self);
--
-- // Fire?
-- if (self.turret_firecheckfunc())
-- turret_fire();
-- }
--
-- // do any custom per-turret stuff
-- if(self.turret_postthink)
-- self.turret_postthink();
--}
--
--void turret_fire()
--{
-- if (autocvar_g_turrets_nofire != 0)
-- return;
--
-- self.turret_firefunc();
--
-- 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_dbg_rvec, self.tur_impacttime + 0.25);
--#endif
--}
--
--void turret_stdproc_fire()
--{
-- dprint("^1Bang, ^3your dead^7 ",self.enemy.netname,"! ^1(turret with no real firefunc)\n");
--}
--
--/*
-- When .used a turret switch team to activator.team.
-- If activator is world, the turret go inactive.
--*/
--void turret_stdproc_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);
- 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 (e.turrcaps_flags & TFL_TURRCAPS_ISTURRET)
-- {
-- load_unit_settings(e,e.cvar_basename,1);
-- if(e.turret_postthink)
-- e.turret_postthink();
-- }
--
-- e = nextent(e);
-- }
-- cvar_set("g_turrets_reloadcvars","0");
-- }
--}
--
--/*
--* Standard turret initialization. use this!
--* (unless you have a very good reason not to)
--* if the return value is 0, the turret should be removed.
--*/
--float turret_stdproc_init (string cvar_base_name, string base, string head, float _turret_type)
--{
-- entity e, ee = world;
--
-- // Are turrets allowed?
-- if (autocvar_g_turrets == 0)
-- return 0;
--
-- if(_turret_type < 1 || _turret_type > TID_LAST)
-- {
-- dprint("Invalid / Unkown turret type\"", ftos(_turret_type), "\", aborting!\n");
-- return 0;
-- }
-- self.turret_type = _turret_type;
--
-- 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(); // why can't we use regular droptofloor here?
--
-- // Terrainbase spawnflag. This puts a enlongated model
-- // under the turret, so it looks ok on uneaven surfaces.
-- /* TODO: Handle this with CSQC
-- if (self.spawnflags & TSF_TERRAINBASE)
-- {
-- entity tb;
-- tb = spawn();
-- setmodel(tb,"models/turrets/terrainbase.md3");
-- setorigin(tb,self.origin);
-- tb.solid = SOLID_BBOX;
-- }
-- */
--
-- self.cvar_basename = cvar_base_name;
-- load_unit_settings(self, self.cvar_basename, 0);
--
-- self.effects = EF_NODRAW;
--
-- // Handle turret teams.
-- if (!teamplay)
-- self.team = MAX_SHOT_DISTANCE; // Group all turrets into the same team, so they dont kill eachother.
-- else if(g_onslaught && self.targetname)
-- {
-- e = find(world,target,self.targetname);
-- if(e != world)
-- {
-- self.team = e.team;
-- ee = e;
-- }
-- }
-- else if(!self.team)
-- self.team = MAX_SHOT_DISTANCE; // Group all turrets into the same team, so they dont kill eachother.
--
-- /*
-- * Try to guess some reasonaly defaults
-- * for missing params and do sanety checks
-- * thise checks could produce some "interesting" results
-- * if it hits a glitch in my logic :P so try to set as mutch
-- * as possible beforehand.
-- */
-- if (!self.ticrate)
-- {
-- if (self.turrcaps_flags & TFL_TURRCAPS_SUPPORT)
-- self.ticrate = 0.2; // Support units generaly dont need to have a high speed ai-loop
-- else
-- self.ticrate = 0.1; // 10 fps for normal turrets
-- }
--
-- self.ticrate = bound(sys_frametime, self.ticrate, 60); // keep it sane
--
--// General stuff
-- if (self.netname == "")
-- self.netname = self.classname;
--
-- if (!self.respawntime)
-- self.respawntime = 60;
-- self.respawntime = max(-1, self.respawntime);
--
-- if (!self.health)
-- self.health = 1000;
-- self.tur_health = max(1, self.health);
- self.bot_attack = TRUE;
- self.monster_attack = TRUE;
- self.bot_attack = true;
- self.monster_attack = true;
--
-- if (!self.turrcaps_flags)
-- self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_MEDPROJ | TFL_TURRCAPS_PLAYERKILL;
--
-- if (!self.damage_flags)
-- self.damage_flags = TFL_DMG_YES | TFL_DMG_RETALIATE | TFL_DMG_AIMSHAKE;
--
--// Shot stuff.
-- if (!self.shot_refire)
-- self.shot_refire = 1;
-- self.shot_refire = bound(0.01, self.shot_refire, 9999);
--
-- if (!self.shot_dmg)
-- self.shot_dmg = self.shot_refire * 50;
-- self.shot_dmg = max(1, self.shot_dmg);
--
-- if (!self.shot_radius)
-- self.shot_radius = self.shot_dmg * 0.5;
-- self.shot_radius = max(1, self.shot_radius);
--
-- if (!self.shot_speed)
-- self.shot_speed = 2500;
-- self.shot_speed = max(1, self.shot_speed);
--
-- if (!self.shot_spread)
-- self.shot_spread = 0.0125;
-- self.shot_spread = bound(0.0001, self.shot_spread, 500);
--
-- if (!self.shot_force)
-- self.shot_force = self.shot_dmg * 0.5 + self.shot_radius * 0.5;
-- self.shot_force = bound(0.001, self.shot_force, 5000);
--
-- if (!self.shot_volly)
-- self.shot_volly = 1;
-- self.shot_volly = bound(1, self.shot_volly, floor(self.ammo_max / self.shot_dmg));
--
-- if (!self.shot_volly_refire)
-- self.shot_volly_refire = self.shot_refire * self.shot_volly;
-- self.shot_volly_refire = bound(self.shot_refire, self.shot_volly_refire, 60);
--
-- if (!self.firecheck_flags)
-- self.firecheck_flags = TFL_FIRECHECK_DEAD | TFL_FIRECHECK_DISTANCES |
-- TFL_FIRECHECK_LOS | TFL_FIRECHECK_AIMDIST | TFL_FIRECHECK_TEAMCECK |
-- TFL_FIRECHECK_OWM_AMMO | TFL_FIRECHECK_REFIRE;
--
--// Range stuff.
-- if (!self.target_range)
-- self.target_range = self.shot_speed * 0.5;
-- self.target_range = bound(0, self.target_range, MAX_SHOT_DISTANCE);
--
-- if (!self.target_range_min)
-- self.target_range_min = self.shot_radius * 2;
-- self.target_range_min = bound(0, self.target_range_min, MAX_SHOT_DISTANCE);
--
-- if (!self.target_range_optimal)
-- self.target_range_optimal = self.target_range * 0.5;
-- self.target_range_optimal = bound(0, self.target_range_optimal, MAX_SHOT_DISTANCE);
--
--
--// Aim stuff.
-- if (!self.aim_maxrot)
-- self.aim_maxrot = 90;
-- self.aim_maxrot = bound(0, self.aim_maxrot, 360);
--
-- if (!self.aim_maxpitch)
-- self.aim_maxpitch = 20;
-- self.aim_maxpitch = bound(0, self.aim_maxpitch, 90);
--
-- if (!self.aim_speed)
-- self.aim_speed = 36;
-- self.aim_speed = bound(0.1, self.aim_speed, 1000);
--
-- if (!self.aim_firetolerance_dist)
-- self.aim_firetolerance_dist = 5 + (self.shot_radius * 2);
-- self.aim_firetolerance_dist = bound(0.1, self.aim_firetolerance_dist, MAX_SHOT_DISTANCE);
--
-- if (!self.aim_flags)
-- {
-- self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
-- if(self.turrcaps_flags & TFL_TURRCAPS_RADIUSDMG)
-- self.aim_flags |= TFL_AIM_GROUNDGROUND;
-- }
--
-- if (!self.track_type)
-- self.track_type = TFL_TRACKTYPE_STEPMOTOR;
--
-- if (self.track_type != TFL_TRACKTYPE_STEPMOTOR)
-- {
-- // Fluid / Ineria mode. Looks mutch nicer.
-- // Can reduce aim preformance alot, needs a bit diffrent aimspeed
--
-- if (!self.aim_speed)
-- self.aim_speed = 180;
-- self.aim_speed = bound(0.1, self.aim_speed, 1000);
--
-- if (!self.track_accel_pitch)
-- self.track_accel_pitch = 0.5;
--
-- if (!self.track_accel_rot)
-- self.track_accel_rot = 0.5;
--
-- if (!self.track_blendrate)
-- self.track_blendrate = 0.35;
-- }
--
-- if (!self.track_flags)
-- self.track_flags = TFL_TRACK_PITCH | TFL_TRACK_ROT;
--
--
--// Target selection stuff.
-- if (!self.target_select_rangebias)
-- self.target_select_rangebias = 1;
-- self.target_select_rangebias = bound(-10, self.target_select_rangebias, 10);
--
-- if (!self.target_select_samebias)
-- self.target_select_samebias = 1;
-- self.target_select_samebias = bound(-10, self.target_select_samebias, 10);
--
-- if (!self.target_select_anglebias)
-- self.target_select_anglebias = 1;
-- self.target_select_anglebias = bound(-10, self.target_select_anglebias, 10);
--
-- if (!self.target_select_missilebias)
-- self.target_select_missilebias = -10;
--
-- self.target_select_missilebias = bound(-10, self.target_select_missilebias, 10);
-- self.target_select_playerbias = bound(-10, self.target_select_playerbias, 10);
--
-- if (!self.target_select_flags)
-- {
-- self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_TEAMCHECK
-- | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_ANGLELIMITS;
--
-- if (self.turrcaps_flags & TFL_TURRCAPS_MISSILEKILL)
-- self.target_select_flags |= TFL_TARGETSELECT_MISSILES;
--
-- if (self.turrcaps_flags & TFL_TURRCAPS_PLAYERKILL)
-- self.target_select_flags |= TFL_TARGETSELECT_PLAYERS;
-- //else
-- // self.target_select_flags = TFL_TARGETSELECT_NO;
-- }
--
-- self.target_validate_flags = self.target_select_flags;
--
--// Ammo stuff
-- if (!self.ammo_max)
-- self.ammo_max = self.shot_dmg * 10;
-- self.ammo_max = max(self.shot_dmg, self.ammo_max);
--
-- if (!self.ammo)
-- self.ammo = self.shot_dmg * 5;
-- self.ammo = bound(0,self.ammo, self.ammo_max);
--
-- if (!self.ammo_recharge)
-- self.ammo_recharge = self.shot_dmg * 0.5;
-- self.ammo_recharge = max(0 ,self.ammo_recharge);
--
-- // Convert the recharge from X per sec to X per ticrate
-- self.ammo_recharge = self.ammo_recharge * self.ticrate;
--
-- if (!self.ammo_flags)
-- self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE;
--
--// Damage stuff
-- if(self.spawnflags & TSL_NO_RESPAWN)
-- if (!(self.damage_flags & TFL_DMG_DEATH_NORESPAWN))
-- self.damage_flags |= TFL_DMG_DEATH_NORESPAWN;
--
--// Offsets & origins
-- if (!self.tur_shotorg) self.tur_shotorg = '50 0 50';
--
-- if (!self.health)
-- self.health = 150;
--
--// Game hooks
-- if(MUTATOR_CALLHOOK(TurretSpawn))
-- return 0;
--
--// End of default & sanety checks, start building the turret.
--
--// Spawn extra bits
-- self.tur_head = spawn();
-- self.tur_head.netname = self.tur_head.classname = "turret_head";
-- self.tur_head.team = self.team;
-- self.tur_head.owner = self;
--
-- setmodel(self, base);
-- setmodel(self.tur_head, head);
--
-- setsize(self, '-32 -32 0', '32 32 64');
-- 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_health = self.health;
-- self.solid = SOLID_BBOX;
-- self.tur_head.solid = SOLID_NOT;
-- self.takedamage = DAMAGE_AIM;
-- self.tur_head.takedamage = DAMAGE_NO;
-- self.movetype = MOVETYPE_NOCLIP;
-- self.tur_head.movetype = MOVETYPE_NOCLIP;
--
-- // Defend mode?
-- 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");
-- }
-- }
--
-- // In target defend mode, aim on the spot to defend when idle.
-- 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';
--
-- // Attach stdprocs. override when and what needed
-- self.turret_firecheckfunc = turret_stdproc_firecheck;
-- self.turret_firefunc = turret_stdproc_fire;
-- self.event_damage = turret_stdproc_damage;
--
-- if (self.turrcaps_flags & TFL_TURRCAPS_SUPPORT)
-- self.turret_score_target = turret_stdproc_targetscore_support;
-- else
-- self.turret_score_target = turret_stdproc_targetscore_generic;
--
-- self.use = turret_stdproc_use;
--
-- ++turret_count;
-- self.nextthink = time + 1;
-- self.nextthink += turret_count * sys_frametime;
--
-- self.tur_head.team = self.team;
-- self.view_ofs = '0 0 0';
--
--#ifdef TURRET_DEBUG
-- self.tur_dbg_start = self.nextthink;
-- while (vlen(self.tur_dbg_rvec) < 2)
-- self.tur_dbg_rvec = randomvec() * 4;
--
- self.tur_dbg_rvec_x = fabs(self.tur_dbg_rvec_x);
- self.tur_dbg_rvec_y = fabs(self.tur_dbg_rvec_y);
- self.tur_dbg_rvec_z = fabs(self.tur_dbg_rvec_z);
- self.tur_dbg_rvec_x = fabs(self.tur_dbg_rvec.x);
- self.tur_dbg_rvec_y = fabs(self.tur_dbg_rvec.y);
- self.tur_dbg_rvec_z = fabs(self.tur_dbg_rvec.z);
--#endif
--
-- // Its all good.
-- self.turrcaps_flags |= TFL_TURRCAPS_ISTURRET;
--
-- self.classname = "turret_main";
--
-- self.active = ACTIVE_ACTIVE;
--
-- // In ONS mode, and linked to a ONS ent. need to call the use to set team.
-- if (g_onslaught && ee)
-- {
-- activator = ee;
-- self.use();
-- }
--
-- turret_link();
-- turret_stdproc_respawn();
-- turret_tag_fire_update();
--
-- return 1;
--}
--
--
+++ /dev/null
- #define ewheel_amin_stop 0
- #define ewheel_amin_fwd_slow 1
- #define ewheel_amin_fwd_fast 2
- #define ewheel_amin_bck_slow 3
- #define ewheel_amin_bck_fast 4
-const float ewheel_amin_stop = 0;
-const float ewheel_amin_fwd_slow = 1;
-const float ewheel_amin_fwd_fast = 2;
-const float ewheel_amin_bck_slow = 3;
-const float ewheel_amin_bck_fast = 4;
--
--void ewheel_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); // WEAPONTODO: this is not a projectile made by the blaster, add separate effect for it
- _mis = turret_projectile("weapons/lasergun_fire.wav", 1, 0, DEATH_TURRET_EWHEEL, PROJECTILE_BLASTER, true, true); // WEAPONTODO: this is not a projectile made by the blaster, add separate effect for it
-- _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;
-- }
--
--}
--//#define EWHEEL_FANCYPATH
--void ewheel_move_path()
--{
--#ifdef EWHEEL_FANCYPATH
-- // 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 (vlen(self.origin - self.pathcurrent.origin) < 64)
-- self.pathcurrent = self.pathcurrent.enemy;
--#endif
--
-- if (self.pathcurrent)
-- {
--
-- self.moveto = self.pathcurrent.origin;
-- self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
--
-- movelib_move_simple(v_forward, autocvar_g_turrets_unit_ewheel_speed_fast, 0.4);
-- }
--}
--
--void ewheel_move_enemy()
--{
--
-- float newframe;
--
-- self.steerto = steerlib_arrive(self.enemy.origin,self.target_range_optimal);
--
-- //self.steerto = steerlib_standoff(self.enemy.origin,self.target_range_optimal);
-- //self.steerto = steerlib_beamsteer(self.steerto,1024,64,68,256);
-- self.moveto = self.origin + self.steerto * 128;
--
-- if (self.tur_dist_enemy > self.target_range_optimal)
-- {
-- if ( self.tur_head.spawnshieldtime < 1 )
-- {
-- newframe = ewheel_amin_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_amin_fwd_slow;
-- movelib_move_simple(v_forward, autocvar_g_turrets_unit_ewheel_speed_slow, 0.4);
-- }
-- else
-- {
-- newframe = ewheel_amin_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_amin_bck_slow;
-- movelib_move_simple(v_forward * -1, autocvar_g_turrets_unit_ewheel_speed_slow, 0.4);
-- }
-- else
-- {
-- newframe = ewheel_amin_stop;
-- movelib_beak_simple(autocvar_g_turrets_unit_ewheel_speed_stop);
-- }
--
- turrets_setframe(newframe , FALSE);
- turrets_setframe(newframe , false);
--
-- /*if(self.frame != newframe)
-- {
-- self.frame = newframe;
-- self.SendFlags |= TNSF_ANIM;
-- self.anim_start_time = time;
-- }*/
--}
--
--
--void ewheel_move_idle()
--{
-- 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 ewheel_postthink()
--{
-- float vz;
-- vector wish_angle, real_angle;
--
- vz = self.velocity_z;
- vz = self.velocity.z;
--
- self.angles_x = anglemods(self.angles_x);
- self.angles_y = anglemods(self.angles_y);
- 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);
- 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;
--}
--
--void ewheel_respawnhook()
--{
-- 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)
-- return;
--
-- 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 = WALKER_PATH(self.origin,e.origin);
-- self.pathgoal = e;
--#else
-- self.pathcurrent = e;
--#endif
-- }
-- }
--}
--
--void ewheel_diehook()
--{
-- self.velocity = '0 0 0';
--
--#ifdef EWHEEL_FANCYPATH
-- if (self.pathcurrent)
-- pathlib_deletepath(self.pathcurrent.owner);
--#endif
-- self.pathcurrent = world;
--}
--
--void turret_ewheel_dinit()
--{
-- entity e;
--
-- if (self.netname == "")
-- self.netname = "eWheel Turret";
--
-- if (self.target != "")
-- {
-- e = find(world,targetname,self.target);
-- if (!e)
-- {
-- bprint("Warning! initital waypoint for ewheel does NOT exsist!\n");
-- self.target = "";
-- }
--
-- if (e.classname != "turret_checkpoint")
-- dprint("Warning: not a turrret path\n");
-- else
-- self.goalcurrent = e;
-- }
--
-- self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
-- self.turrcaps_flags = TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_MOVE | TFL_TURRCAPS_ROAM ;
-- self.turret_respawnhook = ewheel_respawnhook;
--
-- self.turret_diehook = ewheel_diehook;
--
-- if (turret_stdproc_init("ewheel_std", "models/turrets/ewheel-base2.md3", "models/turrets/ewheel-gun1.md3", TID_EWHEEL) == 0)
-- {
-- remove(self);
-- return;
-- }
--
-- self.frame = 1;
-- self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
-- self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
- self.iscreature = TRUE;
- self.iscreature = true;
-- self.teleportable = TELEPORT_NORMAL;
- self.damagedbycontents = TRUE;
- 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;
--
-- setsize(self, '-32 -32 0', '32 32 48');
--
-- // Our fire routine
-- self.turret_firefunc = ewheel_attack;
-- self.turret_postthink = ewheel_postthink;
-- self.tur_head.frame = 1;
--
-- // 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);
--
-- //setorigin(self,self.origin + '0 0 128');
-- 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 = WALKER_PATH(self.origin, e.origin);
-- self.pathgoal = e;
--#else
-- self.pathcurrent = e;
--#endif
-- }
-- }
--}
--
--void spawnfunc_turret_ewheel()
--{
-- g_turrets_common_precash();
--
-- precache_model ("models/turrets/ewheel-base2.md3");
-- precache_model ("models/turrets/ewheel-gun1.md3");
--
-- self.think = turret_ewheel_dinit;
-- self.nextthink = time + 0.5;
--}
+++ /dev/null
--void spawnfunc_turret_flac();
--void turret_flac_dinit();
--void turret_flac_attack();
--
--void turret_flac_projectile_think_explode()
--{
-- 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
-- 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
-- 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
-- remove(self);
--}
--
--void turret_flac_attack()
--{
-- entity proj;
--
-- turret_tag_fire_update();
--
- proj = turret_projectile("weapons/hagar_fire.wav", 5, 0, DEATH_TURRET_FLAC, PROJECTILE_HAGAR, TRUE, TRUE);
- 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;
--
-- self.tur_head.frame = self.tur_head.frame + 1;
-- if (self.tur_head.frame >= 4)
-- self.tur_head.frame = 0;
--
--}
--
--void turret_flac_dinit()
--{
-- if (self.netname == "")
-- self.netname = "FLAC Cannon";
--
-- self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_FASTPROJ | TFL_TURRCAPS_MISSILEKILL;
-- self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
-- self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
--
-- if (turret_stdproc_init("flac_std", "models/turrets/base.md3", "models/turrets/flac.md3", TID_FLAC) == 0)
-- {
-- remove(self);
-- return;
-- }
-- setsize(self.tur_head,'-32 -32 0','32 32 64');
--
-- self.damage_flags |= TFL_DMG_HEADSHAKE;
-- self.target_select_flags |= TFL_TARGETSELECT_NOTURRETS | TFL_TARGETSELECT_MISSILESONLY;
--
-- // Our fire routine
-- self.turret_firefunc = turret_flac_attack;
--
--}
--/*QUAKED turret_flac (0 .5 .8) ?
--*/
--
--void spawnfunc_turret_flac()
--{
-- precache_model ("models/turrets/base.md3");
-- precache_model ("models/turrets/flac.md3");
--
-- self.think = turret_flac_dinit;
-- self.nextthink = time + 0.5;
--}
--
+++ /dev/null
--void spawnfunc_turret_machinegun();
--void turret_machinegun_std_init();
--void turret_machinegun_attack();
--
--//.float bulletcounter;
--void turret_machinegun_attack()
--{
-- fireBullet (self.tur_shotorg, self.tur_shotdir_updated,self.shot_spread, 0, self.shot_dmg, self.shot_force, DEATH_TURRET_MACHINEGUN, 0);
--
-- W_MachineGun_MuzzleFlash(); // WEAPONTODO
-- setattachment(self.muzzle_flash, self.tur_head, "tag_fire");
--}
--
--
--void turret_machinegun_std_init()
--{
-- if (self.netname == "") self.netname = "Machinegun Turret";
--
-- self.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
-- self.turrcaps_flags = TFL_TURRCAPS_PLAYERKILL;
-- self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
--
-- self.turrcaps_flags |= TFL_TURRCAPS_HITSCAN;
--
-- if (turret_stdproc_init("machinegun_std", "models/turrets/base.md3", "models/turrets/machinegun.md3", TID_MACHINEGUN) == 0)
-- {
-- remove(self);
-- return;
-- }
--
-- self.damage_flags |= TFL_DMG_HEADSHAKE;
-- self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK;
--
-- // Our fire routine
-- self.turret_firefunc = turret_machinegun_attack;
--
--}
--
--
--/*QUAKED turret_machinegun (0 .5 .8) ?
--* machinegun turret. does what you'd expect
--*/
--void spawnfunc_turret_machinegun()
--{
-- precache_model ("models/turrets/machinegun.md3");
-- precache_model ("models/turrets/base.md3");
-- precache_sound ("weapons/uzi_fire.wav");
--
-- self.think = turret_machinegun_std_init;
-- self.nextthink = time + 0.5;
--}
--
+++ /dev/null
--void spawnfunc_turret_plasma();
--void spawnfunc_turret_plasma_dual();
--
--void turret_plasma_std_init();
--void turret_plasma_dual_init();
--
--void turret_plasma_attack();
--
--
--void turret_plasma_postthink()
--{
-- 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;
--}
--
--void turret_plasma_dual_postthink()
--{
-- 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;
--}
--
--void turret_plasma_minsta_attack (void)
--{
-- 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;
-- v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
-- if(teamplay)
-- {
-- switch(self.team)
-- {
-- case NUM_TEAM_1: // Red
-- WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3RED"), self.tur_shotorg, v);
-- break;
-- case NUM_TEAM_2: // Blue
-- WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3BLUE"), self.tur_shotorg, v);
-- break;
-- case NUM_TEAM_3: // Yellow
-- WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3YELLOW"), self.tur_shotorg, v);
-- break;
-- case NUM_TEAM_4: // Pink
-- WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3PINK"), self.tur_shotorg, v);
-- break;
-- }
-- }
-- else
-- WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3"), self.tur_shotorg, v);
-- if (self.tur_head.frame == 0)
-- self.tur_head.frame = 1;
--}
--
--void turret_plasma_attack()
--{
- entity missile = turret_projectile("weapons/hagar_fire.wav", 1, 0, DEATH_TURRET_PLASMA, PROJECTILE_ELECTRO_BEAM, TRUE, TRUE);
- 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;
--}
--
--void turret_plasma_dual_attack()
--{
- entity missile = turret_projectile("weapons/hagar_fire.wav", 1, 0, DEATH_TURRET_PLASMA, PROJECTILE_ELECTRO_BEAM, TRUE, TRUE);
- 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;
--}
--
--void turret_plasma_std_init()
--{
-- if (self.netname == "") self.netname = "Plasma Cannon";
--
-- // What ammo to use
-- self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
--
-- // How to aim
-- self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_GROUNDGROUND;
-- self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_MEDPROJ | TFL_TURRCAPS_PLAYERKILL;
--
-- if (turret_stdproc_init("plasma_std", "models/turrets/base.md3", "models/turrets/plasma.md3", TID_PLASMA) == 0)
-- {
-- remove(self);
-- return;
-- }
--
-- self.damage_flags |= TFL_DMG_HEADSHAKE;
-- self.firecheck_flags |= TFL_FIRECHECK_AFF;
--
-- // Our fireing routine
-- if(g_instagib)
-- self.turret_firefunc = turret_plasma_minsta_attack;
-- else
-- self.turret_firefunc = turret_plasma_attack;
--
-- // Custom per turret frame stuff. usualy animation.
-- self.turret_postthink = turret_plasma_postthink;
-- turret_do_updates(self);
--}
--
--
--void turret_plasma_dual_init()
--{
-- if (self.netname == "") self.netname = "Dual Plasma Cannon";
--
-- // What ammo to use
-- self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
--
-- // How to aim at targets
-- self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_GROUNDGROUND ;
-- self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_MEDPROJ | TFL_TURRCAPS_PLAYERKILL;
--
-- if (turret_stdproc_init("plasma_dual", "models/turrets/base.md3", "models/turrets/plasmad.md3", TID_PLASMA_DUAL) == 0)
-- {
-- remove(self);
-- return;
-- }
--
-- self.damage_flags |= TFL_DMG_HEADSHAKE;
-- self.firecheck_flags |= TFL_FIRECHECK_AFF;
--
-- // Our fireing routine
-- self.turret_firefunc = turret_plasma_dual_attack;
--
-- // Custom per turret frame stuff. usualy animation.
-- self.turret_postthink = turret_plasma_dual_postthink;
--}
--
--
--/*
--* Basic moderate (std) or fast (dual) fireing, short-mid range energy cannon.
--* Not too mutch of a therat on its own, but can be rather dangerous in groups.
--* Regenerates ammo slowly, support with a fusionreactor(s) to do some real damage.
--*/
--
--/*QUAKED turret_plasma (0 .5 .8) ?
--*/
--void spawnfunc_turret_plasma()
--{
-- g_turrets_common_precash();
-- precache_model ("models/turrets/plasma.md3");
-- precache_model ("models/turrets/base.md3");
--
-- self.think = turret_plasma_std_init;
-- self.nextthink = time + 0.5;
--}
--
--/*QUAKED turret_plasma_dual (0 .5 .8) ?
--*/
--void spawnfunc_turret_plasma_dual()
--{
--
-- precache_model ("models/turrets/plasmad.md3");
-- precache_model ("models/turrets/base.md3");
--
-- self.think = turret_plasma_dual_init;
-- self.nextthink = time + 0.5;
--}
--
+++ /dev/null
- #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_MEELE 9
- #define ANIM_SWIM 10
- #define ANIM_ROAM 11
-const float ANIM_NO = 0;
-const float ANIM_TURN = 1;
-const float ANIM_WALK = 2;
-const float ANIM_RUN = 3;
-const float ANIM_STRAFE_L = 4;
-const float ANIM_STRAFE_R = 5;
-const float ANIM_JUMP = 6;
-const float ANIM_LAND = 7;
-const float ANIM_PAIN = 8;
-const float ANIM_MEELE = 9;
-const float ANIM_SWIM = 10;
-const float ANIM_ROAM = 11;
--.float animflag;
--
- #define WALKER_MIN '-70 -70 0'
- #define WALKER_MAX '70 70 95'
-const vector WALKER_MIN = '-70 -70 0';
-const vector WALKER_MAX = '70 70 95';
--
--#define WALKER_PATH(s,e) pathlib_astar(s,e)
--
--float walker_firecheck()
--{
-- if (self.animflag == ANIM_MEELE)
-- return 0;
--
-- return turret_stdproc_firecheck();
--}
--
--void walker_meele_do_dmg()
--{
-- vector where;
-- entity e;
--
-- makevectors(self.angles);
-- where = self.origin + v_forward * 128;
--
-- 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_std_meele_dmg, DEATH_TURRET_WALK_MEELE, '0 0 0', v_forward * autocvar_g_turrets_unit_walker_std_meele_force);
--
-- e = e.chain;
-- }
--}
--
--void walker_setnoanim()
--{
- turrets_setframe(ANIM_NO, FALSE);
- turrets_setframe(ANIM_NO, false);
-- self.animflag = self.frame;
--}
--void walker_rocket_explode()
--{
-- RadiusDamage (self, self.owner, autocvar_g_turrets_unit_walker_std_rocket_dmg, 0, autocvar_g_turrets_unit_walker_std_rocket_radius, self, world, autocvar_g_turrets_unit_walker_std_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)
--{
-- self.health = self.health - damage;
-- self.velocity = self.velocity + vforce;
--
-- if (self.health <= 0)
-- W_PrepareExplosionByDamage(self.owner, walker_rocket_explode);
--}
--
--#define WALKER_ROCKET_MOVE movelib_move_simple(newdir, autocvar_g_turrets_unit_walker_std_rocket_speed, autocvar_g_turrets_unit_walker_std_rocket_turnrate); UpdateCSQCProjectile(self)
--void walker_rocket_loop();
--void walker_rocket_think()
--{
-- 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.tur_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()
--{
-- vector newdir;
-- self.nextthink = time;
--
-- if (self.tur_health < time)
-- {
-- self.think = walker_rocket_explode;
-- return;
-- }
--
-- if (vlen(self.origin - self.tur_shotorg) < 100 )
-- {
-- self.think = walker_rocket_think;
-- return;
-- }
--
-- newdir = steerlib_pull(self.tur_shotorg);
-- WALKER_ROCKET_MOVE;
--
-- self.angles = vectoangles(self.velocity);
--}
--
--void walker_rocket_loop2()
--{
-- vector newdir;
--
-- self.nextthink = time;
--
-- if (self.tur_health < time)
-- {
-- self.think = walker_rocket_explode;
-- return;
-- }
--
-- if (vlen(self.origin - self.tur_shotorg) < 100 )
-- {
-- self.tur_shotorg = self.origin - '0 0 200';
-- self.think = walker_rocket_loop3;
-- return;
-- }
--
-- newdir = steerlib_pull(self.tur_shotorg);
-- WALKER_ROCKET_MOVE;
--}
--
--void walker_rocket_loop()
--{
-- 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)
--{
-- 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_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_std_rocket_speed;
-- rocket.angles = vectoangles(rocket.velocity);
-- rocket.touch = walker_rocket_explode;
-- rocket.flags = FL_PROJECTILE;
-- rocket.solid = SOLID_BBOX;
-- rocket.tur_health = time + 9;
-- rocket.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_GUIDED_HEAT;
--
- CSQCProjectile(rocket, FALSE, PROJECTILE_ROCKET, FALSE); // no culling, has fly sound
- 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)
--{
-- 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
-- // 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 (vlen(self.origin - self.pathcurrent.origin) < 64)
-- self.pathcurrent = self.pathcurrent.enemy;
--
-- if(!self.pathcurrent)
-- return;
--
-- self.moveto = self.pathcurrent.origin;
-- self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
-- walker_move_to(self.moveto, 0);
--#endif
--}
--
--.float idletime;
--void walker_postthink()
--{
-- 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;
- 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_std_meele_range && self.animflag != ANIM_MEELE)
-- {
-- vector wish_angle;
--
-- wish_angle = angleofs(self, self.enemy);
-- if (self.animflag != ANIM_SWIM)
- if (fabs(wish_angle_y) < 15)
- 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_MEELE;
-- }
-- }
-- 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_std_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_std_rockets_range_min)
-- if (self.tur_dist_enemy < autocvar_g_turrets_unit_walker_std_rockets_range)
-- self.tur_head.shot_volly = 4;
-- }
-- }
-- else
-- {
-- if (self.animflag != ANIM_MEELE)
-- walker_move_to(self.enemy.origin, self.tur_dist_enemy);
-- }
-- }
--
-- //if(self.animflag != ANIM_NO)
-- {
-- vector real_angle;
-- float turny = 0, turnx = 0;
-- float vz;
--
-- real_angle = vectoangles(self.steerto) - self.angles;
- vz = self.velocity_z;
- 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_MEELE:
-- if(self.frame != ANIM_MEELE)
-- {
-- defer(0.41, walker_setnoanim);
-- defer(0.21, walker_meele_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);
- 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 );
- 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 );
- 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);
- turrets_setframe(self.animflag, false);
--}
--
--void walker_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);
--}
--
--
--void walker_respawnhook()
--{
-- 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)
-- return;
--
-- setorigin(self, self.pos1);
-- self.angles = self.pos2;
--
-- if (self.target != "")
-- {
-- e = find(world, targetname, self.target);
-- if (!e)
-- {
-- dprint("Warning! initital waypoint for Walker does NOT exsist!\n");
-- self.target = "";
-- }
--
-- if (e.classname != "turret_checkpoint")
-- dprint("Warning: not a turrret path\n");
-- else
-- {
-- #ifdef WALKER_FANCYPATHING
-- self.pathcurrent = WALKER_PATH(self.origin, e.origin);
-- self.pathgoal = e;
--#else
-- self.pathcurrent = e;
--#endif
-- }
-- }
--}
--
--void walker_diehook()
--{
--#ifdef WALKER_FANCYPATHING
-- if (self.pathcurrent)
-- pathlib_deletepath(self.pathcurrent.owner);
--#endif
-- self.pathcurrent = world;
--}
--
--void turret_walker_dinit()
--{
-- entity e;
--
-- if (self.netname == "") self.netname = "Walker Turret";
--
-- self.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
-- self.turrcaps_flags = TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_MOVE ;
-- self.aim_flags = TFL_AIM_LEAD;
--
-- self.turrcaps_flags |= TFL_TURRCAPS_HITSCAN;
--
--
-- self.turret_respawnhook = walker_respawnhook;
-- self.turret_diehook = walker_diehook;
--
-- self.ticrate = 0.05;
-- if (turret_stdproc_init("walker_std", "models/turrets/walker_body.md3", "models/turrets/walker_head_minigun.md3", TID_WALKER) == 0)
-- {
-- remove(self);
-- return;
-- }
-- setsize(self, WALKER_MIN, WALKER_MAX);
-- self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
-- self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
- self.iscreature = TRUE;
- self.iscreature = true;
-- self.teleportable = TELEPORT_NORMAL;
- self.damagedbycontents = TRUE;
- self.damagedbycontents = true;
-- self.movetype = MOVETYPE_WALK;
-- self.solid = SOLID_SLIDEBOX;
-- self.takedamage = DAMAGE_AIM;
-- 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.idle_aim = '0 0 0';
-- self.turret_firecheckfunc = walker_firecheck;
-- self.turret_firefunc = walker_attack;
-- self.turret_postthink = walker_postthink;
--
-- 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 = WALKER_PATH(self.origin, e.origin);
-- self.pathgoal = e;
--#else
-- self.pathcurrent = e;
--#endif
-- }
-- }
--}
--
--
--void spawnfunc_turret_walker()
--{
-- g_turrets_common_precash();
--
-- precache_model ("models/turrets/walker_head_minigun.md3");
-- precache_model ("models/turrets/walker_body.md3");
-- precache_model ( "models/turrets/rocket.md3");
-- precache_sound ( "weapons/rocket_impact.wav" );
--
-- self.think = turret_walker_dinit;
-- self.nextthink = time + 0.5;
--}
- #define BRG_SETUP 2
- #define BRG_START 4
- #define BRG_END 8
+ #include "bumblebee.qh"
#ifdef SVQC
- // Auto cvars
- float autocvar_g_vehicle_bumblebee_speed_forward;
- float autocvar_g_vehicle_bumblebee_speed_strafe;
- float autocvar_g_vehicle_bumblebee_speed_up;
- float autocvar_g_vehicle_bumblebee_speed_down;
- float autocvar_g_vehicle_bumblebee_turnspeed;
- float autocvar_g_vehicle_bumblebee_pitchspeed;
- float autocvar_g_vehicle_bumblebee_pitchlimit;
- float autocvar_g_vehicle_bumblebee_friction;
-
- float autocvar_g_vehicle_bumblebee_energy;
- float autocvar_g_vehicle_bumblebee_energy_regen;
- float autocvar_g_vehicle_bumblebee_energy_regen_pause;
-
- float autocvar_g_vehicle_bumblebee_health;
- float autocvar_g_vehicle_bumblebee_health_regen;
- float autocvar_g_vehicle_bumblebee_health_regen_pause;
-
- float autocvar_g_vehicle_bumblebee_shield;
- float autocvar_g_vehicle_bumblebee_shield_regen;
- float autocvar_g_vehicle_bumblebee_shield_regen_pause;
-
- float autocvar_g_vehicle_bumblebee_cannon_cost;
- float autocvar_g_vehicle_bumblebee_cannon_damage;
- float autocvar_g_vehicle_bumblebee_cannon_radius;
- float autocvar_g_vehicle_bumblebee_cannon_refire;
- float autocvar_g_vehicle_bumblebee_cannon_speed;
- float autocvar_g_vehicle_bumblebee_cannon_spread;
- float autocvar_g_vehicle_bumblebee_cannon_force;
-
- float autocvar_g_vehicle_bumblebee_cannon_ammo;
- float autocvar_g_vehicle_bumblebee_cannon_ammo_regen;
- float autocvar_g_vehicle_bumblebee_cannon_ammo_regen_pause;
-
- var float autocvar_g_vehicle_bumblebee_cannon_lock = 0;
-
- float autocvar_g_vehicle_bumblebee_cannon_turnspeed;
- float autocvar_g_vehicle_bumblebee_cannon_pitchlimit_down;
- float autocvar_g_vehicle_bumblebee_cannon_pitchlimit_up;
- float autocvar_g_vehicle_bumblebee_cannon_turnlimit_in;
- float autocvar_g_vehicle_bumblebee_cannon_turnlimit_out;
-
-
- float autocvar_g_vehicle_bumblebee_raygun_turnspeed;
- float autocvar_g_vehicle_bumblebee_raygun_pitchlimit_down;
- float autocvar_g_vehicle_bumblebee_raygun_pitchlimit_up;
- float autocvar_g_vehicle_bumblebee_raygun_turnlimit_sides;
-
- float autocvar_g_vehicle_bumblebee_raygun_range;
- float autocvar_g_vehicle_bumblebee_raygun_dps;
- float autocvar_g_vehicle_bumblebee_raygun_aps;
- float autocvar_g_vehicle_bumblebee_raygun_fps;
-
- float autocvar_g_vehicle_bumblebee_raygun;
- float autocvar_g_vehicle_bumblebee_healgun_hps;
- float autocvar_g_vehicle_bumblebee_healgun_hmax;
- float autocvar_g_vehicle_bumblebee_healgun_aps;
- float autocvar_g_vehicle_bumblebee_healgun_amax;
- float autocvar_g_vehicle_bumblebee_healgun_sps;
- float autocvar_g_vehicle_bumblebee_healgun_locktime;
-
- float autocvar_g_vehicle_bumblebee_respawntime;
-
- float autocvar_g_vehicle_bumblebee_blowup_radius;
- float autocvar_g_vehicle_bumblebee_blowup_coredamage;
- float autocvar_g_vehicle_bumblebee_blowup_edgedamage;
- float autocvar_g_vehicle_bumblebee_blowup_forceintensity;
- var vector autocvar_g_vehicle_bumblebee_bouncepain;
-
- var float autocvar_g_vehicle_bumblebee = 0;
-
-
- float bumble_raygun_send(entity to, float sf);
-
- #define BUMB_MIN '-130 -130 -130'
- #define BUMB_MAX '130 130 130'
-
void bumb_fire_cannon(entity _gun, string _tagname, entity _owner)
{
vector v = gettaginfo(_gun, gettagindex(_gun, _tagname));
vehicles_projectile("bigplasma_muzzleflash", "weapons/flacexp3.wav",
v, normalize(v_forward + randomvec() * autocvar_g_vehicle_bumblebee_cannon_spread) * autocvar_g_vehicle_bumblebee_cannon_speed,
autocvar_g_vehicle_bumblebee_cannon_damage, autocvar_g_vehicle_bumblebee_cannon_radius, autocvar_g_vehicle_bumblebee_cannon_force, 0,
- DEATH_VH_BUMB_GUN, PROJECTILE_BUMBLE_GUN, 0, TRUE, TRUE, _owner);
+ DEATH_VH_BUMB_GUN, PROJECTILE_BUMBLE_GUN, 0, true, true, _owner);
}
float bumb_gunner_frame()
vector vf = real_origin(gun.enemy);
vector _vel = gun.enemy.velocity;
if(gun.enemy.movetype == MOVETYPE_WALK)
- _vel_z *= 0.1;
+ _vel.z *= 0.1;
ad = vf;
WriteByte(MSG_ONE, SVC_SETVIEWANGLES);
WriteAngle(MSG_ONE, 0);
- WriteAngle(MSG_ONE, self.vehicle.angles_y);
+ WriteAngle(MSG_ONE, self.vehicle.angles.y);
WriteAngle(MSG_ONE, 0);
}
else
{
dprint("^1ERROR:^7Tried to enter a fully occupied vehicle!\n");
- return FALSE;
+ return false;
}
_gunner = other;
WriteByte(MSG_ONE, SVC_SETVIEWPORT);
WriteEntity(MSG_ONE, _gun.vehicle_viewport);
WriteByte(MSG_ONE, SVC_SETVIEWANGLES);
- WriteAngle(MSG_ONE, _gun.angles_x + self.angles_x); // tilt
- WriteAngle(MSG_ONE, _gun.angles_y + self.angles_y); // yaw
+ WriteAngle(MSG_ONE, _gun.angles.x + self.angles.x); // tilt
+ WriteAngle(MSG_ONE, _gun.angles.y + self.angles.y); // yaw
WriteAngle(MSG_ONE, 0); // roll
_gun.vehicle_hudmodel.viewmodelforclient = other;
other = vh_player;
_gun = vh_vehicle;
- return TRUE;
+ return true;
}
float vehicles_valid_pilot()
{
if (!IS_PLAYER(other))
- return FALSE;
+ return false;
if(other.deadflag != DEAD_NO)
- return FALSE;
+ return false;
if(other.vehicle != world)
- return FALSE;
+ return false;
if (!IS_REAL_CLIENT(other))
if(!autocvar_g_vehicles_allow_bots)
- return FALSE;
+ return false;
if(teamplay && other.team != self.team)
- return FALSE;
+ return false;
- return TRUE;
+ return true;
}
void bumb_touch()
self.gun2.vehicle_energy + autocvar_g_vehicle_bumblebee_cannon_ammo_regen * frametime);
if(self.vehicle_flags & VHF_SHIELDREGEN)
- vehicles_regen(self.dmg_time, vehicle_shield, autocvar_g_vehicle_bumblebee_shield, autocvar_g_vehicle_bumblebee_shield_regen_pause, autocvar_g_vehicle_bumblebee_shield_regen, frametime, TRUE);
+ vehicles_regen(self.dmg_time, vehicle_shield, autocvar_g_vehicle_bumblebee_shield, autocvar_g_vehicle_bumblebee_shield_regen_pause, autocvar_g_vehicle_bumblebee_shield_regen, frametime, true);
if(self.vehicle_flags & VHF_HEALTHREGEN)
- vehicles_regen(self.dmg_time, vehicle_health, autocvar_g_vehicle_bumblebee_health, autocvar_g_vehicle_bumblebee_health_regen_pause, autocvar_g_vehicle_bumblebee_health_regen, frametime, FALSE);
+ vehicles_regen(self.dmg_time, vehicle_health, autocvar_g_vehicle_bumblebee_health, autocvar_g_vehicle_bumblebee_health_regen_pause, autocvar_g_vehicle_bumblebee_health_regen, frametime, false);
if(self.vehicle_flags & VHF_ENERGYREGEN)
- vehicles_regen(self.wait, vehicle_energy, autocvar_g_vehicle_bumblebee_energy, autocvar_g_vehicle_bumblebee_energy_regen_pause, autocvar_g_vehicle_bumblebee_energy_regen, frametime, FALSE);
+ vehicles_regen(self.wait, vehicle_energy, autocvar_g_vehicle_bumblebee_energy, autocvar_g_vehicle_bumblebee_energy_regen_pause, autocvar_g_vehicle_bumblebee_energy_regen, frametime, false);
}
vang = vehic.angles;
newvel = vectoangles(normalize(trace_endpos - self.origin + '0 0 32'));
- vang_x *= -1;
- newvel_x *= -1;
- if(newvel_x > 180) newvel_x -= 360;
- if(newvel_x < -180) newvel_x += 360;
- if(newvel_y > 180) newvel_y -= 360;
- if(newvel_y < -180) newvel_y += 360;
-
- ftmp = shortangle_f(pilot.v_angle_y - vang_y, vang_y);
+ vang.x *= -1;
+ newvel.x *= -1;
+ if(newvel.x > 180) newvel.x -= 360;
+ if(newvel.x < -180) newvel.x += 360;
+ if(newvel.y > 180) newvel.y -= 360;
+ if(newvel.y < -180) newvel.y += 360;
+
+ ftmp = shortangle_f(pilot.v_angle.y - vang.y, vang.y);
if(ftmp > 180) ftmp -= 360;
if(ftmp < -180) ftmp += 360;
- vehic.avelocity_y = bound(-autocvar_g_vehicle_bumblebee_turnspeed, ftmp + vehic.avelocity_y * 0.9, autocvar_g_vehicle_bumblebee_turnspeed);
+ vehic.avelocity_y = bound(-autocvar_g_vehicle_bumblebee_turnspeed, ftmp + vehic.avelocity.y * 0.9, autocvar_g_vehicle_bumblebee_turnspeed);
// Pitch
ftmp = 0;
- if(pilot.movement_x > 0 && vang_x < autocvar_g_vehicle_bumblebee_pitchlimit)
+ if(pilot.movement.x > 0 && vang.x < autocvar_g_vehicle_bumblebee_pitchlimit)
ftmp = 4;
- else if(pilot.movement_x < 0 && vang_x > -autocvar_g_vehicle_bumblebee_pitchlimit)
+ else if(pilot.movement.x < 0 && vang.x > -autocvar_g_vehicle_bumblebee_pitchlimit)
ftmp = -8;
- newvel_x = bound(-autocvar_g_vehicle_bumblebee_pitchlimit, newvel_x , autocvar_g_vehicle_bumblebee_pitchlimit);
- ftmp = vang_x - bound(-autocvar_g_vehicle_bumblebee_pitchlimit, newvel_x + ftmp, autocvar_g_vehicle_bumblebee_pitchlimit);
- vehic.avelocity_x = bound(-autocvar_g_vehicle_bumblebee_pitchspeed, ftmp + vehic.avelocity_x * 0.9, autocvar_g_vehicle_bumblebee_pitchspeed);
+ newvel.x = bound(-autocvar_g_vehicle_bumblebee_pitchlimit, newvel.x , autocvar_g_vehicle_bumblebee_pitchlimit);
+ ftmp = vang.x - bound(-autocvar_g_vehicle_bumblebee_pitchlimit, newvel.x + ftmp, autocvar_g_vehicle_bumblebee_pitchlimit);
+ vehic.avelocity_x = bound(-autocvar_g_vehicle_bumblebee_pitchspeed, ftmp + vehic.avelocity.x * 0.9, autocvar_g_vehicle_bumblebee_pitchspeed);
- vehic.angles_x = anglemods(vehic.angles_x);
- vehic.angles_y = anglemods(vehic.angles_y);
- vehic.angles_z = anglemods(vehic.angles_z);
+ vehic.angles_x = anglemods(vehic.angles.x);
+ vehic.angles_y = anglemods(vehic.angles.y);
+ vehic.angles_z = anglemods(vehic.angles.z);
- makevectors('0 1 0' * vehic.angles_y);
+ makevectors('0 1 0' * vehic.angles.y);
newvel = vehic.velocity * -autocvar_g_vehicle_bumblebee_friction;
- if(pilot.movement_x != 0)
+ if(pilot.movement.x != 0)
{
- if(pilot.movement_x > 0)
+ if(pilot.movement.x > 0)
newvel += v_forward * autocvar_g_vehicle_bumblebee_speed_forward;
- else if(pilot.movement_x < 0)
+ else if(pilot.movement.x < 0)
newvel -= v_forward * autocvar_g_vehicle_bumblebee_speed_forward;
}
- if(pilot.movement_y != 0)
+ if(pilot.movement.y != 0)
{
- if(pilot.movement_y < 0)
+ if(pilot.movement.y < 0)
newvel -= v_right * autocvar_g_vehicle_bumblebee_speed_strafe;
- else if(pilot.movement_y > 0)
+ else if(pilot.movement.y > 0)
newvel += v_right * autocvar_g_vehicle_bumblebee_speed_strafe;
ftmp = newvel * v_right;
ftmp *= frametime * 0.1;
- vehic.angles_z = bound(-15, vehic.angles_z + ftmp, 15);
+ vehic.angles_z = bound(-15, vehic.angles.z + ftmp, 15);
}
else
{
vehic.angles_z *= 0.95;
- if(vehic.angles_z >= -1 && vehic.angles_z <= -1)
+ if(vehic.angles.z >= -1 && vehic.angles.z <= -1)
vehic.angles_z = 0;
}
trace_ent.health = min(trace_ent.health + autocvar_g_vehicle_bumblebee_healgun_hps * frametime, autocvar_g_vehicle_bumblebee_healgun_hmax);
}
- else if(trace_ent.turrcaps_flags & TFL_TURRCAPS_ISTURRET)
+ else if(trace_ent.turret_flags & TUR_FLAG_ISTURRET)
{
if(trace_ent.health <= trace_ent.tur_health && autocvar_g_vehicle_bumblebee_healgun_hps)
trace_ent.health = min(trace_ent.health + autocvar_g_vehicle_bumblebee_healgun_hps * frametime, trace_ent.tur_health);
void bumb_impact()
{
- if(autocvar_g_vehicle_bumblebee_bouncepain_x)
- vehicles_impact(autocvar_g_vehicle_bumblebee_bouncepain_x, autocvar_g_vehicle_bumblebee_bouncepain_y, autocvar_g_vehicle_bumblebee_bouncepain_z);
+ if(autocvar_g_vehicle_bumblebee_bouncepain.x)
+ vehicles_impact(autocvar_g_vehicle_bumblebee_bouncepain.x, autocvar_g_vehicle_bumblebee_bouncepain.y, autocvar_g_vehicle_bumblebee_bouncepain.z);
}
void bumb_spawn(float _f)
if(self.gun3.enemy == world)
{
self.gun3.enemy = spawn();
- Net_LinkEntity(self.gun3.enemy, TRUE, 0, bumble_raygun_send);
+ Net_LinkEntity(self.gun3.enemy, true, 0, bumble_raygun_send);
self.gun3.enemy.SendFlags = BRG_SETUP;
self.gun3.enemy.cnt = autocvar_g_vehicle_bumblebee_raygun;
self.gun3.enemy.effects = EF_NODRAW | EF_LOWPRECISION;
if(!vehicle_initialize(
"Bumblebee", "models/vehicles/bumblebee_body.dpm",
"", "models/vehicles/spiderbot_cockpit.dpm", "", "", "tag_viewport",
- HUD_BUMBLEBEE, BUMB_MIN, BUMB_MAX, FALSE,
+ HUD_BUMBLEBEE, BUMB_MIN, BUMB_MAX, false,
bumb_spawn, autocvar_g_vehicle_bumblebee_respawntime,
bumb_pilot_frame, bumb_enter, bumb_exit,
- bumb_die, bumb_think, FALSE, autocvar_g_vehicle_bumblebee_health, autocvar_g_vehicle_bumblebee_shield))
+ bumb_die, bumb_think, false, autocvar_g_vehicle_bumblebee_health, autocvar_g_vehicle_bumblebee_shield))
{
remove(self);
return;
if(sf & BRG_START)
{
- WriteCoord(MSG_ENTITY, self.hook_start_x);
- WriteCoord(MSG_ENTITY, self.hook_start_y);
- WriteCoord(MSG_ENTITY, self.hook_start_z);
+ WriteCoord(MSG_ENTITY, self.hook_start.x);
+ WriteCoord(MSG_ENTITY, self.hook_start.y);
+ WriteCoord(MSG_ENTITY, self.hook_start.z);
}
if(sf & BRG_END)
{
- WriteCoord(MSG_ENTITY, self.hook_end_x);
- WriteCoord(MSG_ENTITY, self.hook_end_y);
- WriteCoord(MSG_ENTITY, self.hook_end_z);
+ WriteCoord(MSG_ENTITY, self.hook_end.x);
+ WriteCoord(MSG_ENTITY, self.hook_end.y);
+ WriteCoord(MSG_ENTITY, self.hook_end.z);
}
- return TRUE;
+ return true;
}
#endif // SVQC
void bumble_raygun_read(float bIsNew)
{
- float sf = ReadByte();
+ int sf = ReadByte();
if(sf & BRG_SETUP)
{
- #define RACER_MIN '-120 -120 -40'
- #define RACER_MAX '120 120 40'
+ const vector RACER_MIN = '-120 -120 -40';
+ const vector RACER_MAX = '120 120 40';
#ifdef SVQC
++#include "../../common/turrets/util.qh"
++
void racer_exit(float eject);
void racer_enter();
self.velocity += push_vector * _delta;
// Anti ocilation
- if(self.velocity_z > 0)
+ if(self.velocity.z > 0)
self.velocity_z *= 1 - autocvar_g_vehicle_racer_upforcedamper * _delta;
- push_vector_x = (fl_push - bl_push);
+ push_vector.x = (fl_push - bl_push);
push_vector_x += (fr_push - br_push);
push_vector_x *= 360;
- push_vector_z = (fr_push - fl_push);
+ push_vector.z = (fr_push - fl_push);
push_vector_z += (br_push - bl_push);
push_vector_z *= 360;
// Apply angle diffrance
- self.angles_z += push_vector_z * _delta;
- self.angles_x += push_vector_x * _delta;
+ self.angles_z += push_vector.z * _delta;
+ self.angles_x += push_vector.x * _delta;
// Apply stabilizer
self.angles_x *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * _delta);
bolt = vehicles_projectile("wakizashi_gun_muzzleflash", "weapons/lasergun_fire.wav",
v, normalize(v_forward + randomvec() * autocvar_g_vehicle_racer_cannon_spread) * autocvar_g_vehicle_racer_cannon_speed,
autocvar_g_vehicle_racer_cannon_damage, autocvar_g_vehicle_racer_cannon_radius, autocvar_g_vehicle_racer_cannon_force, 0,
- DEATH_VH_WAKI_GUN, PROJECTILE_WAKICANNON, 0, TRUE, TRUE, self.owner);
+ DEATH_VH_WAKI_GUN, PROJECTILE_WAKICANNON, 0, true, true, self.owner);
// Fix z-aim (for chase mode)
v = normalize(trace_endpos - bolt.origin);
- v_forward_z = v_z * 0.5;
+ v_forward.z = v.z * 0.5;
bolt.velocity = v_forward * autocvar_g_vehicle_racer_cannon_speed;
}
newdir = normalize(predicted_origin - self.origin);
//vector
- float height_diff = predicted_origin_z - self.origin_z;
+ float height_diff = predicted_origin.z - self.origin.z;
if(vlen(newdir - v_forward) > autocvar_g_vehicle_racer_rocket_locked_maxangle)
{
}
if(trace_fraction != 1.0 && trace_ent != self.enemy)
- newdir_z += 16 * sys_frametime;
+ newdir.z += 16 * sys_frametime;
self.velocity = normalize(olddir + newdir * autocvar_g_vehicle_racer_rocket_turnrate) * newvel;
self.velocity_z -= 800 * sys_frametime;
entity rocket = rocket = vehicles_projectile("wakizashi_rocket_launch", "weapons/rocket_fire.wav",
v, v_forward * autocvar_g_vehicle_racer_rocket_speed,
autocvar_g_vehicle_racer_rocket_damage, autocvar_g_vehicle_racer_rocket_radius, autocvar_g_vehicle_racer_rocket_force, 3,
- DEATH_VH_WAKI_ROCKET, PROJECTILE_WAKIROCKET, 20, FALSE, FALSE, self.owner);
+ DEATH_VH_WAKI_ROCKET, PROJECTILE_WAKIROCKET, 20, false, false, self.owner);
rocket.lip = autocvar_g_vehicle_racer_rocket_accel * sys_frametime;
rocket.wait = autocvar_g_vehicle_racer_rocket_turnrate;
// Yaw
ftmp = autocvar_g_vehicle_racer_turnspeed * frametime;
- ftmp = bound(-ftmp, shortangle_f(player.v_angle_y - racer.angles_y, racer.angles_y), ftmp);
- racer.angles_y = anglemods(racer.angles_y + ftmp);
+ ftmp = bound(-ftmp, shortangle_f(player.v_angle.y - racer.angles.y, racer.angles.y), ftmp);
+ racer.angles_y = anglemods(racer.angles.y + ftmp);
// Roll
racer.angles_z += -ftmp * autocvar_g_vehicle_racer_turnroll * frametime;
// Pitch
ftmp = autocvar_g_vehicle_racer_pitchspeed * frametime;
- ftmp = bound(-ftmp, shortangle_f(player.v_angle_x - racer.angles_x, racer.angles_x), ftmp);
- racer.angles_x = bound(-30, anglemods(racer.angles_x + ftmp), 30);
+ ftmp = bound(-ftmp, shortangle_f(player.v_angle.x - racer.angles.x, racer.angles.x), ftmp);
+ racer.angles_x = bound(-30, anglemods(racer.angles.x + ftmp), 30);
makevectors(racer.angles);
racer.angles_x *= -1;
if(vlen(player.movement) != 0)
{
if(player.movement_x)
- df += v_forward * ((player.movement_x > 0) ? autocvar_g_vehicle_racer_speed_forward : -autocvar_g_vehicle_racer_speed_forward);
+ df += v_forward * ((player.movement.x > 0) ? autocvar_g_vehicle_racer_speed_forward : -autocvar_g_vehicle_racer_speed_forward);
if(player.movement_y)
- df += v_right * ((player.movement_y > 0) ? autocvar_g_vehicle_racer_speed_strafe : -autocvar_g_vehicle_racer_speed_strafe);
+ df += v_right * ((player.movement.y > 0) ? autocvar_g_vehicle_racer_speed_strafe : -autocvar_g_vehicle_racer_speed_strafe);
if(self.sound_nexttime < time || self.sounds != 1)
{
player.vehicle_reload1 = bound(0, 100 * ((time - racer.lip) / (racer.delay - racer.lip)), 100);
if(racer.vehicle_flags & VHF_SHIELDREGEN)
- vehicles_regen(racer.dmg_time, vehicle_shield, autocvar_g_vehicle_racer_shield, autocvar_g_vehicle_racer_shield_regen_pause, autocvar_g_vehicle_racer_shield_regen, frametime, TRUE);
+ vehicles_regen(racer.dmg_time, vehicle_shield, autocvar_g_vehicle_racer_shield, autocvar_g_vehicle_racer_shield_regen_pause, autocvar_g_vehicle_racer_shield_regen, frametime, true);
if(racer.vehicle_flags & VHF_HEALTHREGEN)
- vehicles_regen(racer.dmg_time, vehicle_health, autocvar_g_vehicle_racer_health, autocvar_g_vehicle_racer_health_regen_pause, autocvar_g_vehicle_racer_health_regen, frametime, FALSE);
+ vehicles_regen(racer.dmg_time, vehicle_health, autocvar_g_vehicle_racer_health, autocvar_g_vehicle_racer_health_regen_pause, autocvar_g_vehicle_racer_health_regen, frametime, false);
if(racer.vehicle_flags & VHF_ENERGYREGEN)
- vehicles_regen(racer.wait, vehicle_energy, autocvar_g_vehicle_racer_energy, autocvar_g_vehicle_racer_energy_regen_pause, autocvar_g_vehicle_racer_energy_regen, frametime, FALSE);
+ vehicles_regen(racer.wait, vehicle_energy, autocvar_g_vehicle_racer_energy, autocvar_g_vehicle_racer_energy_regen_pause, autocvar_g_vehicle_racer_energy_regen, frametime, false);
VEHICLE_UPDATE_PLAYER(player, health, racer);
tracebox(self.origin, self.mins, self.maxs, self.origin - ('0 0 1' * autocvar_g_vehicle_racer_springlength), MOVE_NORMAL, self);
vector df = self.velocity * -autocvar_g_vehicle_racer_friction;
- df_z += (1 - trace_fraction) * autocvar_g_vehicle_racer_hoverpower + sin(time * 2) * (autocvar_g_vehicle_racer_springlength * 2);
+ df.z += (1 - trace_fraction) * autocvar_g_vehicle_racer_hoverpower + sin(time * 2) * (autocvar_g_vehicle_racer_springlength * 2);
self.velocity += df * pushdeltatime;
- if(self.velocity_z > 0)
+ if(self.velocity.z > 0)
self.velocity_z *= 1 - autocvar_g_vehicle_racer_upforcedamper * pushdeltatime;
self.angles_x *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * pushdeltatime);
void racer_impact()
{
- if(autocvar_g_vehicle_racer_bouncepain_x)
- vehicles_impact(autocvar_g_vehicle_racer_bouncepain_x, autocvar_g_vehicle_racer_bouncepain_y, autocvar_g_vehicle_racer_bouncepain_z);
+ if(autocvar_g_vehicle_racer_bouncepain.x)
+ vehicles_impact(autocvar_g_vehicle_racer_bouncepain.x, autocvar_g_vehicle_racer_bouncepain.y, autocvar_g_vehicle_racer_bouncepain.z);
}
void racer_blowup()
pointparticles(particleeffectnum("explosion_medium"), self.origin, '0 0 0', 1);
if(random() < 0.5)
- self.avelocity_z = 32;
+ self.avelocity_z = 32;
else
- self.avelocity_z = -32;
+ self.avelocity_z = -32;
self.avelocity_x = -vlen(self.velocity) * 0.2;
self.velocity += '0 0 700';
"", "", "tag_viewport",
HUD_WAKIZASHI,
0.5 * RACER_MIN, 0.5 * RACER_MAX,
- FALSE,
+ false,
racer_spawn, autocvar_g_vehicle_racer_respawntime,
racer_frame,
racer_enter, racer_exit,
racer_die, racer_think,
- TRUE,
+ true,
autocvar_g_vehicle_racer_health,
autocvar_g_vehicle_racer_shield))
{
++#include "../../common/turrets/util.qh"
++
float autocvar_g_vehicles_crush_dmg;
float autocvar_g_vehicles_crush_force;
float autocvar_g_vehicles_delayspawn;
float autocvar_g_vehicles_delayspawn_jitter;
- var float autocvar_g_vehicles_vortex_damagerate = 0.5;
- var float autocvar_g_vehicles_machinegun_damagerate = 0.5;
- var float autocvar_g_vehicles_rifle_damagerate = 0.75;
- var float autocvar_g_vehicles_vaporizer_damagerate = 0.001;
- var float autocvar_g_vehicles_tag_damagerate = 5;
+ 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;
WriteByte(MSG_ENTITY, self.cnt);
- WriteCoord(MSG_ENTITY, self.origin_x);
- WriteCoord(MSG_ENTITY, self.origin_y);
- WriteCoord(MSG_ENTITY, self.origin_z);
+ WriteCoord(MSG_ENTITY, self.origin.x);
+ WriteCoord(MSG_ENTITY, self.origin.y);
+ WriteCoord(MSG_ENTITY, self.origin.z);
- WriteByte(MSG_ENTITY, rint(self.colormod_x * 255));
- WriteByte(MSG_ENTITY, rint(self.colormod_y * 255));
- WriteByte(MSG_ENTITY, rint(self.colormod_z * 255));
+ WriteByte(MSG_ENTITY, rint(self.colormod.x * 255));
+ WriteByte(MSG_ENTITY, rint(self.colormod.y * 255));
+ WriteByte(MSG_ENTITY, rint(self.colormod.z * 255));
- return TRUE;
+ return true;
}
void UpdateAuxiliaryXhair(entity own, vector loc, vector clr, float axh_id)
axh.cnt = axh_id;
axh.drawonlytoclient = own;
axh.owner = own;
- Net_LinkEntity(axh, FALSE, 0, SendAuxiliaryXhair);
+ Net_LinkEntity(axh, false, 0, SendAuxiliaryXhair);
}
setorigin(axh, loc);
if(trace_ent.deadflag != DEAD_NO)
trace_ent = world;
- if(!trace_ent.vehicle_flags & VHF_ISVEHICLE ||
- trace_ent.turrcaps_flags & TFL_TURRCAPS_ISTURRET ||
- trace_ent.takedamage == DAMAGE_TARGETDRONE)
+ if(!((trace_ent.vehicle_flags & VHF_ISVEHICLE) || (trace_ent.turret_flags & TUR_FLAG_ISTURRET)))
trace_ent = world;
}
proj.solid = SOLID_BBOX;
proj.movetype = MOVETYPE_FLYMISSILE;
proj.flags = FL_PROJECTILE;
- proj.bot_dodge = TRUE;
+ proj.bot_dodge = true;
proj.bot_dodgerating = _dmg;
proj.velocity = _vel;
proj.touch = vehicles_projectile_explode;
self.touch = vehicles_touch;
self.event_damage = vehicles_damage;
self.reset = vehicles_reset;
- self.iscreature = TRUE;
- self.teleportable = FALSE; // no teleporting for vehicles, too buggy
- self.damagedbycontents = TRUE;
+ self.iscreature = true;
+ self.teleportable = false; // no teleporting for vehicles, too buggy
+ self.damagedbycontents = true;
self.movetype = MOVETYPE_WALK;
self.solid = SOLID_SLIDEBOX;
self.takedamage = DAMAGE_AIM;
self.deadflag = DEAD_NO;
- self.bot_attack = TRUE;
+ self.bot_attack = true;
self.flags = FL_NOTARGET;
self.avelocity = '0 0 0';
self.velocity = '0 0 0';
float vehicles_crushable(entity e)
{
if(IS_PLAYER(e))
- return TRUE;
+ return true;
if(e.flags & FL_MONSTER)
- return TRUE;
+ return true;
- return FALSE;
+ return false;
}
void vehicles_impact(float _minspeed, float _speedfac, float _maxpain)
vehicles_enter();
}
- var float autocvar_g_vehicles_allow_bots = 0;
+ float autocvar_g_vehicles_allow_bots = 0;
void vehicles_enter()
{
// Remove this when bots know how to use vehicles
self.team = self.owner.team;
self.flags -= FL_NOTARGET;
- self.monster_attack = TRUE;
+ self.monster_attack = true;
if (IS_REAL_CLIENT(other))
{
WriteByte (MSG_ONE, SVC_SETVIEWANGLES);
if(self.tur_head)
{
- WriteAngle(MSG_ONE, self.tur_head.angles_x + self.angles_x); // tilt
- WriteAngle(MSG_ONE, self.tur_head.angles_y + self.angles_y); // yaw
+ WriteAngle(MSG_ONE, self.tur_head.angles.x + self.angles.x); // tilt
+ WriteAngle(MSG_ONE, self.tur_head.angles.y + self.angles.y); // yaw
WriteAngle(MSG_ONE, 0); // roll
}
else
{
- WriteAngle(MSG_ONE, self.angles_x * -1); // tilt
- WriteAngle(MSG_ONE, self.angles_y); // yaw
+ WriteAngle(MSG_ONE, self.angles.x * -1); // tilt
+ WriteAngle(MSG_ONE, self.angles.y); // yaw
WriteAngle(MSG_ONE, 0); // roll
}
}
for(i = 0; i < 100; ++i)
{
v = randomvec();
- v_z = 0;
+ v.z = 0;
v = v2 + normalize(v) * mysize;
tracebox(v2, PL_MIN, PL_MAX, v, MOVE_NORMAL, self.owner);
if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid)
return;
}
- vehicles_exit_running = TRUE;
+ vehicles_exit_running = true;
if(IS_CLIENT(self))
{
_vehicle = self.vehicle;
{
_vehicle.vehicle_exit(eject);
self = _oldself;
- vehicles_exit_running = FALSE;
+ vehicles_exit_running = false;
return;
}
}
WriteByte (MSG_ONE, SVC_SETVIEWANGLES);
WriteAngle(MSG_ONE, 0);
- WriteAngle(MSG_ONE, _vehicle.angles_y);
+ WriteAngle(MSG_ONE, _vehicle.angles.y);
WriteAngle(MSG_ONE, 0);
}
sound (_vehicle, CH_TRIGGER_SINGLE, "misc/null.wav", 1, ATTEN_NORM);
_vehicle.vehicle_hudmodel.viewmodelforclient = _vehicle;
_vehicle.phase = time + 1;
- _vehicle.monster_attack = FALSE;
+ _vehicle.monster_attack = false;
_vehicle.vehicle_exit(eject);
_vehicle.owner = world;
self = _oldself;
- vehicles_exit_running = FALSE;
+ vehicles_exit_running = false;
}
rgb = Team_ColorRGB(self.team);
else
rgb = '1 1 1';
- WaypointSprite_Spawn("vehicle", 0, 0, self, '0 0 64', world, 0, self, waypointsprite_attached, TRUE, RADARICON_POWERUP, rgb);
+ WaypointSprite_Spawn("vehicle", 0, 0, self, '0 0 64', world, 0, self, waypointsprite_attached, true, RADARICON_POWERUP, rgb);
if(self.waypointsprite_attached)
{
WaypointSprite_UpdateRule(self.waypointsprite_attached, self.wp00.team, SPRITERULE_DEFAULT);
setattachment(_slot.vehicle_hudmodel, _slot, "");
setattachment(_slot.vehicle_viewport, _slot.vehicle_hudmodel, "");
- return TRUE;
+ return true;
}
float vehicle_initialize(string net_name,
float _max_shield)
{
if(!autocvar_g_vehicles)
- return FALSE;
+ return false;
if(self.targetname)
{
self.tur_head = spawn();
self.tur_head.owner = self;
self.takedamage = DAMAGE_AIM;
- self.bot_attack = TRUE;
- self.iscreature = TRUE;
- self.teleportable = FALSE; // no teleporting for vehicles, too buggy
- self.damagedbycontents = TRUE;
+ self.bot_attack = true;
+ self.iscreature = true;
+ self.teleportable = false; // no teleporting for vehicles, too buggy
+ self.damagedbycontents = true;
self.hud = vhud;
self.tur_health = _max_health;
self.tur_head.tur_health = _max_shield;
self.tur_head.team = self.team;
if(MUTATOR_CALLHOOK(VehicleSpawn))
- return FALSE;
+ return false;
- return TRUE;
+ return true;
}
vector vehicle_aimturret(entity _vehic, vector _target, entity _turrret, string _tagname,
vtag = gettaginfo(_turrret, gettagindex(_turrret, _tagname));
vtmp = vectoangles(normalize(_target - vtag));
vtmp = AnglesTransform_ToAngles(AnglesTransform_LeftDivide(AnglesTransform_FromAngles(_vehic.angles), AnglesTransform_FromAngles(vtmp))) - _turrret.angles;
- vtmp = AnglesTransform_Normalize(vtmp, TRUE);
+ vtmp = AnglesTransform_Normalize(vtmp, true);
ftmp = _aimspeed * frametime;
- vtmp_y = bound(-ftmp, vtmp_y, ftmp);
- vtmp_x = bound(-ftmp, vtmp_x, ftmp);
- _turrret.angles_y = bound(_rotlimit_min, _turrret.angles_y + vtmp_y, _rotlimit_max);
- _turrret.angles_x = bound(_pichlimit_min, _turrret.angles_x + vtmp_x, _pichlimit_max);
+ vtmp.y = bound(-ftmp, vtmp.y, ftmp);
+ vtmp.x = bound(-ftmp, vtmp.x, ftmp);
+ _turrret.angles_y = bound(_rotlimit_min, _turrret.angles.y + vtmp.y, _rotlimit_max);
+ _turrret.angles_x = bound(_pichlimit_min, _turrret.angles.x + vtmp.x, _pichlimit_max);
return vtag;
}
-#include "../tturrets/include/turrets_early.qh"
-
+ #ifndef VEHICLES_DEF_H
+ #define VEHICLES_DEF_H
+
// #define VEHICLES_USE_ODE
#define VEHICLES_ENABLED
#ifdef VEHICLES_ENABLED
- .float vehicle_flags;
- const float VHF_ISVEHICLE = 2; /// Indicates vehicle
- const float VHF_HASSHIELD = 4; /// Vehicle has shileding
- const float VHF_SHIELDREGEN = 8; /// Vehicles shield regenerates
- const float VHF_HEALTHREGEN = 16; /// Vehicles health regenerates
- const float VHF_ENERGYREGEN = 32; /// Vehicles energy regenerates
- const float VHF_DEATHEJECT = 64; /// Vehicle ejects pilot upon fatal damage
- const float VHF_MOVE_GROUND = 128; /// Vehicle moves on gound
- const float VHF_MOVE_HOVER = 256; /// Vehicle hover close to gound
- const float VHF_MOVE_FLY = 512; /// Vehicle is airborn
- const float VHF_DMGSHAKE = 1024; /// Add random velocity each frame if health < 50%
- const float VHF_DMGROLL = 2048; /// Add random angles each frame if health < 50%
- const float VHF_DMGHEADROLL = 4096; /// Add random head angles each frame if health < 50%
- const float VHF_MULTISLOT = 8192; /// Vehicle has multiple player slots
- const float VHF_PLAYERSLOT = 16384; /// This ent is a player slot on a multi-person vehicle
+ .int vehicle_flags;
+ const int VHF_ISVEHICLE = 2; /// Indicates vehicle
+ const int VHF_HASSHIELD = 4; /// Vehicle has shileding
+ const int VHF_SHIELDREGEN = 8; /// Vehicles shield regenerates
+ const int VHF_HEALTHREGEN = 16; /// Vehicles health regenerates
+ const int VHF_ENERGYREGEN = 32; /// Vehicles energy regenerates
+ const int VHF_DEATHEJECT = 64; /// Vehicle ejects pilot upon fatal damage
+ const int VHF_MOVE_GROUND = 128; /// Vehicle moves on gound
+ const int VHF_MOVE_HOVER = 256; /// Vehicle hover close to gound
+ const int VHF_MOVE_FLY = 512; /// Vehicle is airborn
+ const int VHF_DMGSHAKE = 1024; /// Add random velocity each frame if health < 50%
+ const int VHF_DMGROLL = 2048; /// Add random angles each frame if health < 50%
+ const int VHF_DMGHEADROLL = 4096; /// Add random head angles each frame if health < 50%
+ const int VHF_MULTISLOT = 8192; /// Vehicle has multiple player slots
+ const int VHF_PLAYERSLOT = 16384; /// This ent is a player slot on a multi-person vehicle
.entity gun1;
.entity gun2;
.float vehicle_reload2; /// If self is player this field's use depends on the individual vehile. If self is vehile, this is the real reload2 value.
.float sound_nexttime;
- #define VOL_VEHICLEENGINE 1
+ const float VOL_VEHICLEENGINE = 1;
.float hud;
.float dmg_time;
.float vehicle_respawntime;
//.void() vehicle_spawn;
+.float volly_counter;
+
+.float tur_health;
+
void vehicles_exit(float eject);
.void(float exit_flags) vehicle_exit;
const float VHEF_NORMAL = 0; /// User pressed exit key
.void() vehicle_enter; /// Vehicles custom funciton to be executed when owner exit it
.void() vehicle_die; /// Vehicles custom function to be executed when vehile die
- #define VHSF_NORMAL 0
- #define VHSF_FACTORY 2
+ const float VHSF_NORMAL = 0;
+ const float VHSF_FACTORY = 2;
.void(float _spawnflag) vehicle_spawn; /// Vehicles custom fucntion to be efecuted when vehicle (re)spawns
.float(float _imp) vehicles_impulse;
.float vehicle_weapon2mode = volly_counter;
void(entity e, vector torque) physics_addtorque = #542; // add relative torque
#endif // VEHICLES_USE_ODE
#endif // VEHICLES_ENABLED
+ #endif