From: Mario Date: Tue, 14 Apr 2015 22:22:35 +0000 (+1000) Subject: Merge branch 'master' into Mario/turrets X-Git-Tag: xonotic-v0.8.2~2052^2~3 X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=commitdiff_plain;h=82dbcadfd0556053b74638f2e3ae2e57103ddf26;hp=-c Merge branch 'master' into Mario/turrets Conflicts: qcsrc/client/progs.src qcsrc/client/tturrets.qh qcsrc/server/mutators/gamemode_onslaught.qc qcsrc/server/progs.src qcsrc/server/tturrets/include/turrets.qh qcsrc/server/tturrets/include/turrets_early.qh qcsrc/server/tturrets/system/system_aimprocs.qc qcsrc/server/tturrets/system/system_damage.qc qcsrc/server/tturrets/system/system_misc.qc qcsrc/server/tturrets/units/unit_hellion.qc qcsrc/server/tturrets/units/unit_hk.qc qcsrc/server/tturrets/units/unit_mlrs.qc qcsrc/server/tturrets/units/unit_phaser.qc --- 82dbcadfd0556053b74638f2e3ae2e57103ddf26 diff --combined qcsrc/client/damage.qc index 0cbcfbd085,000ef8bcc9..e3660b21a2 --- a/qcsrc/client/damage.qc +++ b/qcsrc/client/damage.qc @@@ -1,3 -1,19 +1,19 @@@ + #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 @@@ -31,11 -47,12 +47,12 @@@ 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; @@@ -85,7 -102,7 +102,7 @@@ { 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 } @@@ -104,7 -121,9 +121,9 @@@ 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; @@@ -114,9 -133,9 +133,9 @@@ 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(); @@@ -185,7 -204,7 +204,7 @@@ 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; @@@ -310,7 -329,7 +329,7 @@@ 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; @@@ -329,9 -348,7 +348,7 @@@ 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); diff --combined qcsrc/client/main.qc index 0000000000,36ec4f7b8c..b753139c46 mode 000000,100644..100644 --- a/qcsrc/client/main.qc +++ b/qcsrc/client/main.qc @@@ -1,0 -1,1317 +1,1319 @@@ + #include "mapvoting.qh" + #include "modeleffects.qh" + #include "particles.qh" + #include "scoreboard.qh" + #include "shownames.qh" + #include "target_music.qh" -#include "tturrets.qh" + #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(); - turrets_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; + } diff --combined qcsrc/client/progs.src index d14edd5d36,f80da18d67..cdd0b09d1f --- a/qcsrc/client/progs.src +++ b/qcsrc/client/progs.src @@@ -1,136 -1,73 +1,76 @@@ ../../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 diff --combined qcsrc/client/tturrets.qc index ba640068ef,d2469851ca..0000000000 deleted file mode 100644,100644 --- a/qcsrc/client/tturrets.qc +++ /dev/null @@@ -1,685 -1,687 +1,0 @@@ -#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; --} diff --combined qcsrc/common/command/generic.qc index 2438c01736,7f302e0a27..460410c289 --- a/qcsrc/common/command/generic.qc +++ b/qcsrc/common/command/generic.qc @@@ -1,3 -1,6 +1,7 @@@ + #include "generic.qh" + #include "shared_defs.qh" ++#include "../turrets/config.qh" + // ========================================================= // Generic program common command code, written by Samual // Last updated: February 19th, 2012 @@@ -18,14 -21,11 +22,11 @@@ string GetProgramCommandPrefix(void } // 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); @@@ -56,8 -56,6 +57,6 @@@ void GenericCommand_addtolist(float req { case CMD_REQUEST_COMMAND: { - float i; - if(argc >= 2) { string original_cvar = argv(1); @@@ -70,7 -68,7 +69,7 @@@ 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 @@@ -99,18 -97,10 +98,10 @@@ void GenericCommand_qc_curl(float reque { 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) @@@ -121,7 -111,7 +112,7 @@@ } if(argv(i) == "--exec") { - do_exec = TRUE; + do_exec = true; continue; } if(argv(i) == "--key" && i+2 < argc) @@@ -135,15 -125,16 +126,16 @@@ // 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 @@@ -234,18 -225,18 +226,18 @@@ void GenericCommand_dumpnotifs(float re 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); @@@ -287,19 -278,19 +279,19 @@@ void GenericCommand_dumpweapons(float r 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(); @@@ -317,7 -308,7 +309,7 @@@ #endif return; } - + default: case CMD_REQUEST_USAGE: { @@@ -330,59 -321,6 +322,59 @@@ } } +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) @@@ -691,7 -629,6 +683,7 @@@ void GenericCommand_(float 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") \ @@@ -709,7 -646,7 +701,7 @@@ void GenericCommand_macro_help( #define GENERIC_COMMAND(name,function,description) \ { print(" ^2", name, "^7: ", description, "\n"); } - GENERIC_COMMANDS(0, 0, "") + GENERIC_COMMANDS(0, 0, ""); #undef GENERIC_COMMAND return; @@@ -718,23 -655,23 +710,23 @@@ 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) @@@ -742,7 -679,7 +734,7 @@@ #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; @@@ -768,13 -705,13 +760,13 @@@ float GenericCommand(string command 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) { @@@ -814,7 -751,7 +806,7 @@@ 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) { @@@ -849,8 -786,8 +841,8 @@@ localcmd(strcat(argv(1), " ", s2)); - return TRUE; + return true; } - return FALSE; + return false; } diff --combined qcsrc/common/deathtypes.qh index 602966cb38,301d665769..89afc0d96f --- a/qcsrc/common/deathtypes.qh +++ b/qcsrc/common/deathtypes.qh @@@ -1,7 -1,21 +1,21 @@@ + #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) \ @@@ -48,7 -62,7 +62,7 @@@ 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) \ @@@ -67,15 -81,14 +81,14 @@@ #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) \ @@@ -105,7 -118,7 +118,7 @@@ DEATHTYPE #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)) { @@@ -116,10 -129,11 +129,11 @@@ 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 diff --combined qcsrc/common/monsters/sv_monsters.qc index fd966f5d2e,28430e9617..4c443495fe --- a/qcsrc/common/monsters/sv_monsters.qc +++ b/qcsrc/common/monsters/sv_monsters.qc @@@ -1,3 -1,29 +1,27 @@@ + #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_early.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" - #include "../../server/tturrets/include/turrets.qh" + #endif + // ========================= // SVQC Monster Properties // ========================= @@@ -20,7 -46,7 +44,7 @@@ void monster_dropitem( if(e && e.monster_loot) { self = e; - e.noalign = TRUE; + e.noalign = true; e.monster_loot(); e.gravity = 1; e.movetype = MOVETYPE_TOSS; @@@ -44,58 -70,58 +68,58 @@@ float Monster_SkillModifier( 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) @@@ -106,10 -132,10 +130,10 @@@ dot = normalize (targ.origin - ent.origin) * v_forward; if(dot <= 0.3) - return FALSE; + return false; } - return TRUE; + return true; } entity FindTarget (entity ent) @@@ -118,7 -144,7 +142,7 @@@ 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 { @@@ -198,7 -224,7 +222,7 @@@ void precache_monstersounds( 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); @@@ -257,7 -283,7 +281,7 @@@ float LoadMonsterSounds(string f, floa return 1; } - .float skin_for_monstersound; + .int skin_for_monstersound; void UpdateMonsterSounds() { entity mon = get_monsterinfo(self.monsterid); @@@ -290,7 -316,7 +314,7 @@@ void monster_makevectors(entity e 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); } @@@ -298,7 -324,7 +322,7 @@@ 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) { @@@ -319,7 -345,7 +343,7 @@@ 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 () @@@ -344,18 -370,17 +368,17 @@@ float Monster_CanRespawn(entity ent 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? @@@ -395,13 -420,13 +418,13 @@@ void Monster_Fade ( 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; @@@ -409,15 -434,15 +432,15 @@@ 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; @@@ -428,7 -453,7 +451,7 @@@ self.attack_finished_single = time + anim_finished; - return TRUE; + return true; } void monster_checkattack(entity e, entity targ) @@@ -447,14 -472,14 +470,14 @@@ 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; } } @@@ -477,7 -502,7 +500,7 @@@ vector monster_pickmovetarget(entity ta 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) @@@ -491,19 -516,19 +514,19 @@@ 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; @@@ -551,9 -576,9 +574,9 @@@ 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; } } @@@ -564,7 -589,7 +587,7 @@@ 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"); @@@ -656,7 -681,7 +679,7 @@@ void monster_move(float runspeed, floa { 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'); @@@ -682,7 -707,7 +705,7 @@@ } else if(self.fish_wasdrowning) { - self.fish_wasdrowning = FALSE; + self.fish_wasdrowning = false; self.angles_x = 0; self.movetype = MOVETYPE_WALK; } @@@ -728,9 -753,9 +751,9 @@@ 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); } } @@@ -745,7 -770,7 +768,7 @@@ 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)) { @@@ -762,13 -787,13 +785,13 @@@ 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 @@@ -795,16 -820,16 +818,16 @@@ 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; } @@@ -859,7 -884,7 +882,7 @@@ void Monster_Appear( 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) @@@ -867,7 -892,7 +890,7 @@@ ent.use = Monster_Appear; ent.flags = FL_MONSTER; // set so this monster can get butchered - return TRUE; + return true; } void monsters_reset() @@@ -918,7 -943,7 +941,7 @@@ void monster_die(entity attacker, floa 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; @@@ -975,8 -1000,8 +998,8 @@@ void monsters_damage (entity inflictor 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; @@@ -1001,7 -1026,7 +1024,7 @@@ 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; @@@ -1053,11 -1078,11 +1076,11 @@@ void monster_setupcolors(entity mon 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')); @@@ -1114,11 -1139,11 +1137,11 @@@ float monster_spawn( 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); @@@ -1129,16 -1154,16 +1152,16 @@@ 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); @@@ -1146,9 -1171,9 +1169,9 @@@ 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; @@@ -1161,10 -1186,10 +1184,10 @@@ //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; @@@ -1181,8 -1206,8 +1204,8 @@@ 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; @@@ -1216,7 -1241,7 +1239,7 @@@ 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) @@@ -1244,12 -1269,12 +1267,12 @@@ } if(!monster_spawn()) - return FALSE; + return false; if(!(self.spawnflags & MONSTERFLAG_RESPAWNED)) monster_setupcolors(self); CSQCMODEL_AUTOINIT(); - return TRUE; + return true; } diff --combined qcsrc/common/nades.qc index 03b15525cf,4225a19f03..07a91a8ccd --- a/qcsrc/common/nades.qc +++ b/qcsrc/common/nades.qc @@@ -1,17 -1,31 +1,30 @@@ - .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); @@@ -20,7 -34,7 +33,7 @@@ WriteByte(MSG_ENTITY, (self.ltime - time)*10.0+0.5); } - return TRUE; + return true; } #endif // SVQC @@@ -43,8 -57,8 +56,8 @@@ void healer_setup( 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; @@@ -62,7 -76,7 +75,7 @@@ void ent_healer() { - float sf = ReadByte(); + int sf = ReadByte(); if(sf & TNSF_SETUP) { @@@ -79,4 -93,4 +92,4 @@@ healer_setup(); } } - #endif // CSQC + #endif // CSQC diff --combined qcsrc/common/notifications.qh index 7795dc2725,1cb1adf51f..dd43575c3b --- a/qcsrc/common/notifications.qh +++ b/qcsrc/common/notifications.qh @@@ -1,19 -1,25 +1,25 @@@ + #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) \ @@@ -45,11 -51,11 +51,11 @@@ void Destroy_All_Notifications(void) 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, @@@ -80,7 -86,7 +86,7 @@@ void Dump_Notifications(float fh, floa 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, @@@ -94,12 -100,12 +100,12 @@@ float prev_soundtime #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, @@@ -431,7 -437,7 +437,7 @@@ void Send_Notification_WOCOVA 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"), "") \ @@@ -728,7 -734,7 +734,7 @@@ 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) \ @@@ -818,7 -824,7 +824,7 @@@ 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) \ @@@ -934,32 -940,32 +940,32 @@@ // 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 @@@ -1013,18 -1019,18 +1019,18 @@@ 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? @@@ -1054,7 -1060,7 +1060,7 @@@ 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) : "")) \ @@@ -1068,7 -1074,9 +1074,9 @@@ 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 \ @@@ -1092,9 -1100,9 +1100,9 @@@ string notif_arg_frag_ping(float newlin 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) @@@ -1269,21 -1277,52 +1277,52 @@@ string notif_arg_spree_inf(float type, // 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]; @@@ -1298,8 -1337,8 +1337,8 @@@ entity msg_choice_notifs[NOTIF_CHOICE_M .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; @@@ -1352,7 -1391,7 +1391,7 @@@ float notif_global_error /* COMMON ======================== */ \ default, /* var_default */ \ ACVNN(name), /* var_cvar */ \ - MSG_ANNCE, /* typeid */ \ + MSG_ANNCE, /* typeId */ \ name, /* nameid */ \ strtoupper(#name), /* namestring */ \ NO_MSG, /* strnum */ \ @@@ -1385,7 -1424,7 +1424,7 @@@ #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) \ @@@ -1394,7 -1433,7 +1433,7 @@@ /* COMMON ======================== */ \ default, /* var_default */ \ ACVNN(name), /* var_cvar */ \ - MSG_INFO, /* typeid */ \ + MSG_INFO, /* typeId */ \ name, /* nameid */ \ strtoupper(#name), /* namestring */ \ strnum, /* strnum */ \ @@@ -1428,17 -1467,15 +1467,15 @@@ #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 */ \ @@@ -1471,7 -1508,7 +1508,7 @@@ #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) \ @@@ -1480,7 -1517,7 +1517,7 @@@ /* COMMON ======================== */ \ default, /* var_default */ \ ACVNN(name), /* var_cvar */ \ - MSG_MULTI, /* typeid */ \ + MSG_MULTI, /* typeId */ \ name, /* nameid */ \ strtoupper(#name), /* namestring */ \ NO_MSG, /* strnum */ \ @@@ -1525,7 -1562,7 +1562,7 @@@ /* COMMON ======================== */ \ default, /* var_default */ \ ACVNN(name), /* var_cvar */ \ - MSG_CHOICE, /* typeid */ \ + MSG_CHOICE, /* typeId */ \ name, /* nameid */ \ strtoupper(#name), /* namestring */ \ NO_MSG, /* strnum */ \ @@@ -1558,7 -1595,7 +1595,7 @@@ void RegisterNotifications_First() { - notif_global_error = FALSE; + notif_global_error = false; #ifdef SVQC #define dedi (server_is_dedicated ? "a dedicated " : "") @@@ -1577,7 -1614,7 +1614,7 @@@ #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); @@@ -1612,3 -1649,4 +1649,4 @@@ ACCUMULATE_FUNCTION(RegisterNotificatio #undef MSG_CHOICE_NOTIF #undef NOTIF_ADD_AUTOCVAR + #endif diff --combined qcsrc/common/turrets/cl_turrets.qc index 3365b92029,0000000000..2f8e77d2d2 mode 100644,000000..100644 --- a/qcsrc/common/turrets/cl_turrets.qc +++ b/qcsrc/common/turrets/cl_turrets.qc @@@ -1,446 -1,0 +1,445 @@@ +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 + ); +} + - void(entity e, entity tagentity, string tagname) setattachment = #443; +void turret_construct() +{ + entity tur = get_turretinfo(self.turretid); + + if(self.tur_head == world) + self.tur_head = spawn(); + + self.netname = TUR_NAME(self.turretid); + + setorigin(self, self.origin); + setmodel(self, tur.model); + setmodel(self.tur_head, tur.head_model); + setsize(self, tur.mins, tur.maxs); + setsize(self.tur_head, '0 0 0', '0 0 0'); + + if(self.turretid == TUR_EWHEEL) + setattachment(self.tur_head, self, ""); + else + setattachment(self.tur_head, self, "tag_head"); + + self.tur_head.classname = "turret_head"; + self.tur_head.owner = self; + self.tur_head.move_movetype = MOVETYPE_NOCLIP; + self.move_movetype = MOVETYPE_NOCLIP; + self.tur_head.angles = self.angles; + self.health = 255; + self.solid = SOLID_BBOX; + self.tur_head.solid = SOLID_NOT; + self.movetype = MOVETYPE_NOCLIP; + self.tur_head.movetype = MOVETYPE_NOCLIP; + self.draw = turret_draw; + self.entremove = turret_remove; + self.drawmask = MASK_NORMAL; + self.tur_head.drawmask = MASK_NORMAL; + self.anim_start_time = 0; + self.draw2d = turret_draw2d; + self.maxdistance = autocvar_g_waypointsprite_turrets_maxdist; + self.teamradar_color = '1 0 0'; + self.alpha = 1; + + TUR_ACTION(self.turretid, TR_SETUP); +} + +entity turret_gibtoss(string _model, vector _from, vector _to, vector _cmod, float _explode); +void turret_gibboom(); +void turret_gib_draw() +{ + Movetype_Physics_MatchTicrate(autocvar_cl_gibs_ticrate, autocvar_cl_gibs_sloppy); + + self.drawmask = MASK_NORMAL; + + if(self.cnt) + { + if(time >= self.nextthink) + { + turret_gibboom(); + remove(self); + } + } + else + { + self.alpha = bound(0, self.nextthink - time, 1); + if(self.alpha < ALPHA_MIN_VISIBLE) + remove(self); + } +} + +void turret_gibboom() +{ + float i; + + sound (self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM); + pointparticles(particleeffectnum("rocket_explode"), self.origin, '0 0 0', 1); + + for (i = 1; i < 5; i = i + 1) - turret_gibtoss(strcat("models/turrets/head-gib", ftos(i), ".md3"), self.origin + '0 0 2', self.velocity + randomvec() * 700, '0 0 0', FALSE); ++ turret_gibtoss(strcat("models/turrets/head-gib", ftos(i), ".md3"), self.origin + '0 0 2', self.velocity + randomvec() * 700, '0 0 0', false); +} + +entity turret_gibtoss(string _model, vector _from, vector _to, vector _cmod, float _explode) +{ + entity gib; + + traceline(_from, _to, MOVE_NOMONSTERS, world); + if(trace_startsolid) + return world; + + gib = spawn(); + setorigin(gib, _from); + setmodel(gib, _model); + gib.colormod = _cmod; + gib.solid = SOLID_CORPSE; + gib.draw = turret_gib_draw; + gib.cnt = _explode; + setsize(gib, '-1 -1 -1', '1 1 1'); + if(_explode) + { + gib.nextthink = time + 0.2 * (autocvar_cl_gibs_lifetime * (1 + prandom() * 0.15)); + gib.effects = EF_FLAME; + } + else + gib.nextthink = time + autocvar_cl_gibs_lifetime * (1 + prandom() * 0.15); + + gib.gravity = 1; + gib.move_movetype = MOVETYPE_BOUNCE; + gib.move_origin = _from; + setorigin(gib, _from); + gib.move_velocity = _to; + gib.move_avelocity = prandomvec() * 32; + gib.move_time = time; + gib.damageforcescale = 1; + gib.classname = "turret_gib"; + + return gib; +} + +void turret_die() +{ + sound (self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM); + pointparticles(particleeffectnum("rocket_explode"), self.origin, '0 0 0', 1); + if (!autocvar_cl_nogibs) + { + // Base + if(self.turretid == TUR_EWHEEL) - turret_gibtoss((get_turretinfo(self.turretid)).model, self.origin + '0 0 18', self.velocity + '0 0 400' + '0.1 0.1 1' * (random() * 400), '-1 -1 -1', TRUE); ++ turret_gibtoss((get_turretinfo(self.turretid)).model, self.origin + '0 0 18', self.velocity + '0 0 400' + '0.1 0.1 1' * (random() * 400), '-1 -1 -1', true); + else if (self.turretid == TUR_WALKER) - turret_gibtoss((get_turretinfo(self.turretid)).model, self.origin + '0 0 18', self.velocity + '0 0 300' + '0.1 0.1 1' * (random() * 200), '-1 -1 -1', TRUE); ++ turret_gibtoss((get_turretinfo(self.turretid)).model, self.origin + '0 0 18', self.velocity + '0 0 300' + '0.1 0.1 1' * (random() * 200), '-1 -1 -1', true); + else if (self.turretid == TUR_TESLA) - turret_gibtoss((get_turretinfo(self.turretid)).model, self.origin + '0 0 18', '0 0 200', '-1 -1 -1', FALSE); ++ turret_gibtoss((get_turretinfo(self.turretid)).model, self.origin + '0 0 18', '0 0 200', '-1 -1 -1', false); + else + { + if (random() > 0.5) + { - turret_gibtoss("models/turrets/base-gib2.md3", self.origin + '0 0 8', '0 0 50' + randomvec() * 150, '0 0 0', FALSE); - turret_gibtoss("models/turrets/base-gib3.md3", self.origin + '0 0 8', '0 0 50' + randomvec() * 150, '0 0 0', FALSE); - turret_gibtoss("models/turrets/base-gib4.md3", self.origin + '0 0 8', '0 0 50' + randomvec() * 150, '0 0 0', FALSE); ++ 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((get_turretinfo(self.turretid)).head_model, self.origin + '0 0 32', '0 0 200' + randomvec() * 200, '-1 -1 -1', 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; +} diff --combined qcsrc/common/turrets/cl_turrets.qh index b616782187,0000000000..0f8ff94851 mode 100644,000000..100644 --- a/qcsrc/common/turrets/cl_turrets.qh +++ b/qcsrc/common/turrets/cl_turrets.qh @@@ -1,1 -1,0 +1,6 @@@ ++#ifndef CL_TURRETS_H ++#define CL_TURRETS_H ++ +void ent_turret(); ++ ++#endif diff --combined qcsrc/common/turrets/config.qh index ad3a0c72fe,0000000000..85cbd2006c mode 100644,000000..100644 --- a/qcsrc/common/turrets/config.qh +++ b/qcsrc/common/turrets/config.qh @@@ -1,29 -1,0 +1,34 @@@ - // ========================== - // 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 diff --combined qcsrc/common/turrets/sv_turrets.qc index aca2b8ead7,0000000000..91d427fd80 mode 100644,000000..100644 --- a/qcsrc/common/turrets/sv_turrets.qc +++ b/qcsrc/common/turrets/sv_turrets.qc @@@ -1,1396 -1,0 +1,1394 @@@ - // ========================= - // 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 diff --combined qcsrc/common/turrets/sv_turrets.qh index f89ef1581b,0000000000..c4ff13e91d mode 100644,000000..100644 --- a/qcsrc/common/turrets/sv_turrets.qh +++ b/qcsrc/common/turrets/sv_turrets.qh @@@ -1,106 -1,0 +1,113 @@@ ++#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 diff --combined qcsrc/common/turrets/turrets.qh index 5491746e9c,0000000000..b3736aff9c mode 100644,000000..100644 --- a/qcsrc/common/turrets/turrets.qh +++ b/qcsrc/common/turrets/turrets.qh @@@ -1,197 -1,0 +1,202 @@@ ++#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: - entity get_turretinfo(float id); ++entity get_turretinfo(int id); + +// fields: +.entity tur_head; + +// target selection flags - .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 ++.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 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 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 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 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 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 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 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 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 - .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 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 - 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 ++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 - .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 ++.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 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 ++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_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 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_ANIM = 128; ++const int TNSF_ANIM = 128; + - const float TNSF_FULL_UPDATE = 16777215; ++const int TNSF_FULL_UPDATE = 16777215; + + +// entity properties of turretinfo: - .float turretid; // TUR_... ++.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 diff --combined qcsrc/common/turrets/unit/ewheel.qc index 1c2dc55645,0000000000..414ec4e822 mode 100644,000000..100644 --- a/qcsrc/common/turrets/unit/ewheel.qc +++ b/qcsrc/common/turrets/unit/ewheel.qc @@@ -1,311 -1,0 +1,311 @@@ +#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)); + } + - turrets_setframe(newframe, FALSE); ++ 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; + - return 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.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; + 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; ++ return true; +} + +#endif // CSQC +#endif // REGISTER_TURRET diff --combined qcsrc/common/turrets/unit/flac.qc index 8c131e76e0,0000000000..8068ab1d7e mode 100644,000000..100644 --- a/qcsrc/common/turrets/unit/flac.qc +++ b/qcsrc/common/turrets/unit/flac.qc @@@ -1,103 -1,0 +1,103 @@@ +#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; ++ return true; +} + +#endif // CSQC +#endif // REGISTER_TURRET diff --combined qcsrc/common/turrets/unit/fusionreactor.qc index d2a3c408e5,0000000000..db49745667 mode 100644,000000..100644 --- a/qcsrc/common/turrets/unit/fusionreactor.qc +++ b/qcsrc/common/turrets/unit/fusionreactor.qc @@@ -1,116 -1,0 +1,116 @@@ +#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; ++ return true; +} + +#endif // CSQC +#endif // REGISTER_TURRET diff --combined qcsrc/common/turrets/unit/hellion.qc index 57dca3b791,0000000000..d090ef7ce5 mode 100644,000000..100644 --- a/qcsrc/common/turrets/unit/hellion.qc +++ b/qcsrc/common/turrets/unit/hellion.qc @@@ -1,160 -1,0 +1,160 @@@ +#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; ++ return true; +} + +#endif // CSQC +#endif // REGISTER_TURRET diff --combined qcsrc/common/turrets/unit/hk.qc index c0f55fa0f0,0000000000..414c71e4b8 mode 100644,000000..100644 --- a/qcsrc/common/turrets/unit/hk.qc +++ b/qcsrc/common/turrets/unit/hk.qc @@@ -1,361 -1,0 +1,361 @@@ +#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, pre_pos,TRUE,self.enemy); ++ traceline(self.origin, pre_pos,true,self.enemy); + ve = normalize(pre_pos - self.origin); + fe = trace_fraction; + + } + else + { + edist = 0; + ve = '0 0 0'; + fe = 0; + } + + if ((fe != 1) || (self.enemy == world) || (edist > 1000)) + { + myspeed = vlen(self.velocity); + + lt_for = myspeed * 3; + lt_seek = myspeed * 2.95; + + // Trace forward - traceline(self.origin, self.origin + v_forward * lt_for,FALSE,self); ++ traceline(self.origin, self.origin + v_forward * lt_for,false,self); + vf = trace_endpos; + ff = trace_fraction; + + // Find angular offset + ad = vlen(vectoangles(normalize(self.enemy.origin - self.origin)) - self.angles); + + // To close to something, Slow down! + if ( ((ff < 0.7) || (ad > 4)) && (myspeed > (autocvar_g_turrets_unit_hk_shot_speed)) ) + myspeed = max(myspeed * (autocvar_g_turrets_unit_hk_shot_speed_decel), (autocvar_g_turrets_unit_hk_shot_speed)); + + // Failry clear, accelerate. + if ( (ff > 0.7) && (myspeed < (autocvar_g_turrets_unit_hk_shot_speed_max)) ) + myspeed = min(myspeed * (autocvar_g_turrets_unit_hk_shot_speed_accel), (autocvar_g_turrets_unit_hk_shot_speed_max)); + + // Setup trace pitch + pt_seek = 1 - ff; + pt_seek = bound(0.15,pt_seek,0.8); + if (ff < 0.5) pt_seek = 1; + + // Trace left - traceline(self.origin, self.origin + (-1 * (v_right * pt_seek) + (v_forward * ff)) * lt_seek,FALSE,self); ++ traceline(self.origin, self.origin + (-1 * (v_right * pt_seek) + (v_forward * ff)) * lt_seek,false,self); + vl = trace_endpos; + fl = trace_fraction; + + // Trace right - traceline(self.origin, self.origin + ((v_right * pt_seek) + (v_forward * ff)) * lt_seek ,FALSE,self); ++ traceline(self.origin, self.origin + ((v_right * pt_seek) + (v_forward * ff)) * lt_seek ,false,self); + vr = trace_endpos; + fr = trace_fraction; + + // Trace up - traceline(self.origin, self.origin + ((v_up * pt_seek) + (v_forward * ff)) * lt_seek ,FALSE,self); ++ traceline(self.origin, self.origin + ((v_up * pt_seek) + (v_forward * ff)) * lt_seek ,false,self); + vu = trace_endpos; + fu = trace_fraction; + + // Trace down - traceline(self.origin, self.origin + (-1 * (v_up * pt_seek) + (v_forward * ff)) * lt_seek ,FALSE,self); ++ 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; ++ return true; +} + +#endif // CSQC +#endif // REGISTER_TURRET diff --combined qcsrc/common/turrets/unit/machinegun.qc index 26cbc48828,0000000000..f4a46212fc mode 100644,000000..100644 --- a/qcsrc/common/turrets/unit/machinegun.qc +++ b/qcsrc/common/turrets/unit/machinegun.qc @@@ -1,79 -1,0 +1,79 @@@ +#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; ++ return true; +} + +#endif // CSQC +#endif // REGISTER_TURRET diff --combined qcsrc/common/turrets/unit/mlrs.qc index fa3c30efcd,0000000000..254a589484 mode 100644,000000..100644 --- a/qcsrc/common/turrets/unit/mlrs.qc +++ b/qcsrc/common/turrets/unit/mlrs.qc @@@ -1,90 -1,0 +1,90 @@@ +#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; ++ return true; +} + +#endif // CSQC +#endif // REGISTER_TURRET diff --combined qcsrc/common/turrets/unit/phaser.qc index 441e041c73,0000000000..32c392b664 mode 100644,000000..100644 --- a/qcsrc/common/turrets/unit/phaser.qc +++ b/qcsrc/common/turrets/unit/phaser.qc @@@ -1,173 -1,0 +1,173 @@@ +#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; - beam.bot_dodge = 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; ++ return true; +} + +#endif // CSQC +#endif // REGISTER_TURRET diff --combined qcsrc/common/turrets/unit/plasma.qc index ac623371f5,0000000000..095aa9d02d mode 100644,000000..100644 --- a/qcsrc/common/turrets/unit/plasma.qc +++ b/qcsrc/common/turrets/unit/plasma.qc @@@ -1,111 -1,0 +1,111 @@@ +#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; ++ return true; +} + +#endif // CSQC +#endif // REGISTER_TURRET diff --combined qcsrc/common/turrets/unit/plasma_dual.qc index 279b41ec40,0000000000..110ae1dea7 mode 100644,000000..100644 --- a/qcsrc/common/turrets/unit/plasma_dual.qc +++ b/qcsrc/common/turrets/unit/plasma_dual.qc @@@ -1,109 -1,0 +1,109 @@@ +#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; ++ return true; +} + +#endif // CSQC +#endif // REGISTER_TURRET diff --combined qcsrc/common/turrets/unit/tesla.qc index 2878c31878,0000000000..61a9f5e304 mode 100644,000000..100644 --- a/qcsrc/common/turrets/unit/tesla.qc +++ b/qcsrc/common/turrets/unit/tesla.qc @@@ -1,217 -1,0 +1,217 @@@ +#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); + - if (t == world) 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; ++ return true; +} + +#endif // CSQC +#endif // REGISTER_TURRET diff --combined qcsrc/common/turrets/unit/walker.qc index fa89d5a3e4,0000000000..0d5d317057 mode 100644,000000..100644 --- a/qcsrc/common/turrets/unit/walker.qc +++ b/qcsrc/common/turrets/unit/walker.qc @@@ -1,696 -1,0 +1,698 @@@ +#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() +{ - 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_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; - 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_rocket_speed); + rocket.angles = vectoangles(rocket.velocity); + rocket.touch = walker_rocket_explode; + rocket.flags = FL_PROJECTILE; + rocket.solid = SOLID_BBOX; + rocket.max_health = time + 9; + rocket.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_GUIDED_HEAT; + - CSQCProjectile(rocket, FALSE, PROJECTILE_ROCKET, FALSE); // no culling, has fly sound ++ 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); + - return TRUE; ++ return true; + } + case TR_THINK: + { + fixedmakevectors(self.angles); + + if (self.spawnflags & TSF_NO_PATHBREAK && self.pathcurrent) + walker_move_path(); + else if (self.enemy == world) + { + if(self.pathcurrent) + walker_move_path(); + else + { + if(self.enemy_last_time != 0) + { + if(vlen(self.origin - self.enemy_last_loc) < 128 || time - self.enemy_last_time > 10) + self.enemy_last_time = 0; + else + walker_move_to(self.enemy_last_loc, 0); + } + else + { + if(self.animflag != ANIM_NO) + { + traceline(self.origin + '0 0 64', self.origin + '0 0 64' + v_forward * 128, MOVE_NORMAL, self); + + if(trace_fraction != 1.0) + self.tur_head.idletime = -1337; + else + { + traceline(trace_endpos, trace_endpos - '0 0 256', MOVE_NORMAL, self); + if(trace_fraction == 1.0) + self.tur_head.idletime = -1337; + } + + if(self.tur_head.idletime == -1337) + { + self.moveto = self.origin + randomvec() * 256; + self.tur_head.idletime = 0; + } + + self.moveto = self.moveto * 0.9 + ((self.origin + v_forward * 500) + randomvec() * 400) * 0.1; + self.moveto_z = self.origin_z + 64; + walker_move_to(self.moveto, 0); + } + + if(self.idletime < time) + { + if(random() < 0.5 || !(self.spawnflags & TSL_ROAM)) + { + self.idletime = time + 1 + random() * 5; + self.moveto = self.origin; + self.animflag = ANIM_NO; + } + else + { + self.animflag = ANIM_WALK; + self.idletime = time + 4 + random() * 2; + self.moveto = self.origin + randomvec() * 256; + self.tur_head.moveto = self.moveto; + self.tur_head.idletime = 0; + } + } + } + } + } + else + { + if (self.tur_dist_enemy < (autocvar_g_turrets_unit_walker_melee_range) && self.animflag != ANIM_MELEE) + { + vector wish_angle; + + wish_angle = angleofs(self, self.enemy); + if (self.animflag != ANIM_SWIM) + if (fabs(wish_angle_y) < 15) + { + self.moveto = self.enemy.origin; + self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95); + self.animflag = ANIM_MELEE; + } + } + else if (self.tur_head.attack_finished_single < time) + { + if(self.tur_head.shot_volly) + { + self.animflag = ANIM_NO; + + self.tur_head.shot_volly = self.tur_head.shot_volly -1; + if(self.tur_head.shot_volly == 0) + self.tur_head.attack_finished_single = time + (autocvar_g_turrets_unit_walker_rocket_refire); + else + self.tur_head.attack_finished_single = time + 0.2; + + if(self.tur_head.shot_volly > 1) + walker_fire_rocket(gettaginfo(self, gettagindex(self, "tag_rocket01"))); + else + walker_fire_rocket(gettaginfo(self, gettagindex(self, "tag_rocket02"))); + } + else + { + if (self.tur_dist_enemy > (autocvar_g_turrets_unit_walker_rocket_range_min)) + if (self.tur_dist_enemy < (autocvar_g_turrets_unit_walker_rocket_range)) + self.tur_head.shot_volly = 4; + } + } + else + { + if (self.animflag != ANIM_MELEE) + walker_move_to(self.enemy.origin, self.tur_dist_enemy); + } + } + + { + vector real_angle; + float turny = 0, turnx = 0; + float vz; + + real_angle = vectoangles(self.steerto) - self.angles; + vz = self.velocity_z; + + switch (self.animflag) + { + case ANIM_NO: + movelib_beak_simple((autocvar_g_turrets_unit_walker_speed_stop)); + break; + + case ANIM_TURN: + turny = (autocvar_g_turrets_unit_walker_turn); + movelib_beak_simple((autocvar_g_turrets_unit_walker_speed_stop)); + break; + + case ANIM_WALK: + turny = (autocvar_g_turrets_unit_walker_turn_walk); + movelib_move_simple(v_forward, (autocvar_g_turrets_unit_walker_speed_walk), 0.6); + break; + + case ANIM_RUN: + turny = (autocvar_g_turrets_unit_walker_turn_run); + movelib_move_simple(v_forward, (autocvar_g_turrets_unit_walker_speed_run), 0.6); + break; + + case ANIM_STRAFE_L: + turny = (autocvar_g_turrets_unit_walker_turn_strafe); + movelib_move_simple(v_right * -1, (autocvar_g_turrets_unit_walker_speed_walk), 0.8); + break; + + case ANIM_STRAFE_R: + turny = (autocvar_g_turrets_unit_walker_turn_strafe); + movelib_move_simple(v_right, (autocvar_g_turrets_unit_walker_speed_walk), 0.8); + break; + + case ANIM_JUMP: + self.velocity += '0 0 1' * (autocvar_g_turrets_unit_walker_speed_jump); + break; + + case ANIM_LAND: + break; + + case ANIM_PAIN: + if(self.frame != ANIM_PAIN) + defer(0.25, walker_setnoanim); + + break; + + case ANIM_MELEE: + if(self.frame != ANIM_MELEE) + { + defer(0.41, walker_setnoanim); + defer(0.21, walker_melee_do_dmg); + } + + movelib_beak_simple((autocvar_g_turrets_unit_walker_speed_stop)); + break; + + case ANIM_SWIM: + turny = (autocvar_g_turrets_unit_walker_turn_swim); + turnx = (autocvar_g_turrets_unit_walker_turn_swim); + + self.angles_x += bound(-10, shortangle_f(real_angle_x, self.angles_x), 10); + movelib_move_simple(v_forward, (autocvar_g_turrets_unit_walker_speed_swim), 0.3); + vz = self.velocity_z + sin(time * 4) * 8; + break; + + case ANIM_ROAM: + turny = (autocvar_g_turrets_unit_walker_turn_walk); + movelib_move_simple(v_forward ,(autocvar_g_turrets_unit_walker_speed_roam), 0.5); + break; + } + + if(turny) + { + turny = bound( turny * -1, shortangle_f(real_angle_y, self.angles_y), turny ); + self.angles_y += turny; + } + + if(turnx) + { + turnx = bound( turnx * -1, shortangle_f(real_angle_x, self.angles_x), turnx ); + self.angles_x += turnx; + } + + self.velocity_z = vz; + } + + + if(self.origin != self.oldorigin) + self.SendFlags |= TNSF_MOVE; + + self.oldorigin = self.origin; - turrets_setframe(self.animflag, FALSE); ++ 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; + - return 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.iscreature = TRUE; ++ self.iscreature = true; + self.teleportable = TELEPORT_NORMAL; - self.damagedbycontents = 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; ++ return true; +} + +#endif // CSQC +#endif // REGISTER_TURRET diff --combined qcsrc/common/turrets/util.qc index 6de59027e3,0000000000..3d6d95a76a mode 100644,000000..100644 --- a/qcsrc/common/turrets/util.qc +++ b/qcsrc/common/turrets/util.qc @@@ -1,331 -1,0 +1,330 @@@ +/* +* 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. +*/ - #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() ++float turret_tag_fire_update() +{ + if(!self.tur_head) + { + error("Call to turret_tag_fire_update with self.tur_head missing!\n"); + self.tur_shotorg = '0 0 0'; - return FALSE; ++ return false; + } + + self.tur_shotorg = gettaginfo(self.tur_head, gettagindex(self.tur_head, "tag_fire")); + v_forward = normalize(v_forward); + - return TRUE; ++ 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) + { - tracebox(start, smin, smax, end, FALSE, self); ++ tracebox(start, smin, smax, end, false, self); + + // if it is world we can't hurt it so stop now + if (trace_ent == world || trace_fraction == 1) + break; + + if (trace_ent.solid == SOLID_BSP) + break; + + // make the entity non-solid so we can hit the next one - trace_ent.railgunhit = TRUE; ++ trace_ent.railgunhit = true; + trace_ent.railgunhitloc = end; + trace_ent.railgunhitsolidbackup = trace_ent.solid; + + // stop if this is a wall + + // make the entity non-solid + trace_ent.solid = SOLID_NOT; + } + + endpoint = trace_endpos; + + // find all the entities the railgun hit and restore their solid state - ent = findfloat(world, railgunhit, TRUE); ++ ent = findfloat(world, railgunhit, true); + while (ent) + { + // restore their solid type + ent.solid = ent.railgunhitsolidbackup; - ent = findfloat(ent, railgunhit, TRUE); ++ ent = findfloat(ent, railgunhit, true); + } + + // find all the entities the railgun hit and hurt them - ent = findfloat(world, railgunhit, TRUE); ++ ent = findfloat(world, railgunhit, true); + while (ent) + { + // get the details we need to call the damage function + hitloc = ent.railgunhitloc; + ent.railgunhitloc = '0 0 0'; + ent.railgunhitsolidbackup = SOLID_NOT; - ent.railgunhit = FALSE; ++ 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); ++ 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 diff --combined qcsrc/common/turrets/util.qh index 0000000000,0000000000..71ba0662e6 new file mode 100644 --- /dev/null +++ b/qcsrc/common/turrets/util.qh @@@ -1,0 -1,0 +1,13 @@@ ++#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 diff --combined qcsrc/server/autocvars.qh index f960c4220c,015c13f148..69e523c0c4 --- a/qcsrc/server/autocvars.qh +++ b/qcsrc/server/autocvars.qh @@@ -1,9 -1,12 +1,12 @@@ - 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; @@@ -43,63 -46,63 +46,63 @@@ float autocvar_bot_ai_navigation_jetpac 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; @@@ -400,7 -403,7 +403,7 @@@ float autocvar_g_instagib_invis_alpha #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; @@@ -507,6 -510,41 +510,6 @@@ float autocvar_g_turrets_nofire 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; @@@ -548,7 -586,7 +551,7 @@@ float autocvar_snd_soundradius 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; @@@ -747,6 -785,7 +750,7 @@@ float autocvar_g_random_gravity_positiv 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; @@@ -760,7 -799,7 +764,7 @@@ float autocvar_g_nades_nade_edgedamage float autocvar_g_nades_nade_radius; float autocvar_g_nades_nade_force; float autocvar_g_nades_nade_newton_style; - 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; @@@ -844,4 -883,4 +848,4 @@@ float autocvar_g_buffs_vampire_damage_s float autocvar_g_buffs_invisible_alpha; float autocvar_g_buffs_flight_gravity; float autocvar_g_buffs_jump_height; - + #endif diff --combined qcsrc/server/g_damage.qc index 3f5ba0d621,d170cf4c02..aab2f9ced5 --- a/qcsrc/server/g_damage.qc +++ b/qcsrc/server/g_damage.qc @@@ -1,21 -1,45 +1,46 @@@ - .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) @@@ -39,23 -63,9 +64,9 @@@ 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) @@@ -73,9 -83,6 +84,6 @@@ void UpdateFrags(entity player, float f 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 @@@ -275,7 -282,6 +283,6 @@@ void Obituary_SpecialDeath else { backtrace("Obituary_SpecialDeath called without a special deathtype?\n"); return; } } - float w_deathtype; float Obituary_WeaponDeath( entity notif_target, float murder, @@@ -288,7 -294,7 +295,7 @@@ { w_deathtype = deathtype; float death_message = WEP_ACTION(death_weapon, ((murder) ? WR_KILLMESSAGE : WR_SUICIDEMESSAGE)); - w_deathtype = FALSE; + w_deathtype = false; if(death_message) { @@@ -318,9 -324,9 +325,9 @@@ ); } - return TRUE; + return true; } - return FALSE; + return false; } void Obituary(entity attacker, entity inflictor, entity targ, float deathtype) @@@ -329,7 -335,7 +336,7 @@@ 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 @@@ -359,7 -365,7 +366,7 @@@ { 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 { @@@ -367,19 -373,19 +374,19 @@@ { 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; @@@ -431,8 -437,8 +438,8 @@@ 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); @@@ -493,8 -499,8 +500,8 @@@ ); } - 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); } } @@@ -518,7 -524,7 +525,7 @@@ case DEATH_CUSTOM: { - Obituary_SpecialDeath(targ, FALSE, deathtype, + Obituary_SpecialDeath(targ, false, deathtype, targ.netname, ((strstrofs(deathmessage, "%", 0) < 0) ? strcat("%s ", deathmessage) : deathmessage), deathlocation, @@@ -530,7 -536,7 +537,7 @@@ 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; } } @@@ -603,8 -609,8 +610,8 @@@ void Freeze (entity targ, float freeze_ 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) @@@ -616,9 -622,9 +623,9 @@@ 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); @@@ -629,11 -635,6 +636,6 @@@ 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; @@@ -724,18 -725,18 +726,18 @@@ 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) @@@ -787,42 -788,42 +789,42 @@@ 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; } @@@ -864,7 -865,7 +866,7 @@@ 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) { @@@ -948,7 -949,6 +950,6 @@@ } } - 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 { @@@ -990,7 -990,7 +991,7 @@@ stat_damagedone = 0; - targ = WarpZone_FindRadius (inflictororigin, rad + MAX_DAMAGEEXTRARADIUS, FALSE); + targ = WarpZone_FindRadius (inflictororigin, rad + MAX_DAMAGEEXTRARADIUS, false); while (targ) { next = targ.chain; @@@ -1087,9 -1087,9 +1088,9 @@@ 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)); @@@ -1140,18 -1140,9 +1141,9 @@@ 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); @@@ -1254,7 -1245,7 +1246,7 @@@ float Fire_AddDamage(entity e, entity o if(e.fire_owner != o) { e.fire_owner = o; - e.fire_hitsound = FALSE; + e.fire_hitsound = false; } } if(accuracy_isgooddamage(o, e)) @@@ -1270,7 -1261,7 +1262,7 @@@ 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; @@@ -1309,7 -1300,7 +1301,7 @@@ void Fire_ApplyDamage(entity e 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) diff --combined qcsrc/server/g_damage.qh index 0000000000,4cc3f6f63e..68f9a0a385 mode 000000,100644..100644 --- a/qcsrc/server/g_damage.qh +++ b/qcsrc/server/g_damage.qh @@@ -1,0 -1,123 +1,122 @@@ + #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 "tturrets/include/turrets_early.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 diff --combined qcsrc/server/g_world.qc index dc5d9d6e30,04f8ff7b38..24a3d211cc --- a/qcsrc/server/g_world.qc +++ b/qcsrc/server/g_world.qc @@@ -1,4 -1,41 +1,42 @@@ - #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; @@@ -133,8 -170,8 +171,8 @@@ void cvar_changes_init( 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) { @@@ -277,15 -314,21 +315,21 @@@ // 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"); @@@ -439,12 -482,12 +483,12 @@@ void detect_maptype( 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) @@@ -470,7 -513,7 +514,7 @@@ float RandomSeed_Send(entity to, float { WriteByte(MSG_ENTITY, ENT_CLIENT_RANDOMSEED); WriteShort(MSG_ENTITY, self.cnt); - return TRUE; + return true; } void RandomSeed_Think() { @@@ -483,7 -526,7 +527,7 @@@ void RandomSeed_Spawn( { randomseed = spawn(); randomseed.think = RandomSeed_Think; - Net_LinkEntity(randomseed, FALSE, 0, RandomSeed_Send); + Net_LinkEntity(randomseed, false, 0, RandomSeed_Send); entity oldself; oldself = self; @@@ -515,7 -558,6 +559,7 @@@ void spawnfunc___init_dedicated_server( // 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); @@@ -543,7 -585,7 +587,7 @@@ void spawnfunc_worldspawn (void 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! @@@ -560,11 -602,10 +604,11 @@@ 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); @@@ -645,7 -686,7 +689,7 @@@ // 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)); @@@ -766,7 -807,7 +810,7 @@@ 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 @@@ -825,7 -866,7 +869,7 @@@ 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); @@@ -833,7 -874,7 +877,7 @@@ 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); @@@ -915,7 -956,7 +959,7 @@@ float MapHasRightSize(string map if(!fexists(strcat("maps/", map, ".waypoints"))) { dprint(": no waypoints\n"); - return FALSE; + return false; } dprint(": has waypoints\n"); } @@@ -933,18 -974,18 +977,18 @@@ 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) @@@ -1174,60 -1215,60 +1218,60 @@@ float DoNextMapOverride(float reinit 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) @@@ -1237,7 -1278,7 +1281,7 @@@ //string s; if (alreadychangedlevel) return; - alreadychangedlevel = TRUE; + alreadychangedlevel = true; string nextMap; @@@ -1267,7 -1308,7 +1311,7 @@@ void IntermissionThink( && ((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; } @@@ -1352,13 -1393,13 +1396,13 @@@ void DumpStats(float final 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:"; @@@ -1376,7 -1417,7 +1420,7 @@@ { file = fopen(autocvar_sv_logscores_filename, FILE_APPEND); if(file == -1) - to_file = FALSE; + to_file = false; else fputs(file, strcat(s, "\n")); } @@@ -1478,7 -1519,7 +1522,7 @@@ only called if a time or frag limit ha */ void NextLevel() { - gameover = TRUE; + gameover = true; intermission_running = 1; @@@ -1499,10 -1540,10 +1543,10 @@@ 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 @@@ -1545,15 -1586,6 +1589,6 @@@ void CheckRules_Player( // (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() { @@@ -1739,16 -1771,16 +1774,16 @@@ float WinningCondition_LMS( 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) { @@@ -1800,7 -1832,7 +1835,7 @@@ ClearWinners(); if(WinningConditionHelper_winner) - WinningConditionHelper_winner.winning = TRUE; + WinningConditionHelper_winner.winning = true; if(WinningConditionHelper_topscore == WinningConditionHelper_secondscore) return WINNING_NEVER; @@@ -1862,10 -1894,10 +1897,10 @@@ float WinningCondition_Scores(float lim } } - limitreached = FALSE; + limitreached = false; if(limit) if(WinningConditionHelper_topscore >= limit) - limitreached = TRUE; + limitreached = true; if(leadlimit) { float leadlimitreached; @@@ -1967,7 -1999,7 +2002,7 @@@ float WinningCondition_RanOutOfSpawns( 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) @@@ -2064,7 -2096,7 +2099,7 @@@ void CheckRules_World( { 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 @@@ -2223,7 -2255,7 +2258,7 @@@ void EndFrame( // needed! FOR_EACH_CLIENT(self) { - self.typehitsound = FALSE; + self.typehitsound = false; self.damage_dealt = 0; antilag_record(self, altime); } @@@ -2234,7 -2266,7 +2269,7 @@@ /* * RedirectionThink: - * returns TRUE if redirecting + * returns true if redirecting */ float redirection_timeout; float redirection_nextthink; @@@ -2243,7 -2275,7 +2278,7 @@@ float RedirectionThink( float clients_found; if(redirection_target == "") - return FALSE; + return false; if(!redirection_timeout) { @@@ -2256,7 -2288,7 +2291,7 @@@ } if(time < redirection_nextthink) - return TRUE; + return true; redirection_nextthink = time + 1; @@@ -2277,7 -2309,7 +2312,7 @@@ if(time > redirection_timeout || clients_found == 0) localcmd("\nwait; wait; wait; quit\n"); - return TRUE; + return true; } void TargetMusic_RestoreGame(); @@@ -2309,7 -2341,7 +2344,7 @@@ void Shutdown( Ban_SaveBans(); // playerstats with unfinished match - PlayerStats_GameReport(FALSE); + PlayerStats_GameReport(false); if(!cheatcount_total) { diff --combined qcsrc/server/miscfunctions.qc index db706003be,d998ea7999..eb457449ec --- a/qcsrc/server/miscfunctions.qc +++ b/qcsrc/server/miscfunctions.qc @@@ -1,9 -1,35 +1,34 @@@ - 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)); @@@ -23,15 -49,11 +48,11 @@@ void crosshair_trace_plusvisibletrigger 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) { @@@ -41,8 -63,6 +62,6 @@@ return "SERVER ADMIN"; } - float DistributeEvenly_amount; - float DistributeEvenly_totalweight; void DistributeEvenly_Init(float amount, float totalweight) { if (DistributeEvenly_amount) @@@ -77,37 -97,6 +96,6 @@@ float DistributeEvenly_GetRandomized(fl 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) { @@@ -118,7 -107,7 +106,7 @@@ { 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); @@@ -131,7 -120,7 +119,7 @@@ 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")); } @@@ -157,32 -146,6 +145,6 @@@ void GameLogClose( } } - #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; @@@ -202,7 -165,7 +164,7 @@@ 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) @@@ -232,7 -195,7 +194,7 @@@ // 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) @@@ -368,7 -331,7 +330,7 @@@ string formatmessage(string msg 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)); @@@ -378,8 -341,8 +340,8 @@@ 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; } /* @@@ -548,94 -511,16 +510,16 @@@ vector randompos(vector m1, vector m2 { 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; @@@ -643,9 -528,9 +527,9 @@@ 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); @@@ -659,7 -544,7 +543,7 @@@ 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")); @@@ -783,7 -668,7 +667,7 @@@ void readplayerstartcvars( 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) @@@ -845,7 -730,7 +729,7 @@@ 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) @@@ -893,156 -778,7 +777,7 @@@ 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 (;;) @@@ -1057,30 -793,30 +792,30 @@@ 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); @@@ -1089,61 -825,61 +824,61 @@@ 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); @@@ -1155,22 -891,22 +890,22 @@@ 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) @@@ -1191,18 -927,18 +926,18 @@@ void play2(entity e, string filename // 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) @@@ -1245,7 -981,7 +980,7 @@@ void precache_playermodel(string m 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); @@@ -1262,7 -998,7 +997,7 @@@ void precache_all_playermodels(string p 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); @@@ -1281,6 -1017,11 +1016,6 @@@ void precache( 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) { @@@ -1384,23 -1125,6 +1119,6 @@@ #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) { @@@ -1535,8 -1259,6 +1253,6 @@@ void InitializeEntitiesRun( remove = remove_unsafely; } - .float uncustomizeentityforclient_set; - .void(void) uncustomizeentityforclient; void UncustomizeEntitiesRun() { entity oldself; @@@ -1552,10 -1274,7 +1268,7 @@@ void SetCustomizer(entity e, float(void 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; @@@ -1607,7 -1326,7 +1320,7 @@@ float EliminatedPlayers_SendEntity(enti } } - return TRUE; + return true; } void EliminatedPlayers_Init(float(entity) isEliminated_func) @@@ -1617,7 -1336,7 +1330,7 @@@ 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; } @@@ -1672,9 -1391,9 +1385,9 @@@ float trace_hits_box_1d(float end, floa { // just check if x is in range if (0 < thmi) - return FALSE; + return false; if (0 > thma) - return FALSE; + return false; } else { @@@ -1683,9 -1402,9 +1396,9 @@@ 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) @@@ -1698,14 -1417,14 +1411,14 @@@ 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) @@@ -1754,11 -1473,11 +1467,11 @@@ void W_Crylink_Dequeue(entity e) 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") @@@ -1768,16 -1487,13 +1481,13 @@@ } 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) { @@@ -1842,14 -1558,14 +1552,14 @@@ float MoveToRandomMapLocation(entity e 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) @@@ -1860,7 -1576,7 +1570,7 @@@ 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; @@@ -1869,19 -1585,19 +1579,19 @@@ // 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; @@@ -1901,9 -1617,9 +1611,9 @@@ } // 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 @@@ -1931,10 -1647,10 +1641,10 @@@ 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) @@@ -1957,15 -1673,15 +1667,15 @@@ vector shotorg_adjustfromclient(vector 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 { @@@ -1977,13 -1693,13 +1687,13 @@@ 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; } @@@ -2000,28 -1716,28 +1710,28 @@@ vector shotorg_adjust_values(vector vec 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) { @@@ -2059,12 -1775,12 +1769,12 @@@ void attach_sameorigin(entity e, entit 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 @@@ -2137,26 -1853,26 +1847,26 @@@ float modeleffect_SendEntity(entity to 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); @@@ -2164,7 -1880,7 +1874,7 @@@ 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) @@@ -2184,16 -1900,16 +1894,16 @@@ 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) @@@ -2263,26 -1979,6 +1973,6 @@@ float ExponentialFalloff(float mindist } - - - #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; @@@ -2350,9 -2046,9 +2040,9 @@@ float LostMovetypeFollow(entity ent float isPushable(entity e) { if(e.iscreature) - return TRUE; + return true; if(e.pushable) - return TRUE; + return true; switch(e.classname) { case "body": @@@ -2360,11 -2056,11 +2050,11 @@@ 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; } diff --combined qcsrc/server/mutators/gamemode_assault.qc index 8d1a7c1fd2,49deac0e8f..841b5a910b --- a/qcsrc/server/mutators/gamemode_assault.qc +++ b/qcsrc/server/mutators/gamemode_assault.qc @@@ -106,9 -106,9 +106,9 @@@ float assault_decreaser_sprite_visible( decreaser = self.assault_decreaser; if(decreaser.enemy.health >= ASSAULT_VALUE_INACTIVE) - return FALSE; + return false; - return TRUE; + return true; } void target_objective_decrease_activate() @@@ -163,6 -163,7 +163,6 @@@ void assault_roundstart_use( activator = self; SUB_UseTargets(); -#ifdef TTURRETS_ENABLED entity ent, oldself; //(Re)spawn all turrets @@@ -178,11 -179,12 +178,11 @@@ self = ent; // Dubbles as teamchange - turret_stdproc_respawn(); + turret_respawn(); ent = find(ent, classname, "turret_main"); } self = oldself; -#endif } void assault_wall_think() @@@ -344,7 -346,7 +344,7 @@@ void havocbot_goalrating_ast_targets(fl if (!ad.bot_attack) continue; - found = FALSE; + found = false; for(tod = world; (tod = find(tod, targetname, ad.target)); ) { if(tod.classname == "target_objective_decrease") @@@ -352,7 -354,7 +352,7 @@@ if(tod.enemy.health > 0 && tod.enemy.health < ASSAULT_VALUE_INACTIVE) { // dprint(etos(ad),"\n"); - found = TRUE; + found = true; break; } } @@@ -372,7 -374,7 +372,7 @@@ // 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) @@@ -383,7 -385,7 +383,7 @@@ if(wp.classname=="waypoint") if(checkpvs(wp.origin, ad)) { - found = TRUE; + found = true; if(wp.cnt 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 @@@ -623,9 -623,9 +623,9 @@@ void onslaught_generator_damage(entity 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 @@@ -666,11 -666,11 +666,11 @@@ 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 { @@@ -687,7 -687,7 +687,7 @@@ //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 @@@ -732,14 -732,14 +732,14 @@@ void onslaught_generator_updatesprite(e 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'); } @@@ -819,14 -819,14 +819,14 @@@ void onslaught_controlpoint_updatesprit 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'); } @@@ -843,10 -843,10 +843,10 @@@ void onslaught_generator_reset( 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; @@@ -925,11 -925,11 +925,11 @@@ void spawnfunc_onslaught_generator( 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 @@@ -987,12 -987,12 +987,12 @@@ void onslaught_controlpoint_icon_damage 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; } } @@@ -1000,12 -1000,12 +1000,12 @@@ { 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"); @@@ -1037,17 -1037,17 +1037,17 @@@ 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; @@@ -1150,54 -1150,54 +1150,54 @@@ void onslaught_controlpoint_icon_think( 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); @@@ -1235,7 -1235,7 +1235,7 @@@ void onslaught_controlpoint_icon_buildt 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); @@@ -1289,7 -1289,7 +1289,7 @@@ void onslaught_controlpoint_touch( 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; @@@ -1316,9 -1316,9 +1316,9 @@@ void onslaught_controlpoint_reset( 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; @@@ -1333,7 -1333,7 +1333,7 @@@ activator = self; SUB_UseTargets(); // to reset the structures, playerspawns etc. - + CSQCMODEL_AUTOUPDATE(); } @@@ -1386,9 -1386,9 +1386,9 @@@ void spawnfunc_onslaught_controlpoint( 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(); @@@ -1405,7 -1405,7 +1405,7 @@@ self.enemy.colormap = self.colormap; waypoint_spawnforitem(self); - + self.think = onslaught_controlpoint_think; self.nextthink = time; @@@ -1415,7 -1415,7 +1415,7 @@@ onslaught_updatelinks(); self.reset = onslaught_controlpoint_reset; - + CSQCMODEL_AUTOINIT(); } @@@ -1425,21 -1425,21 +1425,21 @@@ float onslaught_link_send(entity to, fl 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() @@@ -1520,7 -1520,7 +1520,7 @@@ void spawnfunc_onslaught_link( 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) @@@ -1539,7 -1539,7 +1539,7 @@@ MUTATOR_HOOKFUNCTION(ons_Spawn_Score { /* - float _neer_home = (random() > 0.5 ? TRUE : FALSE); + float _neer_home = (random() > 0.5 ? true : false); RandomSelection_Init(); @@@ -1579,7 -1579,7 +1579,7 @@@ MUTATOR_HOOKFUNCTION(ons_PlayerSpawn 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; @@@ -1657,50 -1657,36 +1657,50 @@@ 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) @@@ -1708,7 -1694,6 +1708,7 @@@ 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); diff --combined qcsrc/server/mutators/mutators_include.qc index 0f52e34f03,a0170e4803..95f9604a0d --- a/qcsrc/server/mutators/mutators_include.qc +++ b/qcsrc/server/mutators/mutators_include.qc @@@ -1,3 -1,85 +1,83 @@@ + #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_early.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 "../tturrets/include/turrets.qh" + #include "../vehicles/vehicles.qh" + #endif + #include "base.qc" #include "gamemode_assault.qc" #include "gamemode_ca.qc" diff --combined qcsrc/server/progs.src index 68ded63d88,85e75cda9e..527c427124 --- a/qcsrc/server/progs.src +++ b/qcsrc/server/progs.src @@@ -1,157 -1,77 +1,77 @@@ - ../../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 @@@ -163,104 -83,32 +83,38 @@@ weapons/throwing.q 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 diff --combined qcsrc/server/t_teleporters.qc index 5bed9ec930,46df0eb786..53704a06f7 --- a/qcsrc/server/t_teleporters.qc +++ b/qcsrc/server/t_teleporters.qc @@@ -1,32 -1,30 +1,29 @@@ + #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 "tturrets/include/turrets_early.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) @@@ -41,7 -39,7 +38,7 @@@ } return 0; } - float tdeath_hit; + void tdeath(entity player, entity teleporter, entity telefragger, vector telefragmin, vector telefragmax) { TDEATHLOOP(player.origin) @@@ -66,21 -64,6 +63,6 @@@ void spawn_tdeath(vector v0, entity e, 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; @@@ -114,7 -97,7 +96,7 @@@ 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); @@@ -170,7 -153,7 +152,7 @@@ entity Simple_TeleportPlayer(entity tel 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; } @@@ -191,7 -174,7 +173,7 @@@ 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; @@@ -212,7 -195,7 +194,7 @@@ void Teleport_Touch (void 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) @@@ -313,8 -296,6 +295,6 @@@ entity Teleport_Find(vector mi, vector return world; } - entity teleport_first; - .entity teleport_next; void spawnfunc_trigger_teleport (void) { self.angles = '0 0 0'; diff --combined qcsrc/server/tturrets/system/system_main.qc index d56a81bbf0,f2b0c56ce8..0000000000 deleted file mode 100644,100644 --- a/qcsrc/server/tturrets/system/system_main.qc +++ /dev/null @@@ -1,1378 -1,1378 +1,0 @@@ --#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; --} -- -- diff --combined qcsrc/server/tturrets/units/unit_ewheel.qc index e8e677ac8c,7eb1622baf..0000000000 deleted file mode 100644,100644 --- a/qcsrc/server/tturrets/units/unit_ewheel.qc +++ /dev/null @@@ -1,310 -1,310 +1,0 @@@ - #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; --} diff --combined qcsrc/server/tturrets/units/unit_flac.qc index 3c9e55863f,e398a83da5..0000000000 deleted file mode 100644,100644 --- a/qcsrc/server/tturrets/units/unit_flac.qc +++ /dev/null @@@ -1,74 -1,74 +1,0 @@@ --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; --} -- diff --combined qcsrc/server/tturrets/units/unit_machinegun.qc index d235dfb327,d235dfb327..0000000000 deleted file mode 100644,100644 --- a/qcsrc/server/tturrets/units/unit_machinegun.qc +++ /dev/null @@@ -1,52 -1,52 +1,0 @@@ --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; --} -- diff --combined qcsrc/server/tturrets/units/unit_plasma.qc index 26a3dc04e4,1bfd8ac34d..0000000000 deleted file mode 100644,100644 --- a/qcsrc/server/tturrets/units/unit_plasma.qc +++ /dev/null @@@ -1,173 -1,173 +1,0 @@@ --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; --} -- diff --combined qcsrc/server/tturrets/units/unit_walker.qc index a91daa1901,4b1c44c154..0000000000 deleted file mode 100644,100644 --- a/qcsrc/server/tturrets/units/unit_walker.qc +++ /dev/null @@@ -1,643 -1,643 +1,0 @@@ - #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; --} diff --combined qcsrc/server/vehicles/bumblebee.qc index c3ebdede4e,9b3ae6c31d..9c200d78ac --- a/qcsrc/server/vehicles/bumblebee.qc +++ b/qcsrc/server/vehicles/bumblebee.qc @@@ -1,92 -1,13 +1,13 @@@ - #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() @@@ -157,7 -78,7 +78,7 @@@ 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; @@@ -222,7 -143,7 +143,7 @@@ void bumb_gunner_exit(float _exitflag 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); } @@@ -292,7 -213,7 +213,7 @@@ float bumb_gunner_enter( else { dprint("^1ERROR:^7Tried to enter a fully occupied vehicle!\n"); - return FALSE; + return false; } _gunner = other; @@@ -321,8 -242,8 +242,8 @@@ 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; @@@ -334,28 -255,28 +255,28 @@@ 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() @@@ -392,13 -313,13 +313,13 @@@ void bumb_regen( 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); } @@@ -428,58 -349,58 +349,58 @@@ float bumb_pilot_frame( 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; } @@@ -569,7 -490,7 +490,7 @@@ 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); @@@ -791,8 -712,8 +712,8 @@@ void bumb_die( 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) @@@ -863,7 -784,7 +784,7 @@@ 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; @@@ -913,10 -834,10 +834,10 @@@ void spawnfunc_vehicle_bumblebee( 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; @@@ -937,19 -858,19 +858,19 @@@ float bumble_raygun_send(entity to, flo 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 @@@ -1000,7 -921,7 +921,7 @@@ void bumble_raygun_draw( void bumble_raygun_read(float bIsNew) { - float sf = ReadByte(); + int sf = ReadByte(); if(sf & BRG_SETUP) { diff --combined qcsrc/server/vehicles/racer.qc index fc9cee8657,87dfe52a7e..45c3713af7 --- a/qcsrc/server/vehicles/racer.qc +++ b/qcsrc/server/vehicles/racer.qc @@@ -1,7 -1,7 +1,9 @@@ - #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(); @@@ -99,20 -99,20 +101,20 @@@ void racer_align4point(float _delta 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); @@@ -128,11 -128,11 +130,11 @@@ void racer_fire_cannon(string tagname 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; } @@@ -215,7 -215,7 +217,7 @@@ void racer_rocket_tracker( 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) { @@@ -226,7 -226,7 +228,7 @@@ } 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; @@@ -242,7 -242,7 +244,7 @@@ void racer_fire_rocket(string tagname, 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; @@@ -288,16 -288,16 +290,16 @@@ float racer_frame( // 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; @@@ -309,10 -309,10 +311,10 @@@ 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) { @@@ -425,13 -425,13 +427,13 @@@ 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); @@@ -460,10 -460,10 +462,10 @@@ void racer_think( 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); @@@ -528,8 -528,8 +530,8 @@@ void racer_exit(float eject 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() @@@ -578,9 -578,9 +580,9 @@@ void racer_die( 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'; @@@ -667,12 -667,12 +669,12 @@@ void spawnfunc_vehicle_racer( "", "", "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)) { diff --combined qcsrc/server/vehicles/vehicles.qc index 94656c2f47,96d54e3de7..695e3db750 --- a/qcsrc/server/vehicles/vehicles.qc +++ b/qcsrc/server/vehicles/vehicles.qc @@@ -1,13 -1,13 +1,15 @@@ ++#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; @@@ -33,15 -33,15 +35,15 @@@ float SendAuxiliaryXhair(entity to, flo 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) @@@ -60,7 -60,7 +62,7 @@@ 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); @@@ -275,7 -275,9 +277,7 @@@ void vehicles_locktarget(float incr, fl 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; } @@@ -420,7 -422,7 +422,7 @@@ entity vehicles_projectile(string _mzlf 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; @@@ -493,14 -495,14 +495,14 @@@ void vehicles_spawn( 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'; @@@ -527,12 -529,12 +529,12 @@@ 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) @@@ -593,7 -595,7 +595,7 @@@ void vehicles_touch( 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 @@@ -665,7 -667,7 +667,7 @@@ self.team = self.owner.team; self.flags -= FL_NOTARGET; - self.monster_attack = TRUE; + self.monster_attack = true; if (IS_REAL_CLIENT(other)) { @@@ -676,14 -678,14 +678,14 @@@ 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 } } @@@ -723,7 -725,7 +725,7 @@@ vector vehicles_findgoodexit(vector pre 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) @@@ -772,7 -774,7 +774,7 @@@ void vehicles_exit(float eject return; } - vehicles_exit_running = TRUE; + vehicles_exit_running = true; if(IS_CLIENT(self)) { _vehicle = self.vehicle; @@@ -781,7 -783,7 +783,7 @@@ { _vehicle.vehicle_exit(eject); self = _oldself; - vehicles_exit_running = FALSE; + vehicles_exit_running = false; return; } } @@@ -802,7 -804,7 +804,7 @@@ 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); } @@@ -843,7 -845,7 +845,7 @@@ 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); @@@ -852,7 -854,7 +854,7 @@@ _vehicle.owner = world; self = _oldself; - vehicles_exit_running = FALSE; + vehicles_exit_running = false; } @@@ -1070,7 -1072,7 +1072,7 @@@ void vehicles_showwp( 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); @@@ -1200,7 -1202,7 +1202,7 @@@ float vehicle_addplayerslot( entity setattachment(_slot.vehicle_hudmodel, _slot, ""); setattachment(_slot.vehicle_viewport, _slot.vehicle_hudmodel, ""); - return TRUE; + return true; } float vehicle_initialize(string net_name, @@@ -1226,7 -1228,7 +1228,7 @@@ float _max_shield) { if(!autocvar_g_vehicles) - return FALSE; + return false; if(self.targetname) { @@@ -1288,10 -1290,10 +1290,10 @@@ 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; @@@ -1350,9 -1352,9 +1352,9 @@@ 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, @@@ -1364,12 -1366,12 +1366,12 @@@ 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; } diff --combined qcsrc/server/vehicles/vehicles_def.qh index 5b82788d16,080f891f4e..ca40a93e8d --- a/qcsrc/server/vehicles/vehicles_def.qh +++ b/qcsrc/server/vehicles/vehicles_def.qh @@@ -1,22 -1,27 +1,25 @@@ + #ifndef VEHICLES_DEF_H + #define VEHICLES_DEF_H + -#include "../tturrets/include/turrets_early.qh" - // #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; @@@ -40,17 -45,13 +43,17 @@@ .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 @@@ -63,8 -64,8 +66,8 @@@ const float SVC_UPDATEENTITY = 128; / .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; @@@ -75,3 -76,4 +78,4 @@@ void(entity e, vector force, vector for void(entity e, vector torque) physics_addtorque = #542; // add relative torque #endif // VEHICLES_USE_ODE #endif // VEHICLES_ENABLED + #endif