From: terencehill Date: Sun, 23 Aug 2015 15:33:36 +0000 (+0200) Subject: Merge branch 'master' into terencehill/bot_fixes X-Git-Tag: xonotic-v0.8.2~1891^2 X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=commitdiff_plain;h=867ce0406b74601b6d74a4ac412ac30063490d88;hp=7a0a311ff868e71c2336e0cdffdadad6a55fac8f Merge branch 'master' into terencehill/bot_fixes --- diff --git a/defaultXonotic.cfg b/defaultXonotic.cfg index 45c920195e..798da0913b 100644 --- a/defaultXonotic.cfg +++ b/defaultXonotic.cfg @@ -234,10 +234,12 @@ seta cl_hitsound_nom_damage 25 "damage amount at which hitsound bases pitch off" seta cl_eventchase_death 1 "camera goes into 3rd person mode when the player is dead; set to 2 to active the effect only when the corpse doesn't move anymore" seta cl_eventchase_nexball 1 "camera goes into 3rd person mode when in nexball game-mode" seta cl_eventchase_distance 140 "final camera distance" +seta cl_eventchase_generator_distance 400 "final camera distance while viewing generator explosion" seta cl_eventchase_speed 1.3 "how fast the camera slides back, 0 is instant" seta cl_eventchase_maxs "12 12 8" "max size of eventchase camera bbox" seta cl_eventchase_mins "-12 -12 -8" "min size of eventchase camera bbox" seta cl_eventchase_viewoffset "0 0 20" "viewoffset of eventchase camera" +seta cl_eventchase_generator_viewoffset "0 0 80" "viewoffset of eventchase camera while viewing generator explosion" //nifreks lockonrestart feature, used in team-based game modes, if set to 1 and all players readied up no other player can then join the game anymore, useful to block spectators from joining set teamplay_lockonrestart 0 "it set to 1 in a team-based game, the teams are locked once all players readied up and the game restarted (no new players can join after restart unless using the server-command unlockteams)" @@ -288,12 +290,6 @@ set cl_deathglow 0.8 "number of seconds during which dead bodies glow out" set sv_gibhealth 100 "Minus health a dead body must have in order to get gibbed" -// fragmessage: This allows extra information to be displayed with the frag centerprints. -set sv_fraginfo 1 "Enable extra frag message information, 0 = Never display, 1 = Display only in warmup mode; 2 = Always display" -set sv_fraginfo_ping 1 "Enable ping display information, 0 = Never display, 1 = Always display (If the player is a bot, it will say bot instead of the ping.)" -set sv_fraginfo_handicap 1 "Enable handicap display information, 0 = Never display, 1 = Only when the player has handicap on, 2 = Always display (Displays Off if disabled)" -set sv_fraginfo_stats 1 "Enable statistics (health/armor) display information, 0 = Never display, 1 = Always display (Only available for the person who was killed)" - // use default physics set sv_friction_on_land 0 set sv_friction_slick 0.5 diff --git a/gamemodes.cfg b/gamemodes.cfg index 7f444e4448..340d01b9dc 100644 --- a/gamemodes.cfg +++ b/gamemodes.cfg @@ -501,7 +501,17 @@ seta g_nexball_tackling 1 "Allow ball theft?" // onslaught // =========== set g_onslaught 0 "Onslaught: take control points towards the enemy generator and then destroy it" +set g_onslaught_point_limit 1 "Onslaught point limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)" +set g_onslaught_warmup 5 +set g_onslaught_round_timelimit 280 +set g_onslaught_debug 0 "show debug prints in onslaught" +set g_onslaught_teleport_radius 200 "Allows teleporting from a control point to another" +set g_onslaught_teleport_wait 5 "Time before player can teleport again" +set g_onslaught_spawn_choose 1 "Allow players to choose the control point to be spawned at" +set g_onslaught_click_radius 500 "When choosing from the map, this level of precision is required" + set g_onslaught_gen_health 2500 +set g_onslaught_allow_vehicle_touch 0 set g_onslaught_cp_health 1000 set g_onslaught_cp_buildhealth 100 set g_onslaught_cp_buildtime 5 @@ -509,8 +519,13 @@ set g_onslaught_cp_regen 20 set g_onslaught_cp_proxydecap 0 "de-capture controlpoints by standing close to them" set g_onslaught_cp_proxydecap_distance 512 set g_onslaught_cp_proxydecap_dps 100 +set g_onslaught_shield_force 100 set g_onslaught_spawn_at_controlpoints 0 +set g_onslaught_spawn_at_controlpoints_chance 0.5 +set g_onslaught_spawn_at_controlpoints_random 0 set g_onslaught_spawn_at_generator 0 +set g_onslaught_spawn_at_generator_chance 0 +set g_onslaught_spawn_at_generator_random 0 // ====== diff --git a/gfx/teamradar_icon_glow.tga b/gfx/teamradar_icon_glow.tga new file mode 100644 index 0000000000..4272d34d23 Binary files /dev/null and b/gfx/teamradar_icon_glow.tga differ diff --git a/qcsrc/client/autocvars.qh b/qcsrc/client/autocvars.qh index 9c1a679cf7..a9a442b308 100644 --- a/qcsrc/client/autocvars.qh +++ b/qcsrc/client/autocvars.qh @@ -447,6 +447,8 @@ float autocvar_cl_hitsound_nom_damage = 25; float autocvar_cl_hitsound_antispam_time; int autocvar_cl_eventchase_death = 1; int autocvar_cl_eventchase_nexball = 1; +vector autocvar_cl_eventchase_generator_viewoffset = '0 0 80'; +float autocvar_cl_eventchase_generator_distance = 400; float autocvar_cl_eventchase_distance = 140; float autocvar_cl_eventchase_speed = 1.3; vector autocvar_cl_eventchase_maxs = '12 12 8'; diff --git a/qcsrc/client/command/cl_cmd.qc b/qcsrc/client/command/cl_cmd.qc index f3ac3234d0..e80130c596 100644 --- a/qcsrc/client/command/cl_cmd.qc +++ b/qcsrc/client/command/cl_cmd.qc @@ -282,9 +282,15 @@ void LocalCommand_hud(int request, int argc) case "radar": { if(argv(2)) - hud_panel_radar_maximized = InterpretBoolean(argv(2)); + HUD_Radar_Show_Maximized(InterpretBoolean(argv(2)),0); else - hud_panel_radar_maximized = !hud_panel_radar_maximized; + HUD_Radar_Show_Maximized(!hud_panel_radar_maximized,0); + return; + } + + case "clickradar": + { + HUD_Radar_Show_Maximized(!hud_panel_radar_mouse,1); return; } } diff --git a/qcsrc/client/controlpoint.qc b/qcsrc/client/controlpoint.qc new file mode 100644 index 0000000000..a579f93aa0 --- /dev/null +++ b/qcsrc/client/controlpoint.qc @@ -0,0 +1,212 @@ +#include "controlpoint.qh" +#include "gibs.qh" +#include "teamradar.qh" + +bool cpicon_precached; +.int count; +.float pain_finished; + +.bool iscaptured; + +.vector cp_origin, cp_bob_origin; +.float cp_bob_spd; + +.vector cp_bob_dmg; + +.vector punchangle; + +.float max_health; + +.entity icon_realmodel; + +void cpicon_precache() +{ + if(cpicon_precached) + return; // already precached + + precache_model("models/onslaught/controlpoint_icon_dmg3.md3"); + precache_model("models/onslaught/controlpoint_icon_dmg2.md3"); + precache_model("models/onslaught/controlpoint_icon_dmg1.md3"); + precache_model("models/onslaught/controlpoint_icon.md3"); + + cpicon_precached = true; +} + +void cpicon_draw() +{ + if(time < self.move_time) { return; } + + if(self.cp_bob_dmg_z > 0) + self.cp_bob_dmg_z = self.cp_bob_dmg_z - 3 * frametime; + else + self.cp_bob_dmg_z = 0; + self.cp_bob_origin_z = 4 * PI * (1 - cos(self.cp_bob_spd)); + self.cp_bob_spd = self.cp_bob_spd + 1.875 * frametime; + self.colormod = '1 1 1' * (2 - bound(0, (self.pain_finished - time) / 10, 1)); + + if(!self.iscaptured) self.alpha = self.health / self.max_health; + + if(self.iscaptured) + { + if (self.punchangle_x > 0) + { + self.punchangle_x = self.punchangle_x - 60 * frametime; + if (self.punchangle_x < 0) + self.punchangle_x = 0; + } + else if (self.punchangle_x < 0) + { + self.punchangle_x = self.punchangle_x + 60 * frametime; + if (self.punchangle_x > 0) + self.punchangle_x = 0; + } + + if (self.punchangle_y > 0) + { + self.punchangle_y = self.punchangle_y - 60 * frametime; + if (self.punchangle_y < 0) + self.punchangle_y = 0; + } + else if (self.punchangle_y < 0) + { + self.punchangle_y = self.punchangle_y + 60 * frametime; + if (self.punchangle_y > 0) + self.punchangle_y = 0; + } + + if (self.punchangle_z > 0) + { + self.punchangle_z = self.punchangle_z - 60 * frametime; + if (self.punchangle_z < 0) + self.punchangle_z = 0; + } + else if (self.punchangle_z < 0) + { + self.punchangle_z = self.punchangle_z + 60 * frametime; + if (self.punchangle_z > 0) + self.punchangle_z = 0; + } + + self.angles_x = self.punchangle_x; + self.angles_y = self.punchangle_y + self.move_angles_y; + self.angles_z = self.punchangle_z; + self.move_angles_y = self.move_angles_y + 45 * frametime; + } + + setorigin(self, self.cp_origin + self.cp_bob_origin + self.cp_bob_dmg); +} + +void cpicon_damage(float hp) +{ + if(!self.iscaptured) { return; } + + if(hp < self.max_health * 0.25) + setmodel(self, "models/onslaught/controlpoint_icon_dmg3.md3"); + else if(hp < self.max_health * 0.50) + setmodel(self, "models/onslaught/controlpoint_icon_dmg2.md3"); + else if(hp < self.max_health * 0.75) + setmodel(self, "models/onslaught/controlpoint_icon_dmg1.md3"); + else if(hp <= self.max_health || hp >= self.max_health) + setmodel(self, "models/onslaught/controlpoint_icon.md3"); + + self.punchangle = (2 * randomvec() - '1 1 1') * 45; + + self.cp_bob_dmg_z = (2 * random() - 1) * 15; + self.pain_finished = time + 1; + self.colormod = '2 2 2'; + + setsize(self, CPICON_MIN, CPICON_MAX); +} + +void cpicon_construct() +{ + self.netname = "Control Point Icon"; + + setmodel(self, "models/onslaught/controlpoint_icon.md3"); + setsize(self, CPICON_MIN, CPICON_MAX); + + if(self.icon_realmodel == world) + { + self.icon_realmodel = spawn(); + setmodel(self.icon_realmodel, "null"); + setorigin(self.icon_realmodel, self.origin); + setsize(self.icon_realmodel, CPICON_MIN, CPICON_MAX); + self.icon_realmodel.movetype = MOVETYPE_NOCLIP; + self.icon_realmodel.solid = SOLID_NOT; + self.icon_realmodel.move_origin = self.icon_realmodel.origin; + } + + if(self.iscaptured) { self.icon_realmodel.solid = SOLID_BBOX; } + + self.move_movetype = MOVETYPE_NOCLIP; + self.solid = SOLID_NOT; + self.movetype = MOVETYPE_NOCLIP; + self.move_origin = self.origin; + self.move_time = time; + self.drawmask = MASK_NORMAL; + self.alpha = 1; + self.draw = cpicon_draw; + self.cp_origin = self.origin; + self.cp_bob_origin = '0 0 0.1'; + self.cp_bob_spd = 0; +} + +.vector glowmod; +void cpicon_changeteam() +{ + if(self.team) + { + self.glowmod = Team_ColorRGB(self.team - 1); + self.teamradar_color = Team_ColorRGB(self.team - 1); + self.colormap = 1024 + (self.team - 1) * 17; + } + else + { + self.colormap = 1024; + self.glowmod = '1 1 0'; + self.teamradar_color = '1 1 0'; + } +} + +void ent_cpicon() +{ + int sf = ReadByte(); + + if(sf & CPSF_SETUP) + { + self.origin_x = ReadCoord(); + self.origin_y = ReadCoord(); + self.origin_z = ReadCoord(); + setorigin(self, self.origin); + + self.health = ReadByte(); + self.max_health = ReadByte(); + self.count = ReadByte(); + self.team = ReadByte(); + self.iscaptured = ReadByte(); + + if(!self.count) + self.count = (self.health - self.max_health) * frametime; + + cpicon_changeteam(); + cpicon_precache(); + cpicon_construct(); + } + + if(sf & CPSF_STATUS) + { + int _tmp = ReadByte(); + if(_tmp != self.team) + { + self.team = _tmp; + cpicon_changeteam(); + } + + _tmp = ReadByte(); + + if(_tmp != self.health) + cpicon_damage(_tmp); + + self.health = _tmp; + } +} diff --git a/qcsrc/client/controlpoint.qh b/qcsrc/client/controlpoint.qh new file mode 100644 index 0000000000..8469b5226f --- /dev/null +++ b/qcsrc/client/controlpoint.qh @@ -0,0 +1,13 @@ +#ifndef CONTROLPOINT_H +#define CONTROLPOINT_H + +const vector CPICON_MIN = '-32 -32 -9'; +const vector CPICON_MAX = '32 32 25'; + +const int CPSF_STATUS = 4; +const int CPSF_SETUP = 8; + +void ent_cpicon(); +void cpicon_precache(); + +#endif diff --git a/qcsrc/client/damage.qc b/qcsrc/client/damage.qc index fb80a52a0e..9479f5786c 100644 --- a/qcsrc/client/damage.qc +++ b/qcsrc/client/damage.qc @@ -4,7 +4,7 @@ #include "gibs.qh" #include "prandom.qh" -#include "../common/vehicles/cl_vehicles.qh" +#include "../common/vehicles/all.qh" #include "../common/constants.qh" #include "../common/deathtypes.qh" @@ -334,7 +334,7 @@ void Ent_DamageInfo(float isNew) 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; diff --git a/qcsrc/client/generator.qc b/qcsrc/client/generator.qc new file mode 100644 index 0000000000..0c2ce4681c --- /dev/null +++ b/qcsrc/client/generator.qc @@ -0,0 +1,261 @@ +#include "generator.qh" + +bool generator_precached; +.int count; +.float max_health; + +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; + return v; +} + +void generator_precache() +{ + if(generator_precached) + return; // already precached + + precache_model("models/onslaught/generator.md3"); + precache_model("models/onslaught/generator_dead.md3"); + precache_model("models/onslaught/generator_dmg1.md3"); + precache_model("models/onslaught/generator_dmg2.md3"); + precache_model("models/onslaught/generator_dmg3.md3"); + precache_model("models/onslaught/generator_dmg4.md3"); + precache_model("models/onslaught/generator_dmg5.md3"); + precache_model("models/onslaught/generator_dmg6.md3"); + precache_model("models/onslaught/generator_dmg7.md3"); + precache_model("models/onslaught/generator_dmg8.md3"); + precache_model("models/onslaught/generator_dmg9.md3"); + precache_model("models/onslaught/generator_dead.md3"); + + precache_model("models/onslaught/ons_ray.md3"); + precache_sound("onslaught/shockwave.wav"); + precache_sound("weapons/grenade_impact.wav"); + precache_sound("weapons/rocket_impact.wav"); + precache_sound("onslaught/electricity_explode.wav"); + + generator_precached = true; +} + +void ons_generator_ray_draw() +{ + if(time < self.move_time) + return; + + self.move_time = time + 0.05; + + if(self.count > 10) + { + remove(self); + return; + } + + if(self.count > 5) + self.alpha -= 0.1; + else + self.alpha += 0.1; + + self.scale += 0.2; + self.count +=1; +} + +void ons_generator_ray_spawn(vector org) +{ + entity e; + e = spawn(); + e.classname = "ons_ray"; + setmodel(e, "models/onslaught/ons_ray.md3"); + setorigin(e, org); + e.angles = randomvec() * 360; + e.move_origin = org; + e.movetype = MOVETYPE_NONE; + e.alpha = 0; + e.scale = random() * 5 + 8; + e.move_time = time + 0.05; + e.drawmask = MASK_NORMAL; + e.draw = ons_generator_ray_draw; +} + +void generator_draw() +{ + if(time < self.move_time) + return; + + if(self.health > 0) + { + // damaged fx (less probable the more damaged is the generator) + if(random() < 0.9 - self.health / self.max_health) + if(random() < 0.01) + { + pointparticles(particleeffectnum("electro_ballexplode"), self.origin + randompos('-50 -50 -20', '50 50 50'), '0 0 0', 1); + sound(self, CH_TRIGGER, "onslaught/electricity_explode.wav", VOL_BASE, ATTEN_NORM); + } + else + pointparticles(particleeffectnum("torch_small"), self.origin + randompos('-60 -60 -20', '60 60 60'), '0 0 0', 1); + + self.move_time = time + 0.1; + + return; + } + + if(self.count <= 0) + return; + + vector org; + int i; + + // White shockwave + if(self.count==40||self.count==20) + { + sound(self, CH_TRIGGER, "onslaught/shockwave.wav", VOL_BASE, ATTEN_NORM); + pointparticles(particleeffectnum("electro_combo"), self.origin, '0 0 0', 6); + } + + // rays + if(random() > 0.25) + { + ons_generator_ray_spawn(self.origin); + } + + // Spawn fire balls + for(i=0;i < 10;++i) + { + org = self.origin + randompos('-30 -30 -30' * i + '0 0 -20', '30 30 30' * i + '0 0 20'); + pointparticles(particleeffectnum("onslaught_generator_gib_explode"), org, '0 0 0', 1); + } + + // Short explosion sound + small explosion + if(random() < 0.25) + { + te_explosion(self.origin); + sound(self, CH_TRIGGER, "weapons/grenade_impact.wav", VOL_BASE, ATTEN_NORM); + } + + // Particles + org = self.origin + randompos(self.mins + '8 8 8', self.maxs + '-8 -8 -8'); + pointparticles(particleeffectnum("onslaught_generator_smallexplosion"), org, '0 0 0', 1); + + // Final explosion + if(self.count==1) + { + org = self.origin; + te_explosion(org); + pointparticles(particleeffectnum("onslaught_generator_finalexplosion"), org, '0 0 0', 1); + sound(self, CH_TRIGGER, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM); + } + + self.move_time = time + 0.05; + + self.count -= 1; +} + +void generator_damage(float hp) +{ + if(hp <= 0) + setmodel(self, "models/onslaught/generator_dead.md3"); + else if(hp < self.max_health * 0.10) + setmodel(self, "models/onslaught/generator_dmg9.md3"); + else if(hp < self.max_health * 0.20) + setmodel(self, "models/onslaught/generator_dmg8.md3"); + else if(hp < self.max_health * 0.30) + setmodel(self, "models/onslaught/generator_dmg7.md3"); + else if(hp < self.max_health * 0.40) + setmodel(self, "models/onslaught/generator_dmg6.md3"); + else if(hp < self.max_health * 0.50) + setmodel(self, "models/onslaught/generator_dmg5.md3"); + else if(hp < self.max_health * 0.60) + setmodel(self, "models/onslaught/generator_dmg4.md3"); + else if(hp < self.max_health * 0.70) + setmodel(self, "models/onslaught/generator_dmg3.md3"); + else if(hp < self.max_health * 0.80) + setmodel(self, "models/onslaught/generator_dmg2.md3"); + else if(hp < self.max_health * 0.90) + setmodel(self, "models/onslaught/generator_dmg1.md3"); + else if(hp <= self.max_health || hp >= self.max_health) + setmodel(self, "models/onslaught/generator.md3"); + + setsize(self, GENERATOR_MIN, GENERATOR_MAX); +} + +void generator_construct() +{ + self.netname = "Generator"; + self.classname = "onslaught_generator"; + + setorigin(self, self.origin); + setmodel(self, "models/onslaught/generator.md3"); + setsize(self, GENERATOR_MIN, GENERATOR_MAX); + + self.move_movetype = MOVETYPE_NOCLIP; + self.solid = SOLID_BBOX; + self.movetype = MOVETYPE_NOCLIP; + self.move_origin = self.origin; + self.move_time = time; + self.drawmask = MASK_NORMAL; + self.alpha = 1; + self.draw = generator_draw; +} + +.vector glowmod; +void generator_changeteam() +{ + if(self.team) + { + self.glowmod = Team_ColorRGB(self.team - 1); + self.teamradar_color = Team_ColorRGB(self.team - 1); + self.colormap = 1024 + (self.team - 1) * 17; + } + else + { + self.colormap = 1024; + self.glowmod = '1 1 0'; + self.teamradar_color = '1 1 0'; + } +} + +void ent_generator() +{ + int sf = ReadByte(); + + if(sf & GSF_SETUP) + { + self.origin_x = ReadCoord(); + self.origin_y = ReadCoord(); + self.origin_z = ReadCoord(); + setorigin(self, self.origin); + + self.health = ReadByte(); + self.max_health = ReadByte(); + self.count = ReadByte(); + self.team = ReadByte(); + + if(!self.count) + self.count = 40; + + generator_changeteam(); + generator_precache(); + generator_construct(); + } + + if(sf & GSF_STATUS) + { + int _tmp; + _tmp = ReadByte(); + if(_tmp != self.team) + { + self.team = _tmp; + generator_changeteam(); + } + + _tmp = ReadByte(); + + if(_tmp != self.health) + generator_damage(_tmp); + + self.health = _tmp; + } +} diff --git a/qcsrc/client/generator.qh b/qcsrc/client/generator.qh new file mode 100644 index 0000000000..e4e1611f31 --- /dev/null +++ b/qcsrc/client/generator.qh @@ -0,0 +1,11 @@ +#ifndef GENERATOR_H +#define GENERATOR_H +const vector GENERATOR_MIN = '-52 -52 -14'; +const vector GENERATOR_MAX = '52 52 75'; + +const int GSF_STATUS = 4; +const int GSF_SETUP = 8; + +void ent_generator(); +void generator_precache(); +#endif diff --git a/qcsrc/client/hud.qc b/qcsrc/client/hud.qc index 50eed4c421..cfa00a1aff 100644 --- a/qcsrc/client/hud.qc +++ b/qcsrc/client/hud.qc @@ -2,11 +2,14 @@ #include "_all.qh" #include "hud_config.qh" +#include "mapvoting.qh" #include "scoreboard.qh" #include "sortlist.qh" #include "teamradar.qh" #include "t_items.qh" +#include "../dpdefs/keycodes.qh" + #include "../common/buffs.qh" #include "../common/constants.qh" #include "../common/counting.qh" @@ -2017,6 +2020,167 @@ void HUD_Timer(void) // Radar (#6) // + +float HUD_Radar_Clickable() +{ + return hud_panel_radar_mouse && !hud_panel_radar_temp_hidden; +} + +void HUD_Radar_Show_Maximized(bool doshow,float clickable) +{ + hud_panel_radar_maximized = doshow; + hud_panel_radar_temp_hidden = 0; + + if ( doshow ) + { + if (clickable) + { + if(autocvar_hud_cursormode) + setcursormode(1); + hud_panel_radar_mouse = 1; + } + } + else if ( hud_panel_radar_mouse ) + { + hud_panel_radar_mouse = 0; + mouseClicked = 0; + if(autocvar_hud_cursormode) + if(!mv_active) + setcursormode(0); + } +} +void HUD_Radar_Hide_Maximized() +{ + HUD_Radar_Show_Maximized(false,false); +} + + +float HUD_Radar_InputEvent(float bInputType, float nPrimary, float nSecondary) +{ + if(!hud_panel_radar_maximized || !hud_panel_radar_mouse || + autocvar__hud_configure || mv_active) + return false; + + if(bInputType == 3) + { + mousepos_x = nPrimary; + mousepos_y = nSecondary; + return true; + } + + if(nPrimary == K_MOUSE1) + { + if(bInputType == 0) // key pressed + mouseClicked |= S_MOUSE1; + else if(bInputType == 1) // key released + mouseClicked -= (mouseClicked & S_MOUSE1); + } + else if(nPrimary == K_MOUSE2) + { + if(bInputType == 0) // key pressed + mouseClicked |= S_MOUSE2; + else if(bInputType == 1) // key released + mouseClicked -= (mouseClicked & S_MOUSE2); + } + else if ( nPrimary == K_ESCAPE && bInputType == 0 ) + { + HUD_Radar_Hide_Maximized(); + } + else + { + // allow console/use binds to work without hiding the map + string con_keys; + float keys; + float i; + con_keys = strcat(findkeysforcommand("toggleconsole", 0)," ",findkeysforcommand("+use", 0)) ; + keys = tokenize(con_keys); // findkeysforcommand returns data for this + for (i = 0; i < keys; ++i) + { + if(nPrimary == stof(argv(i))) + return false; + } + + if ( getstati(STAT_HEALTH) <= 0 ) + { + // Show scoreboard + if ( bInputType < 2 ) + { + con_keys = findkeysforcommand("+showscores", 0); + keys = tokenize(con_keys); + for (i = 0; i < keys; ++i) + { + if ( nPrimary == stof(argv(i)) ) + { + hud_panel_radar_temp_hidden = bInputType == 0; + return false; + } + } + } + } + else if ( bInputType == 0 ) + HUD_Radar_Hide_Maximized(); + + return false; + } + + return true; +} + +void HUD_Radar_Mouse() +{ + if ( !hud_panel_radar_mouse ) return; + if(mv_active) return; + + if ( intermission ) + { + HUD_Radar_Hide_Maximized(); + return; + } + + if(mouseClicked & S_MOUSE2) + { + HUD_Radar_Hide_Maximized(); + return; + } + + if(!autocvar_hud_cursormode) + { + mousepos = mousepos + getmousepos() * autocvar_menu_mouse_speed; + + mousepos_x = bound(0, mousepos_x, vid_conwidth); + mousepos_y = bound(0, mousepos_y, vid_conheight); + } + + HUD_Panel_UpdateCvars(); + + + panel_size = autocvar_hud_panel_radar_maximized_size; + panel_size_x = bound(0.2, panel_size_x, 1) * vid_conwidth; + panel_size_y = bound(0.2, panel_size_y, 1) * vid_conheight; + panel_pos_x = (vid_conwidth - panel_size_x) / 2; + panel_pos_y = (vid_conheight - panel_size_y) / 2; + + if(mouseClicked & S_MOUSE1) + { + // click outside + if ( mousepos_x < panel_pos_x || mousepos_x > panel_pos_x + panel_size_x || + mousepos_y < panel_pos_y || mousepos_y > panel_pos_y + panel_size_y ) + { + HUD_Radar_Hide_Maximized(); + return; + } + vector pos = teamradar_texcoord_to_3dcoord(teamradar_2dcoord_to_texcoord(mousepos),view_origin_z); + localcmd(sprintf("cmd ons_spawn %f %f %f",pos_x,pos_y,pos_z)); + + HUD_Radar_Hide_Maximized(); + return; + } + + + const vector cursor_size = '32 32 0'; + drawpic(mousepos-'8 4 0', strcat("gfx/menu/", autocvar_menu_skin, "/cursor.tga"), cursor_size, '1 1 1', 0.8, DRAWFLAG_NORMAL); +} + void HUD_Radar(void) { if(intermission == 2) return; @@ -2038,6 +2202,9 @@ void HUD_Radar(void) } } + if ( hud_panel_radar_temp_hidden ) + return; + HUD_Panel_UpdateCvars(); float f = 0; @@ -2191,8 +2358,27 @@ void HUD_Radar(void) for(tm = world; (tm = find(tm, classname, "radarlink")); ) draw_teamradar_link(tm.origin, tm.velocity, tm.team); + + vector coord; + vector brightcolor; for(tm = world; (tm = findflags(tm, teamradar_icon, 0xFFFFFF)); ) + { + if ( hud_panel_radar_mouse ) + if ( tm.health > 0 ) + if ( tm.team == myteam+1 ) + { + coord = teamradar_texcoord_to_2dcoord(teamradar_3dcoord_to_texcoord(tm.origin)); + if ( vlen(mousepos-coord) < 8 ) + { + brightcolor_x = min(1,tm.teamradar_color_x*1.5); + brightcolor_y = min(1,tm.teamradar_color_y*1.5); + brightcolor_z = min(1,tm.teamradar_color_z*1.5); + drawpic(coord - '8 8 0', "gfx/teamradar_icon_glow", '16 16 0', brightcolor, panel_fg_alpha, 0); + } + } + draw_teamradar_icon(tm.origin, tm.teamradar_icon, tm, tm.teamradar_color, panel_fg_alpha); + } for(tm = world; (tm = find(tm, classname, "entcs_receiver")); ) { color2 = GetPlayerColor(tm.sv_entnum); @@ -2202,6 +2388,21 @@ void HUD_Radar(void) draw_teamradar_player(view_origin, view_angles, '1 1 1'); drawresetcliparea(); + + if ( hud_panel_radar_mouse ) + { + string message = "Click to select teleport destination"; + + if ( getstati(STAT_HEALTH) <= 0 ) + { + message = "Click to select spawn location"; + } + + drawcolorcodedstring(pos + '0.5 0 0' * (mySize_x - stringwidth(message, true, hud_fontsize)) - '0 1 0' * hud_fontsize_y * 2, + message, hud_fontsize, hud_panel_radar_foreground_alpha, DRAWFLAG_NORMAL); + + hud_panel_radar_bottom = pos_y + mySize_y + hud_fontsize_y; + } } // Score (#7) @@ -4428,7 +4629,15 @@ void HUD_CenterPrint (void) } HUD_Panel_UpdateCvars(); - if(scoreboard_fade_alpha) + if ( HUD_Radar_Clickable() ) + { + if (hud_panel_radar_bottom >= 0.96 * vid_conheight) + return; + + panel_pos = eY * hud_panel_radar_bottom + eX * 0.5 * (vid_conwidth - panel_size_x); + panel_size_y = min(panel_size_y, vid_conheight - hud_panel_radar_bottom); + } + else if(scoreboard_fade_alpha) { hud_fade_alpha = hud_fade_alpha_save; diff --git a/qcsrc/client/hud.qh b/qcsrc/client/hud.qh index 72e3326429..8a2f76ded4 100644 --- a/qcsrc/client/hud.qh +++ b/qcsrc/client/hud.qh @@ -12,6 +12,16 @@ int HUD_PANEL_LAST; int panel_order[HUD_PANEL_MAX]; string hud_panelorder_prev; +bool hud_draw_maximized; +bool hud_panel_radar_maximized; +bool hud_panel_radar_mouse; +float hud_panel_radar_bottom; +bool hud_panel_radar_temp_hidden; +bool chat_panel_modified; +bool radar_panel_modified; + +void HUD_Radar_Hide_Maximized(); + void HUD_Reset (void); void HUD_Main (void); @@ -25,11 +35,6 @@ int vote_prev; // previous state of vote_active to check for a change float vote_alpha; float vote_change; // "time" when vote_active changed -float hud_draw_maximized; -float hud_panel_radar_maximized; -float chat_panel_modified; -float radar_panel_modified; - vector mousepos; vector panel_click_distance; // mouse cursor distance from the top left corner of the panel (saved only upon a click) vector panel_click_resizeorigin; // coordinates for opposite point when resizing diff --git a/qcsrc/client/hud_config.qc b/qcsrc/client/hud_config.qc index 485b82b2c3..ca7fde9e04 100644 --- a/qcsrc/client/hud_config.qc +++ b/qcsrc/client/hud_config.qc @@ -636,14 +636,6 @@ void HUD_Panel_Arrow_Action(float nPrimary) } } -const int S_MOUSE1 = 1; -const int S_MOUSE2 = 2; -const int S_MOUSE3 = 4; -int mouseClicked; -int prevMouseClicked; // previous state -float prevMouseClickedTime; // time during previous left mouse click, to check for doubleclicks -vector prevMouseClickedPos; // pos during previous left mouse click, to check for doubleclicks - void HUD_Panel_EnableMenu(); entity tab_panels[HUD_PANEL_MAX]; entity tab_panel; diff --git a/qcsrc/client/hud_config.qh b/qcsrc/client/hud_config.qh index cc1d4d563c..39dc659918 100644 --- a/qcsrc/client/hud_config.qh +++ b/qcsrc/client/hud_config.qh @@ -11,4 +11,12 @@ void HUD_Configure_PostDraw(); float HUD_Panel_InputEvent(float bInputType, float nPrimary, float nSecondary); +const int S_MOUSE1 = 1; +const int S_MOUSE2 = 2; +const int S_MOUSE3 = 4; +int mouseClicked; +int prevMouseClicked; // previous state +float prevMouseClickedTime; // time during previous left mouse click, to check for doubleclicks +vector prevMouseClickedPos; // pos during previous left mouse click, to check for doubleclicks + #endif diff --git a/qcsrc/client/main.qc b/qcsrc/client/main.qc index 231dd68675..9e7b8bd685 100644 --- a/qcsrc/client/main.qc +++ b/qcsrc/client/main.qc @@ -2,9 +2,11 @@ #include "_all.qh" #include "casings.qh" +#include "controlpoint.qh" #include "csqcmodel_hooks.qh" #include "damage.qh" #include "effects.qh" +#include "generator.qh" #include "gibs.qh" #include "hook.qh" #include "hud.qh" @@ -17,15 +19,14 @@ #include "scoreboard.qh" #include "shownames.qh" #include "sortlist.qh" -#include "tturrets.qh" #include "tuba.qh" #include "t_items.qh" #include "wall.qh" #include "waypointsprites.qh" -#include "../common/vehicles/unit/bumblebee.qh" -#include "../common/vehicles/cl_vehicles.qh" -#include "../common/vehicles/vehicles.qh" +#include "../common/vehicles/all.qh" + +#include "mutators/events.qh" #include "weapons/projectile.qh" @@ -51,6 +52,9 @@ #include "../common/triggers/include.qh" +#include "../common/turrets/cl_turrets.qh" +#include "../common/turrets/turrets.qh" + #include "../warpzonelib/client.qh" // -------------------------------------------------------------------------- @@ -145,11 +149,11 @@ void CSQC_Init(void) // needs to be done so early because of the constants they create static_init(); + CALL_ACCUMULATED_FUNCTION(RegisterTurrets); CALL_ACCUMULATED_FUNCTION(RegisterNotifications); CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes); CALL_ACCUMULATED_FUNCTION(RegisterHUD_Panels); CALL_ACCUMULATED_FUNCTION(RegisterEffects); - CALL_ACCUMULATED_FUNCTION(RegisterVehicles); WaypointSprite_Load(); @@ -158,11 +162,11 @@ void CSQC_Init(void) precache_sound("misc/hit.wav"); precache_sound("misc/typehit.wav"); + generator_precache(); Projectile_Precache(); Hook_Precache(); GibSplash_Precache(); Casings_Precache(); - turrets_precache(); Tuba_Precache(); CSQCPlayer_Precache(); @@ -368,6 +372,9 @@ float CSQC_InputEvent(float bInputType, float nPrimary, float nSecondary) if (HUD_Panel_InputEvent(bInputType, nPrimary, nSecondary)) return true; + if ( HUD_Radar_InputEvent(bInputType, nPrimary, nSecondary) ) + return true; + if (MapVote_InputEvent(bInputType, nPrimary, nSecondary)) return true; @@ -783,7 +790,7 @@ void Ent_ReadSpawnEvent(float is_new) button_zoom = false; } } - + HUD_Radar_Hide_Maximized(); //printf("Ent_ReadSpawnEvent(is_new = %d); origin = %s, entnum = %d, localentnum = %d\n", is_new, vtos(self.origin), entnum, player_localentnum); } @@ -870,6 +877,8 @@ void CSQC_Ent_Update(float bIsNewEntity) 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_GENERATOR: ent_generator(); break; + case ENT_CLIENT_CONTROLPOINT_ICON: ent_cpicon(); 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; @@ -1257,69 +1266,55 @@ void Net_WeaponComplain() // 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(); + int nTEID = ReadByte(); - if(autocvar_developer_csqcentities) + if (autocvar_developer_csqcentities) printf("CSQC_Parse_TempEntity() with nTEID=%d\n", nTEID); - // NOTE: Could just do return instead of break... - switch(nTEID) + switch (nTEID) { + case TE_CSQC_MUTATOR: + int mutID = ReadMutator(); + if (MUTATOR_CALLHOOK(CSQC_Parse_TempEntity, mutID)) + return true; case TE_CSQC_TARGET_MUSIC: Net_TargetMusic(); - bHandled = true; - break; + return true; case TE_CSQC_PICTURE: Net_MapVote_Picture(); - bHandled = true; - break; + return true; case TE_CSQC_RACE: Net_ReadRace(); - bHandled = true; - break; + return true; case TE_CSQC_VORTEXBEAMPARTICLE: Net_ReadVortexBeamParticle(); - bHandled = true; - break; + return true; case TE_CSQC_TEAMNAGGER: Net_TeamNagger(); - bHandled = true; - break; + return true; case TE_CSQC_ARC: Net_ReadArc(); - bHandled = true; - break; + return true; case TE_CSQC_PINGPLREPORT: Net_ReadPingPLReport(); - bHandled = true; - break; + return true; case TE_CSQC_WEAPONCOMPLAIN: Net_WeaponComplain(); - bHandled = true; - break; + return true; case TE_CSQC_VEHICLESETUP: Net_VehicleSetup(); - bHandled = true; - break; + return true; case TE_CSQC_SVNOTICE: cl_notice_read(); - bHandled = true; - break; + return true; case TE_CSQC_SHOCKWAVEPARTICLE: Net_ReadShockwaveParticle(); - bHandled = true; - break; + return true; default: // No special logic for this temporary entity; return 0 so the engine can handle it - bHandled = false; - break; + return false; } - - return bHandled; } string getcommandkey(string text, string command) diff --git a/qcsrc/client/main.qh b/qcsrc/client/main.qh index 0bc85a441d..c8de3afdc9 100644 --- a/qcsrc/client/main.qh +++ b/qcsrc/client/main.qh @@ -153,4 +153,6 @@ entity entcs_receiver[255]; // 255 is the engine limit on maxclients float hud; float view_quality; int framecount; +.float health; + #endif diff --git a/qcsrc/client/mapvoting.qc b/qcsrc/client/mapvoting.qc index 6610f80362..037d906fbe 100644 --- a/qcsrc/client/mapvoting.qc +++ b/qcsrc/client/mapvoting.qc @@ -12,7 +12,6 @@ int mv_num_maps; -float mv_active; string mv_maps[MAPVOTE_COUNT]; string mv_pics[MAPVOTE_COUNT]; string mv_pk3[MAPVOTE_COUNT]; // map pk3 name or gametype human readable name diff --git a/qcsrc/client/mapvoting.qh b/qcsrc/client/mapvoting.qh index 9c7086efc1..7a9a511a2b 100644 --- a/qcsrc/client/mapvoting.qh +++ b/qcsrc/client/mapvoting.qh @@ -11,4 +11,6 @@ float MapVote_InputEvent(float bInputType, float nPrimary, float nSecondary); void Ent_MapVote(); void Net_MapVote_Picture(); + +float mv_active; #endif diff --git a/qcsrc/client/mutators/events.qh b/qcsrc/client/mutators/events.qh index 362e8d321d..8f317c8e8a 100644 --- a/qcsrc/client/mutators/events.qh +++ b/qcsrc/client/mutators/events.qh @@ -35,4 +35,18 @@ string cmd_string; /**/ MUTATOR_HOOKABLE(CSQC_ConsoleCommand, EV_CSQC_ConsoleCommand); +/* Called when the crosshair is being updated */ +MUTATOR_HOOKABLE(UpdateCrosshair, EV_NO_ARGS); + +/** + * Called when a temp entity is parsed + * NOTE: hooks MUST start with `if (MUTATOR_RETURNVALUE) return false;` + * NOTE: hooks MUST start with `if (!ReadMutatorEquals(mutator_argv_int_0, name_of_mutator)) return false;` + * NOTE: return true if you handled the command, return false to continue handling + */ +#define EV_CSQC_Parse_TempEntity(i, o) \ + /** entity id */ i(int, mutator_argv_int_0) \ + /**/ +MUTATOR_HOOKABLE(CSQC_Parse_TempEntity, EV_CSQC_Parse_TempEntity); + #endif diff --git a/qcsrc/client/progs.src b/qcsrc/client/progs.src index ea61aed0d4..9b687532ff 100644 --- a/qcsrc/client/progs.src +++ b/qcsrc/client/progs.src @@ -7,9 +7,11 @@ announcer.qc bgmscript.qc casings.qc +controlpoint.qc csqcmodel_hooks.qc damage.qc effects.qc +generator.qc gibs.qc hook.qc hud.qc @@ -28,7 +30,6 @@ scoreboard.qc shownames.qc sortlist.qc teamradar.qc -tturrets.qc tuba.qc t_items.qc view.qc @@ -57,10 +58,13 @@ weapons/projectile.qc // TODO ../common/viewloc.qc ../common/items/all.qc - ../common/monsters/all.qc +../common/mutators/all.qc +../common/vehicles/all.qc +../common/weapons/all.qc -../common/weapons/all.qc // TODO +../common/turrets/cl_turrets.qc +../common/turrets/turrets.qc ../common/triggers/include.qc @@ -68,8 +72,6 @@ weapons/projectile.qc // TODO ../csqcmodellib/cl_player.qc ../csqcmodellib/interpolate.qc -../common/vehicles/vehicles_include.qc - ../server/mutators/mutator_multijump.qc ../warpzonelib/anglestransform.qc diff --git a/qcsrc/client/scoreboard.qc b/qcsrc/client/scoreboard.qc index b6d2db25c2..126cc904d0 100644 --- a/qcsrc/client/scoreboard.qc +++ b/qcsrc/client/scoreboard.qc @@ -302,7 +302,7 @@ void Cmd_HUD_Help() #define HUD_DefaultColumnLayout() \ "ping pl name | " \ "-teams,race,lms/kills +ft,tdm/kills -teams,lms/deaths +ft,tdm/deaths -teams,lms,race,ka/suicides +ft,tdm/suicides -race,dm,tdm,ka,ft/frags " /* tdm already has this in "score" */ \ -"+ctf/caps +ctf/pickups +ctf/fckills +ctf/returns " \ +"+ctf/caps +ctf/pickups +ctf/fckills +ctf/returns +ons/caps +ons/takes " \ "+lms/lives +lms/rank " \ "+kh/caps +kh/pushes +kh/destroyed " \ "?+race/laps ?+race/time ?+race/fastest " \ @@ -960,6 +960,8 @@ vector HUD_Scoreboard_MakeTable(vector pos, entity tm, vector rgb, vector bg_siz float HUD_WouldDrawScoreboard() { if (autocvar__hud_configure) return 0; + else if (HUD_Radar_Clickable()) + return 0; else if (scoreboard_showscores) return 1; else if (intermission == 1) diff --git a/qcsrc/client/teamradar.qc b/qcsrc/client/teamradar.qc index aa7923bafc..874fec1f59 100644 --- a/qcsrc/client/teamradar.qc +++ b/qcsrc/client/teamradar.qc @@ -46,6 +46,34 @@ vector teamradar_texcoord_to_2dcoord(vector in) return out; } + +vector teamradar_2dcoord_to_texcoord(vector in) +{ + vector out; + out = in; + + out -= teamradar_origin2d; + if(v_flipped) + out_x = -out_x; + out = out / teamradar_size; + + out_y = - out_y; // screen space is reversed + out = rotate(out, -teamradar_angle * DEG2RAD); + + out += teamradar_origin3d_in_texcoord; + + return out; +} + +vector teamradar_texcoord_to_3dcoord(vector in,float z) +{ + vector out; + out_x = in_x * (mi_picmax_x - mi_picmin_x) + mi_picmin_x; + out_y = in_y * (mi_picmax_y - mi_picmin_y) + mi_picmin_y; + out_z = z; + return out; +} + vector yinvert(vector v) { v.y = 1 - v.y; diff --git a/qcsrc/client/teamradar.qh b/qcsrc/client/teamradar.qh index f7c186ac62..b2329cfb06 100644 --- a/qcsrc/client/teamradar.qh +++ b/qcsrc/client/teamradar.qh @@ -33,10 +33,14 @@ float vlen_maxnorm2d(vector v); float vlen_minnorm2d(vector v); +vector teamradar_2dcoord_to_texcoord(vector in); + vector teamradar_3dcoord_to_texcoord(vector in); vector teamradar_texcoord_to_2dcoord(vector in); +vector teamradar_texcoord_to_3dcoord(vector in,float z); + vector yinvert(vector v); void draw_teamradar_background(float fg); diff --git a/qcsrc/client/tturrets.qc b/qcsrc/client/tturrets.qc deleted file mode 100644 index d469fdcca0..0000000000 --- a/qcsrc/client/tturrets.qc +++ /dev/null @@ -1,696 +0,0 @@ -#include "tturrets.qh" -#include "_all.qh" - -#include "hud.qh" -#include "movelib.qh" -#include "prandom.qh" -#include "teamradar.qh" -#include "waypointsprites.qh" - -#include "../common/teams.qh" - -#include "../common/movetypes/movetypes.qh" - -#include "../server/tturrets/include/turrets_early.qh" - -#include "../warpzonelib/anglestransform.qh" -#include "../warpzonelib/mathlib.qh" - -.vector colormod; -.float cnt; -.float alpha; -.float gravity; - -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(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/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; -} - -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; -} - -class(Turret) .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))) - return; // Dont draw wp's for turrets out of view - o.z = 0; - if(hud != HUD_NORMAL) - { - if(self.turret_type == TID_EWHEEL || self.turret_type == TID_WALKER) - txt = "gfx/vehicles/turret_moving.tga"; - else - txt = "gfx/vehicles/turret_stationary.tga"; - - vector pz = drawgetimagesize(txt) * autocvar_cl_vehicles_crosshair_size; - drawpic(o - pz * 0.5, txt, pz , '1 1 1', 0.7, DRAWFLAG_NORMAL); - } - } - - if(dist > self.maxdistance) - return; - - string spriteimage = self.netname; - float a = self.alpha * autocvar_hud_panel_fg_alpha; - vector rgb = spritelookupcolor(spriteimage, self.teamradar_color); - - - if(self.maxdistance > waypointsprite_normdistance) - a *= pow(bound(0, (self.maxdistance - dist) / (self.maxdistance - waypointsprite_normdistance), 1), waypointsprite_distancealphaexponent); - else if(self.maxdistance > 0) - a *= pow(bound(0, (waypointsprite_fadedistance - dist) / (waypointsprite_fadedistance - waypointsprite_normdistance), 1), waypointsprite_distancealphaexponent) * (1 - waypointsprite_minalpha) + waypointsprite_minalpha; - - if(rgb == '0 0 0') - { - self.teamradar_color = '1 0 1'; - printf("WARNING: sprite of name %s has no color, using pink so you notice it\n", spriteimage); - } - - txt = self.netname; - if(autocvar_g_waypointsprite_spam && waypointsprite_count >= autocvar_g_waypointsprite_spam) - txt = _("Spam"); - else - txt = spritelookuptext(spriteimage); - - if(time - floor(time) > 0.5 && t == self.team) - { - if(self.helpme && time < self.helpme) - { - a *= SPRITE_HELPME_BLINK; - txt = sprintf(_("%s under attack!"), txt); - } - else - a *= spritelookupblinkvalue(spriteimage); - } - - if(autocvar_g_waypointsprite_uppercase) - txt = strtoupper(txt); - - if(a > 1) - { - rgb *= a; - a = 1; - } - - if(a <= 0) - return; - - rgb = fixrgbexcess(rgb); - - o = project_3d_to_2d(self.origin + '0 0 64'); - if(o.z < 0 - || o.x < (vid_conwidth * waypointsprite_edgeoffset_left) - || o.y < (vid_conheight * waypointsprite_edgeoffset_top) - || o.x > (vid_conwidth - (vid_conwidth * waypointsprite_edgeoffset_right)) - || o.y > (vid_conheight - (vid_conheight * waypointsprite_edgeoffset_bottom))) - return; // Dont draw wp's for turrets out of view - - o.z = 0; - - float edgedistance_min, crosshairdistance; - edgedistance_min = min((o.y - (vid_conheight * waypointsprite_edgeoffset_top)), - (o.x - (vid_conwidth * waypointsprite_edgeoffset_left)), - (vid_conwidth - (vid_conwidth * waypointsprite_edgeoffset_right)) - o.x, - (vid_conheight - (vid_conheight * waypointsprite_edgeoffset_bottom)) - o.y); - - float vidscale = max(vid_conwidth / vid_width, vid_conheight / vid_height); - - crosshairdistance = sqrt( pow(o.x - vid_conwidth/2, 2) + pow(o.y - vid_conheight/2, 2) ); - - t = waypointsprite_scale * vidscale; - a *= waypointsprite_alpha; - - { - a = a * (1 - (1 - waypointsprite_distancefadealpha) * (bound(0, dist/waypointsprite_distancefadedistance, 1))); - t = t * (1 - (1 - waypointsprite_distancefadescale) * (bound(0, dist/waypointsprite_distancefadedistance, 1))); - } - if (edgedistance_min < waypointsprite_edgefadedistance) { - a = a * (1 - (1 - waypointsprite_edgefadealpha) * (1 - bound(0, edgedistance_min/waypointsprite_edgefadedistance, 1))); - t = t * (1 - (1 - waypointsprite_edgefadescale) * (1 - bound(0, edgedistance_min/waypointsprite_edgefadedistance, 1))); - } - if(crosshairdistance < waypointsprite_crosshairfadedistance) { - a = a * (1 - (1 - waypointsprite_crosshairfadealpha) * (1 - bound(0, crosshairdistance/waypointsprite_crosshairfadedistance, 1))); - t = t * (1 - (1 - waypointsprite_crosshairfadescale) * (1 - bound(0, crosshairdistance/waypointsprite_crosshairfadedistance, 1))); - } - - o = drawspritearrow(o, M_PI, rgb, a, SPRITE_ARROW_SCALE * t); - o = drawspritetext(o, M_PI, (SPRITE_HEALTHBAR_WIDTH + 2 * SPRITE_HEALTHBAR_BORDER) * t, rgb, a, waypointsprite_fontsize * '1 1 0', txt); - drawhealthbar( - o, - 0, - self.health / 255, - '0 0 0', - '0 0 0', - 0.5 * SPRITE_HEALTHBAR_WIDTH * t, - 0.5 * SPRITE_HEALTHBAR_HEIGHT * t, - SPRITE_HEALTHBAR_MARGIN * t + 0.5 * waypointsprite_fontsize, - SPRITE_HEALTHBAR_BORDER * t, - 0, - rgb, - a * SPRITE_HEALTHBAR_BORDERALPHA, - rgb, - a * SPRITE_HEALTHBAR_HEALTHALPHA, - DRAWFLAG_NORMAL - ); -} - -void turret_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); -} - -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; - - if (self.health < 127) - if(random() < 0.05) - te_spark(self.origin + '0 0 40', randomvec() * 256 + '0 0 256', 16); -} - -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); -} - -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); - 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); - else if (self.turret_type == TID_TESLA) - 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); - } - else - 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); - 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() -{ - 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) - { - 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 --git a/qcsrc/client/tturrets.qh b/qcsrc/client/tturrets.qh deleted file mode 100644 index 4cf9854c46..0000000000 --- a/qcsrc/client/tturrets.qh +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef TTURRETS_H -#define TTURRETS_H - -void ent_turret(); -void turrets_precache(); -entityclass(Turret); -class(Turret) .entity tur_head; -#endif diff --git a/qcsrc/client/view.qc b/qcsrc/client/view.qc index 67bcf42249..e846a662b1 100644 --- a/qcsrc/client/view.qc +++ b/qcsrc/client/view.qc @@ -10,6 +10,8 @@ #include "shownames.qh" #include "waypointsprites.qh" +#include "mutators/events.qh" + #include "../common/constants.qh" #include "../common/mapinfo.qh" #include "../common/nades.qh" @@ -801,6 +803,8 @@ void UpdateCrosshair() wcross_alpha_prev = wcross_alpha; wcross_color_prev = wcross_color; + MUTATOR_CALLHOOK(UpdateCrosshair); + wcross_scale *= 1 - autocvar__menu_alpha; wcross_alpha *= 1 - autocvar__menu_alpha; wcross_size = draw_getimagesize(wcross_name) * wcross_scale; @@ -1109,16 +1113,35 @@ void CSQC_UpdateView(float w, float h) if(autocvar_chase_active <= 0) // greater than 0 means it's enabled manually, and this code is skipped { float vehicle_chase = (hud != HUD_NORMAL && (autocvar_cl_eventchase_vehicle || spectatee_status > 0)); - if(WantEventchase()) + float ons_roundlost = (gametype == MAPINFO_TYPE_ONSLAUGHT && getstati(STAT_ROUNDLOST)); + entity gen = world; + + if(ons_roundlost) + { + entity e; + for(e = world; (e = find(e, classname, "onslaught_generator")); ) + { + if(e.health <= 0) + { + gen = e; + break; + } + } + if(!gen) + ons_roundlost = FALSE; // don't enforce the 3rd person camera if there is no dead generator to show + } + if(WantEventchase() || (!autocvar_cl_orthoview && ons_roundlost)) { eventchase_running = true; // make special vector since we can't use view_origin (It is one frame old as of this code, it gets set later with the results this code makes.) vector current_view_origin = (csqcplayer ? csqcplayer.origin : pmove_org); + if(ons_roundlost) { current_view_origin = gen.origin; } // detect maximum viewoffset and use it vector view_offset = autocvar_cl_eventchase_viewoffset; if(vehicle_chase && autocvar_cl_eventchase_vehicle_viewoffset) { view_offset = autocvar_cl_eventchase_vehicle_viewoffset; } + if(ons_roundlost) { view_offset = autocvar_cl_eventchase_generator_viewoffset; } if(view_offset) { @@ -1135,6 +1158,7 @@ void CSQC_UpdateView(float w, float h) // make the camera smooth back float chase_distance = autocvar_cl_eventchase_distance; if(vehicle_chase && autocvar_cl_eventchase_vehicle_distance) { chase_distance = autocvar_cl_eventchase_vehicle_distance; } + if(ons_roundlost) { chase_distance = autocvar_cl_eventchase_generator_distance; } if(autocvar_cl_eventchase_speed && eventchase_current_distance < chase_distance) eventchase_current_distance += autocvar_cl_eventchase_speed * (chase_distance - eventchase_current_distance) * frametime; // slow down the further we get @@ -1811,6 +1835,8 @@ void CSQC_UpdateView(float w, float h) if(autocvar__hud_configure) HUD_Panel_Mouse(); + else + HUD_Radar_Mouse(); if(hud && !intermission) if(hud == HUD_BUMBLEBEE_GUN) diff --git a/qcsrc/client/waypointsprites.qc b/qcsrc/client/waypointsprites.qc index f63b3cf3c8..40fc56a413 100644 --- a/qcsrc/client/waypointsprites.qc +++ b/qcsrc/client/waypointsprites.qc @@ -172,11 +172,8 @@ float spritelookupblinkvalue(string s) switch(s) { - case "ons-cp-atck-neut": return 2; - case "ons-cp-atck-red": return 2; - case "ons-cp-atck-blue": return 2; - case "ons-cp-dfnd-red": return 0.5; - case "ons-cp-dfnd-blue": return 0.5; + case "ons-cp-atck": return 2; + case "ons-cp-dfnd": return 0.5; case "item_health_mega": return 2; case "item_armor_large": return 2; case "item-invis": return 2; @@ -238,17 +235,11 @@ string spritelookuptext(string s) case "neutralbase": return _("White base"); case "pinkbase": return _("Pink base"); case "waypoint": return _("Waypoint"); - case "ons-gen-red": return _("Generator"); - case "ons-gen-blue": return _("Generator"); + case "ons-gen": return _("Generator"); case "ons-gen-shielded": return _("Generator"); - case "ons-cp-neut": return _("Control point"); - case "ons-cp-red": return _("Control point"); - case "ons-cp-blue": return _("Control point"); - case "ons-cp-atck-neut": return _("Control point"); - case "ons-cp-atck-red": return _("Control point"); - case "ons-cp-atck-blue": return _("Control point"); - case "ons-cp-dfnd-red": return _("Control point"); - case "ons-cp-dfnd-blue": return _("Control point"); + case "ons-cp": return _("Control point"); + case "ons-cp-atck": return _("Control point"); + case "ons-cp-dfnd": return _("Control point"); case "race-checkpoint": return _("Checkpoint"); case "race-finish": return _("Finish"); case "race-start": return _("Start"); diff --git a/qcsrc/client/waypointsprites.qh b/qcsrc/client/waypointsprites.qh index adea76ca7e..cb4f7adbd6 100644 --- a/qcsrc/client/waypointsprites.qh +++ b/qcsrc/client/waypointsprites.qh @@ -78,6 +78,7 @@ void Draw_WaypointSprite(); // they are drawn using a .draw function void Ent_RemoveWaypointSprite(); + void Ent_WaypointSprite(); void WaypointSprite_Load_Frames(string ext); diff --git a/qcsrc/common/buffs.qh b/qcsrc/common/buffs.qh index db57943241..ddf5722816 100644 --- a/qcsrc/common/buffs.qh +++ b/qcsrc/common/buffs.qh @@ -34,7 +34,7 @@ CLASS(Buff, Pickup) ATTRIB(Buff, m_skin, int, 0) ATTRIB(Buff, m_sprite, string, "") #ifdef SVQC - METHOD(Buff, m_time, float(entity)) + METHOD(Buff, m_time, float(entity)); float Buff_m_time(entity this) { return cvar(strcat("g_buffs_", this.netname, "_time")); } #endif ENDCLASS(Buff) diff --git a/qcsrc/common/command/generic.qc b/qcsrc/common/command/generic.qc index 6aa93a024e..d12cc064e5 100644 --- a/qcsrc/common/command/generic.qc +++ b/qcsrc/common/command/generic.qc @@ -20,7 +20,7 @@ #include "../../server/command/cmd.qh" #include "../../server/command/common.qh" #include "../../server/command/sv_cmd.qh" - + #include "../../common/turrets/config.qh" #include "../../common/weapons/config.qh" #endif @@ -363,6 +363,59 @@ void GenericCommand_dumpweapons(float request) // WEAPONTODO: make this work wit } } +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) @@ -672,6 +725,7 @@ void GenericCommand_(float request) GENERIC_COMMAND("dumpcommands", GenericCommand_dumpcommands(request), "Dump all commands on the program to *_cmd_dump.txt") \ GENERIC_COMMAND("dumpitems", GenericCommand_dumpitems(request), "Dump all items to the console") \ GENERIC_COMMAND("dumpnotifs", GenericCommand_dumpnotifs(request), "Dump all notifications into notifications_dump.txt") \ + GENERIC_COMMAND("dumpturrets", GenericCommand_dumpturrets(request), "Dump all turrets into turrets_dump.txt") \ GENERIC_COMMAND("dumpweapons", GenericCommand_dumpweapons(request), "Dump all weapons into weapons_dump.txt") \ GENERIC_COMMAND("maplist", GenericCommand_maplist(request, arguments), "Automatic control of maplist") \ GENERIC_COMMAND("nextframe", GenericCommand_nextframe(request, arguments, command), "Execute the given command next frame of this VM") \ diff --git a/qcsrc/common/constants.qh b/qcsrc/common/constants.qh index 1953b1f33d..231046d6dd 100644 --- a/qcsrc/common/constants.qh +++ b/qcsrc/common/constants.qh @@ -31,6 +31,14 @@ const int AS_INT = 2; const int AS_FLOAT_TRUNCATED = 2; const int AS_FLOAT = 8; +const int TE_CSQC_MUTATOR = 99; +#define MUTATOR_HASH(s) crc16(true, s) +#define WriteMutator(to, s) do { \ + WriteByte(to, TE_CSQC_MUTATOR); \ + WriteLong(to, MUTATOR_HASH(#s)); \ +} while (0) +#define ReadMutator() ReadLong() +#define ReadMutatorEquals(read, s) (read == MUTATOR_HASH(#s)) const int TE_CSQC_PICTURE = 100; const int TE_CSQC_RACE = 101; const int TE_CSQC_VORTEXBEAMPARTICLE = 103; @@ -115,7 +123,9 @@ const int ENT_CLIENT_TRIGGER_IMPULSE = 68; const int ENT_CLIENT_SWAMP = 69; const int ENT_CLIENT_CORNER = 70; const int ENT_CLIENT_KEYLOCK = 71; -const int ENT_CLIENT_EFFECT = 72; +const int ENT_CLIENT_GENERATOR = 72; +const int ENT_CLIENT_CONTROLPOINT_ICON = 73; +const int ENT_CLIENT_EFFECT = 74; const int ENT_CLIENT_VIEWLOC = 78; const int ENT_CLIENT_VIEWLOC_TRIGGER = 79; diff --git a/qcsrc/common/csqcmodel_settings.qh b/qcsrc/common/csqcmodel_settings.qh index ac14969f24..e11604aae3 100644 --- a/qcsrc/common/csqcmodel_settings.qh +++ b/qcsrc/common/csqcmodel_settings.qh @@ -61,7 +61,7 @@ CSQCMODEL_PROPERTY(1024, float, ReadAngle, WriteAngle, v_angle_x) \ CSQCMODEL_PROPERTY_SCALED(4096, float, ReadByte, WriteByte, scale, 16, 0, 255) \ CSQCMODEL_PROPERTY(8192, int, ReadInt24_t, WriteInt24_t, dphitcontentsmask) \ - CSQCMODEL_PROPERTY(16384, TAG_VIEWLOC_TYPE, ReadShort, WriteEntity, TAG_VIEWLOC_NAME) + CSQCMODEL_PROPERTY(16384, TAG_VIEWLOC_TYPE, ReadShort, WriteEntity, TAG_VIEWLOC_NAME) // TODO get rid of colormod/glowmod here, find good solution for vortex charge glowmod hack; also get rid of some useless properties on non-players that only exist for CopyBody // add hook function calls here diff --git a/qcsrc/common/deathtypes.qh b/qcsrc/common/deathtypes.qh index dae684c14f..b9c215f907 100644 --- a/qcsrc/common/deathtypes.qh +++ b/qcsrc/common/deathtypes.qh @@ -62,7 +62,7 @@ int DEATH_VHLAST; 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) \ diff --git a/qcsrc/common/effects.qc b/qcsrc/common/effects.qc index 81dbd704fd..349fdffbfb 100644 --- a/qcsrc/common/effects.qc +++ b/qcsrc/common/effects.qc @@ -34,7 +34,7 @@ void Read_Effect(bool is_new) vel_y = ReadCoord(); vel_z = ReadCoord(); } - + if(!eff_trail) eff_cnt = ReadByte(); @@ -117,4 +117,4 @@ void Send_Effect(string eff_name, vector eff_loc, vector eff_vel, int eff_cnt) Net_LinkEntity(net_eff, false, 0, Net_Write_Effect); } -#endif \ No newline at end of file +#endif diff --git a/qcsrc/common/effects.qh b/qcsrc/common/effects.qh index 5262dee543..790d8a7db6 100644 --- a/qcsrc/common/effects.qh +++ b/qcsrc/common/effects.qh @@ -91,7 +91,7 @@ EFFECT(0, EFFECT_ITEM_PICKUP, "item_pickup") \ EFFECT(0, EFFECT_ITEM_RESPAWN, "item_respawn") \ EFFECT(0, EFFECT_JUMPPAD, "jumppad_activate") \ - EFFECT(1, EFFECT_BULLET, "tr_bullet") + EFFECT(1, EFFECT_BULLET, "tr_bullet") diff --git a/qcsrc/common/items/item.qh b/qcsrc/common/items/item.qh index 6ecd6d7f7a..0b17f35b2c 100644 --- a/qcsrc/common/items/item.qh +++ b/qcsrc/common/items/item.qh @@ -5,7 +5,7 @@ /** If you register a new item, make sure to add it to all.inc */ CLASS(GameItem, Object) ATTRIB(GameItem, m_id, int, 0) - METHOD(GameItem, show, void(entity this)) + METHOD(GameItem, show, void(entity this)); void GameItem_show(entity this) { print("A game item\n"); } void ITEM_HANDLE(Show, entity this) { this.show(this); } ENDCLASS(GameItem) diff --git a/qcsrc/common/items/item/pickup.qh b/qcsrc/common/items/item/pickup.qh index 1875517f13..643617068c 100644 --- a/qcsrc/common/items/item/pickup.qh +++ b/qcsrc/common/items/item/pickup.qh @@ -5,7 +5,7 @@ CLASS(Pickup, GameItem) ATTRIB(Pickup, m_model, string, string_null) ATTRIB(Pickup, m_sound, string, "misc/itempickup.wav") ATTRIB(Pickup, m_name, string, string_null) - METHOD(Pickup, show, void(entity this)) + METHOD(Pickup, show, void(entity this)); void Pickup_show(entity this) { printf("%s: %s\n", etos(this), this.m_name); } #ifdef SVQC ATTRIB(Pickup, m_botvalue, int, 0) @@ -14,7 +14,7 @@ CLASS(Pickup, GameItem) ATTRIB(Pickup, m_pickupevalfunc, float(entity player, entity item), generic_pickupevalfunc) ATTRIB(Pickup, m_respawntime, float(), func_null) ATTRIB(Pickup, m_respawntimejitter, float(), func_null) - METHOD(Pickup, giveTo, bool(entity this, entity item, entity player)) + METHOD(Pickup, giveTo, bool(entity this, entity item, entity player)); bool Pickup_giveTo(entity this, entity item, entity player) { return Item_GiveTo(item, player); } bool ITEM_HANDLE(Pickup, entity this, entity item, entity player); #endif diff --git a/qcsrc/common/mapinfo.qh b/qcsrc/common/mapinfo.qh index 22b17d900d..e9979379c9 100644 --- a/qcsrc/common/mapinfo.qh +++ b/qcsrc/common/mapinfo.qh @@ -52,49 +52,49 @@ REGISTER_REGISTRY(RegisterGametypes) #define IS_GAMETYPE(NAME) \ (MapInfo_LoadedGametype == MAPINFO_TYPE_##NAME) -REGISTER_GAMETYPE(_("Deathmatch"),dm,g_dm,DEATHMATCH,false,"timelimit=20 pointlimit=30 leadlimit=0",_("Kill all enemies")); +REGISTER_GAMETYPE(_("Deathmatch"),dm,g_dm,DEATHMATCH,false,"timelimit=20 pointlimit=30 leadlimit=0",_("Score as many frags as you can.")); #define g_dm IS_GAMETYPE(DEATHMATCH) -REGISTER_GAMETYPE(_("Last Man Standing"),lms,g_lms,LMS,false,"timelimit=20 lives=9 leadlimit=0",_("Survive and kill until the enemies have no lives left")); +REGISTER_GAMETYPE(_("Last Man Standing"),lms,g_lms,LMS,false,"timelimit=20 lives=9 leadlimit=0",_("Survive and kill until the enemies have no lives left.")); #define g_lms IS_GAMETYPE(LMS) -REGISTER_GAMETYPE(_("Race"),rc,g_race,RACE,false,"timelimit=20 qualifying_timelimit=5 laplimit=7 teamlaplimit=15 leadlimit=0",_("Race against other players to the finish line")); +REGISTER_GAMETYPE(_("Race"),rc,g_race,RACE,false,"timelimit=20 qualifying_timelimit=5 laplimit=7 teamlaplimit=15 leadlimit=0",_("Race against other players to the finish line.")); #define g_race IS_GAMETYPE(RACE) -REGISTER_GAMETYPE(_("Race CTS"),cts,g_cts,CTS,false,"timelimit=20 skill=-1",_("Race for fastest time")); +REGISTER_GAMETYPE(_("Race CTS"),cts,g_cts,CTS,false,"timelimit=20 skill=-1",_("Race for fastest time.")); #define g_cts IS_GAMETYPE(CTS) -REGISTER_GAMETYPE(_("Team Deathmatch"),tdm,g_tdm,TEAM_DEATHMATCH,true,"timelimit=20 pointlimit=50 teams=2 leadlimit=0",_("Kill all enemy teammates")); +REGISTER_GAMETYPE(_("Team Deathmatch"),tdm,g_tdm,TEAM_DEATHMATCH,true,"timelimit=20 pointlimit=50 teams=2 leadlimit=0",_("Help your team score the most frags against the enemy team.")); #define g_tdm IS_GAMETYPE(TEAM_DEATHMATCH) -REGISTER_GAMETYPE(_("Capture the Flag"),ctf,g_ctf,CTF,true,"timelimit=20 caplimit=10 leadlimit=6",_("Find and bring the enemy flag to your base to capture it")); +REGISTER_GAMETYPE(_("Capture the Flag"),ctf,g_ctf,CTF,true,"timelimit=20 caplimit=10 leadlimit=6",_("Find and bring the enemy flag to your base to capture it, defend your base from the other team.")); #define g_ctf IS_GAMETYPE(CTF) -REGISTER_GAMETYPE(_("Clan Arena"),ca,g_ca,CA,true,"timelimit=20 pointlimit=10 teams=2 leadlimit=0",_("Kill all enemy teammates to win the round")); +REGISTER_GAMETYPE(_("Clan Arena"),ca,g_ca,CA,true,"timelimit=20 pointlimit=10 teams=2 leadlimit=0",_("Kill all enemy teammates to win the round.")); #define g_ca IS_GAMETYPE(CA) -REGISTER_GAMETYPE(_("Domination"),dom,g_domination,DOMINATION,true,"timelimit=20 pointlimit=200 teams=2 leadlimit=0",_("Capture all the control points to win")); +REGISTER_GAMETYPE(_("Domination"),dom,g_domination,DOMINATION,true,"timelimit=20 pointlimit=200 teams=2 leadlimit=0",_("Capture and defend all the control points to win.")); #define g_domination IS_GAMETYPE(DOMINATION) -REGISTER_GAMETYPE(_("Key Hunt"),kh,g_keyhunt,KEYHUNT,true,"timelimit=20 pointlimit=1000 teams=3 leadlimit=0",_("Gather all the keys to win the round")); +REGISTER_GAMETYPE(_("Key Hunt"),kh,g_keyhunt,KEYHUNT,true,"timelimit=20 pointlimit=1000 teams=3 leadlimit=0",_("Gather all the keys to win the round.")); #define g_keyhunt IS_GAMETYPE(KEYHUNT) -REGISTER_GAMETYPE(_("Assault"),as,g_assault,ASSAULT,true,"timelimit=20",_("Destroy obstacles to find and destroy the enemy power core before time runs out")); +REGISTER_GAMETYPE(_("Assault"),as,g_assault,ASSAULT,true,"timelimit=20",_("Destroy obstacles to find and destroy the enemy power core before time runs out.")); #define g_assault IS_GAMETYPE(ASSAULT) -REGISTER_GAMETYPE(_("Onslaught"),ons,g_onslaught,ONSLAUGHT,true,"timelimit=20",_("Capture control points to reach and destroy the enemy generator")); +REGISTER_GAMETYPE(_("Onslaught"),ons,g_onslaught,ONSLAUGHT,true,"pointlimit=1 timelimit=20",_("Capture control points to reach and destroy the enemy generator.")); #define g_onslaught IS_GAMETYPE(ONSLAUGHT) -REGISTER_GAMETYPE(_("Nexball"),nb,g_nexball,NEXBALL,true,"timelimit=20 pointlimit=5 leadlimit=0",_("XonSports")); +REGISTER_GAMETYPE(_("Nexball"),nb,g_nexball,NEXBALL,true,"timelimit=20 pointlimit=5 leadlimit=0",_("Shoot and kick the ball into the enemies goal, keep your goal clean.")); #define g_nexball IS_GAMETYPE(NEXBALL) -REGISTER_GAMETYPE(_("Freeze Tag"),ft,g_freezetag,FREEZETAG,true,"timelimit=20 pointlimit=10 teams=2 leadlimit=0",_("Kill enemies to freeze them, stand next to teammates to revive them")); +REGISTER_GAMETYPE(_("Freeze Tag"),ft,g_freezetag,FREEZETAG,true,"timelimit=20 pointlimit=10 teams=2 leadlimit=0",_("Kill enemies to freeze them, stand next to teammates to revive them, freeze the most enemies to win.")); #define g_freezetag IS_GAMETYPE(FREEZETAG) -REGISTER_GAMETYPE(_("Keepaway"),ka,g_keepaway,KEEPAWAY,true,"timelimit=20 pointlimit=30",_("Hold the ball to get points for kills")); +REGISTER_GAMETYPE(_("Keepaway"),ka,g_keepaway,KEEPAWAY,true,"timelimit=20 pointlimit=30",_("Hold the ball to get points for kills.")); #define g_keepaway IS_GAMETYPE(KEEPAWAY) -REGISTER_GAMETYPE(_("Invasion"),inv,g_invasion,INVASION,false,"pointlimit=50 teams=0",_("Survive against waves of monsters")); +REGISTER_GAMETYPE(_("Invasion"),inv,g_invasion,INVASION,false,"pointlimit=50 teams=0",_("Survive against waves of monsters.")); #define g_invasion IS_GAMETYPE(INVASION) const int MAPINFO_FEATURE_WEAPONS = 1; // not defined for instagib-only maps diff --git a/qcsrc/common/monsters/sv_monsters.qc b/qcsrc/common/monsters/sv_monsters.qc index 887ac20ec3..249e6f97eb 100644 --- a/qcsrc/common/monsters/sv_monsters.qc +++ b/qcsrc/common/monsters/sv_monsters.qc @@ -14,15 +14,16 @@ #include "../../server/defs.qh" #include "../deathtypes.qh" #include "../../server/mutators/mutators_include.qh" - #include "../../server/tturrets/include/turrets_early.qh" - #include "../vehicles/sv_vehicles.qh" + #include "../../server/steerlib.qh" + #include "../turrets/sv_turrets.qh" + #include "../turrets/util.qh" + #include "../vehicles/all.qh" #include "../../server/campaign.qh" #include "../../server/command/common.qh" #include "../../server/command/cmd.qh" #include "../triggers/triggers.qh" #include "../../csqcmodellib/sv_model.qh" #include "../../server/round_handler.qh" - #include "../../server/tturrets/include/turrets.qh" #endif // ========================= diff --git a/qcsrc/common/movetypes/movetypes.qc b/qcsrc/common/movetypes/movetypes.qc index 3dd286e000..90be7738c2 100644 --- a/qcsrc/common/movetypes/movetypes.qc +++ b/qcsrc/common/movetypes/movetypes.qc @@ -42,7 +42,7 @@ int _Movetype_FlyMove(float dt, bool applygravity, vector stepnormal, float step for(i = 0; i <= MAX_CLIP_PLANES; ++i) planes[i] = '0 0 0'; - + grav = 0; restore_velocity = self.move_velocity; diff --git a/qcsrc/common/movetypes/push.qh b/qcsrc/common/movetypes/push.qh index 44d5442ea6..685982b144 100644 --- a/qcsrc/common/movetypes/push.qh +++ b/qcsrc/common/movetypes/push.qh @@ -3,4 +3,4 @@ void _Movetype_Physics_Pusher(float dt); -#endif \ No newline at end of file +#endif diff --git a/qcsrc/common/movetypes/toss.qh b/qcsrc/common/movetypes/toss.qh index 9e11595350..63152e007f 100644 --- a/qcsrc/common/movetypes/toss.qh +++ b/qcsrc/common/movetypes/toss.qh @@ -3,4 +3,4 @@ void _Movetype_Physics_Toss(float dt); -#endif \ No newline at end of file +#endif diff --git a/qcsrc/common/mutators/all.inc b/qcsrc/common/mutators/all.inc new file mode 100644 index 0000000000..4cb1a6ceaa --- /dev/null +++ b/qcsrc/common/mutators/all.inc @@ -0,0 +1 @@ +#include "mutator/damagetext.qc" diff --git a/qcsrc/common/mutators/all.qc b/qcsrc/common/mutators/all.qc new file mode 100644 index 0000000000..14530a3c5e --- /dev/null +++ b/qcsrc/common/mutators/all.qc @@ -0,0 +1 @@ +#include "all.inc" diff --git a/qcsrc/common/mutators/events.qh b/qcsrc/common/mutators/events.qh index e193d5f8a0..eb46486b6b 100644 --- a/qcsrc/common/mutators/events.qh +++ b/qcsrc/common/mutators/events.qh @@ -3,8 +3,28 @@ #define EV_NO_ARGS(i, o) +#pragma noref 1 string ret_string; +#define MUTATOR_TYPES(_, x) \ + _(x, bool) \ + _(x, int) \ + _(x, entity) \ + _(x, float) \ + _(x, vector) \ + _(x, string) \ + /**/ + +#define MUTATOR_NEWGLOBAL(x, type) type mutator_argv_##type##_##x; + +MUTATOR_TYPES(MUTATOR_NEWGLOBAL, 0) +MUTATOR_TYPES(MUTATOR_NEWGLOBAL, 1) + +#undef MUTATOR_TYPES +#undef MUTATOR_NEWGLOBAL + +#pragma noref 0 + /** appends ":mutatorname" to ret_string for logging */ #define EV_BuildMutatorsString(i, o) \ /**/ i(string, ret_string) \ diff --git a/qcsrc/common/mutators/mutator/damagetext.qc b/qcsrc/common/mutators/mutator/damagetext.qc new file mode 100644 index 0000000000..aacfc730a7 --- /dev/null +++ b/qcsrc/common/mutators/mutator/damagetext.qc @@ -0,0 +1,125 @@ +REGISTER_MUTATOR(damagetext, true); + +#ifdef CSQC +bool autocvar_cl_damagetext = false; +string autocvar_cl_damagetext_format = "-%3$d"; +vector autocvar_cl_damagetext_color = '1 1 0'; +float autocvar_cl_damagetext_size = 8; +float autocvar_cl_damagetext_alpha_start = 1; +float autocvar_cl_damagetext_alpha_lifetime = 3; +vector autocvar_cl_damagetext_velocity = '0 0 20'; +vector autocvar_cl_damagetext_offset = '0 -40 0'; +float autocvar_cl_damagetext_accumulate_range = 30; +STATIC_INIT(cl_damagetext) { + CVAR_DESCRIBE(cl_damagetext, _("Draw damage dealt. 0: disabled, 1: enabled")); + CVAR_DESCRIBESTR(cl_damagetext_format, _("How to format the damage text. 1$ is health, 2$ is armor, 3$ is both")); + CVAR_DESCRIBEVEC(cl_damagetext_color, _("Default damage text color")); + CVAR_DESCRIBE(cl_damagetext_size, _("Damage text font size")); + CVAR_DESCRIBE(cl_damagetext_alpha_start, _("Damage text initial alpha")); + CVAR_DESCRIBE(cl_damagetext_alpha_lifetime, _("Damage text lifetime in seconds")); + CVAR_DESCRIBEVEC(cl_damagetext_velocity, _("Damage text move direction")); + CVAR_DESCRIBEVEC(cl_damagetext_offset, _("Damage text offset")); + CVAR_DESCRIBE(cl_damagetext_accumulate_range, _("Damage text spawned within this range is accumulated")); +} + +CLASS(DamageText, Object) + ATTRIB(DamageText, m_color, vector, autocvar_cl_damagetext_color) + ATTRIB(DamageText, m_size, float, autocvar_cl_damagetext_size) + ATTRIB(DamageText, alpha, float, autocvar_cl_damagetext_alpha_start) + ATTRIB(DamageText, fade_rate, float, 1 / autocvar_cl_damagetext_alpha_lifetime) + ATTRIB(DamageText, velocity, vector, autocvar_cl_damagetext_velocity) + ATTRIB(DamageText, m_group, int, 0) + ATTRIB(DamageText, m_damage, int, 0) + ATTRIB(DamageText, m_armordamage, int, 0) + ATTRIB(DamageText, time_prev, float, time) + + void DamageText_draw() { + entity this = self; + float dt = time - this.time_prev; + this.time_prev = time; + setorigin(this, this.origin + dt * this.velocity); + this.alpha -= dt * this.fade_rate; + if (this.alpha < 0) remove(this); + vector pos = project_3d_to_2d(this.origin) + autocvar_cl_damagetext_offset; + if (pos.z >= 0 && this.m_size > 0) { + pos.z = 0; + string s = sprintf(autocvar_cl_damagetext_format, this.m_damage, this.m_armordamage, this.m_damage + this.m_armordamage); + drawcolorcodedstring2(pos, s, this.m_size * '1 1 0', this.m_color, this.alpha, DRAWFLAG_NORMAL); + } + } + ATTRIB(DamageText, draw2d, void(), DamageText_draw) + + void DamageText_update(DamageText this, vector _origin, int _health, int _armor) { + this.m_damage = _health; + this.m_armordamage = _armor; + setorigin(this, _origin); + this.alpha = 1; + } + + CONSTRUCTOR(DamageText, int _group, vector _origin, int _health, int _armor) { + CONSTRUCT(DamageText); + this.m_group = _group; + DamageText_update(this, _origin, _health, _armor); + return this; + } +ENDCLASS(DamageText) +#endif + +#ifdef SVQC +int autocvar_sv_damagetext = 2; +STATIC_INIT(sv_damagetext) { + CVAR_DESCRIBE(sv_damagetext, _("<= 0: disabled, >= 1: spectators, >= 2: players, >= 3: all players")); +} +#define SV_DAMAGETEXT_DISABLED() (autocvar_sv_damagetext <= 0 /* disabled */) +#define SV_DAMAGETEXT_SPECTATORS_ONLY() (autocvar_sv_damagetext >= 1 /* spectators only */) +#define SV_DAMAGETEXT_PLAYERS() (autocvar_sv_damagetext >= 2 /* players */) +#define SV_DAMAGETEXT_ALL() (autocvar_sv_damagetext >= 3 /* all players */) +MUTATOR_HOOKFUNCTION(damagetext, PlayerDamaged) { + if (SV_DAMAGETEXT_DISABLED()) return; + const entity attacker = mutator_argv_entity_0; + const entity hit = mutator_argv_entity_1; if (hit == attacker) return; + const int health = mutator_argv_int_0; + const int armor = mutator_argv_int_1; + const vector location = hit.origin; + entity e; + FOR_EACH_REALCLIENT(e) if ( + (SV_DAMAGETEXT_ALL()) || + (SV_DAMAGETEXT_PLAYERS() && e == attacker) || + (SV_DAMAGETEXT_SPECTATORS_ONLY() && IS_SPEC(e) && e.enemy == attacker) || + (SV_DAMAGETEXT_SPECTATORS_ONLY() && IS_OBSERVER(e)) + ) { + msg_entity = e; + WriteByte(MSG_ONE, SVC_TEMPENTITY); + WriteMutator(MSG_ONE, damagetext); + WriteShort(MSG_ONE, health); + WriteShort(MSG_ONE, armor); + WriteEntity(MSG_ONE, hit); + WriteCoord(MSG_ONE, location.x); + WriteCoord(MSG_ONE, location.y); + WriteCoord(MSG_ONE, location.z); + } +} +#endif + +#ifdef CSQC +MUTATOR_HOOKFUNCTION(damagetext, CSQC_Parse_TempEntity) { + if (MUTATOR_RETURNVALUE) return false; + if (!ReadMutatorEquals(mutator_argv_int_0, damagetext)) return false; + int health = ReadShort(); + int armor = ReadShort(); + int group = ReadShort(); + vector location = vec3(ReadCoord(), ReadCoord(), ReadCoord()); + if (autocvar_cl_damagetext) { + if (autocvar_cl_damagetext_accumulate_range) { + for (entity e = findradius(location, autocvar_cl_damagetext_accumulate_range); e; e = e.chain) { + if (e.instanceOfDamageText && e.m_group == group) { + DamageText_update(e, location, e.m_damage + health, e.m_armordamage + armor); + return true; + } + } + } + NEW(DamageText, group, location, health, armor); + } + return true; +} +#endif diff --git a/qcsrc/common/nades.qc b/qcsrc/common/nades.qc index fcdc5533e4..f9ddb8e991 100644 --- a/qcsrc/common/nades.qc +++ b/qcsrc/common/nades.qc @@ -4,7 +4,6 @@ #include "nades.qh" #include "buffs.qh" #include "../common/movetypes/movetypes.qh" - #include "../server/tturrets/include/turrets_early.qh" #include "../client/main.qh" #include "../csqcmodellib/cl_model.qh" #elif defined(MENUQC) @@ -12,6 +11,7 @@ #include "../dpdefs/progsdefs.qh" #include "constants.qh" #include "../server/constants.qh" + #include "../common/turrets/sv_turrets.qh" #endif diff --git a/qcsrc/common/notifications.qh b/qcsrc/common/notifications.qh index 59d9f62b17..92386b3132 100644 --- a/qcsrc/common/notifications.qh +++ b/qcsrc/common/notifications.qh @@ -447,7 +447,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"), "") \ @@ -493,6 +493,10 @@ void Send_Notification_WOCOVA( MSG_INFO_NOTIF(1, INFO_LMS_FORFEIT, 1, 0, "s1", "", "", _("^BG%s^F3 forfeited"), "") \ MSG_INFO_NOTIF(1, INFO_LMS_NOLIVES, 1, 0, "s1", "", "", _("^BG%s^F3 has no more lives left"), "") \ MSG_INFO_NOTIF(1, INFO_MONSTERS_DISABLED, 0, 0, "", "", "", _("^BGMonsters are currently disabled"), "") \ + MSG_INFO_NOTIF(1, INFO_ONSLAUGHT_CAPTURE, 2, 0, "s1 s2", "", "", _("^BG%s^BG captured %s^BG control point"), "") \ + MULTITEAM_INFO(1, INFO_ONSLAUGHT_CPDESTROYED_, 4, 2, 0, "s1 s2", "", "", _("^TC^TT^BG team %s^BG control point has been destroyed by %s"), "") \ + MULTITEAM_INFO(1, INFO_ONSLAUGHT_GENDESTROYED_, 4, 0, 0, "", "", "", _("^TC^TT^BG generator has been destroyed"), "") \ + MULTITEAM_INFO(1, INFO_ONSLAUGHT_GENDESTROYED_OVERTIME_, 4, 0, 0, "", "", "", _("^TC^TT^BG generator spontaneously combusted due to overtime!"), "") \ MSG_INFO_NOTIF(1, INFO_POWERUP_INVISIBILITY, 1, 0, "s1", "s1", "strength", _("^BG%s^K1 picked up Invisibility"), "") \ MSG_INFO_NOTIF(1, INFO_POWERUP_SHIELD, 1, 0, "s1", "s1", "shield", _("^BG%s^K1 picked up Shield"), "") \ MSG_INFO_NOTIF(1, INFO_POWERUP_SPEED, 1, 0, "s1", "s1", "shield", _("^BG%s^K1 picked up Speed"), "") \ @@ -693,6 +697,7 @@ void Send_Notification_WOCOVA( MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_REVIVE_SELF, 0, 0, "", NO_CPID, "0 0", _("^K3You revived yourself"), "") \ MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_REVIVED, 1, 0, "s1", NO_CPID, "0 0", _("^K3You were revived by ^BG%s"), "") \ MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_AUTO_REVIVED, 0, 1, "f1", NO_CPID, "0 0", _("^K3You were automatically revived after %s second(s)"), "") \ + MSG_CENTER_NOTIF(1, CENTER_GENERATOR_UNDERATTACK, 0, 0, "", NO_CPID, "0 0", _("^BGThe generator is under attack!"), "") \ MULTITEAM_CENTER(1, CENTER_ROUND_TEAM_WIN_, 4, 0, 0, "", CPID_ROUND, "0 0", _("^TC^TT^BG team wins the round"), "") \ MSG_CENTER_NOTIF(1, CENTER_ROUND_PLAYER_WIN, 1, 0, "s1", CPID_ROUND, "0 0", _("^BG%s^BG wins the round"), "") \ MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_SELF, 0, 0, "", NO_CPID, "0 0", _("^K1You froze yourself"), "") \ @@ -728,7 +733,14 @@ void Send_Notification_WOCOVA( MSG_CENTER_NOTIF(1, CENTER_NIX_COUNTDOWN, 0, 2, "item_wepname", CPID_NIX, "1 f2", _("^F2^COUNT^BG until weapon change...\nNext weapon: ^F1%s"), "") \ MSG_CENTER_NOTIF(1, CENTER_NIX_NEWWEAPON, 0, 1, "item_wepname", CPID_NIX, "0 0", _("^F2Active weapon: ^F1%s"), "") \ MSG_CENTER_NOTIF(1, CENTER_NADE, 0, 0, "", NO_CPID, "0 0", _("^BGPress ^F2DROPWEAPON^BG again to toss the grenade!"), "") \ - MSG_CENTER_NOTIF(1, CENTER_ONS_NOTSHIELDED, 0, 0, "", CPID_ONSLAUGHT, "0 0", _("^K1Your generator is NOT shielded!\n^BGRe-capture controlpoints to shield it!"), "") \ + MSG_CENTER_NOTIF(1, CENTER_ONS_CAPTURE, 1, 0, "s1", CPID_ONSLAUGHT, "0 0", _("^BGYou captured %s^BG control point"), "") \ + MULTITEAM_CENTER(1, CENTER_ONS_CAPTURE_, 4, 1, 0, "s1", CPID_ONSLAUGHT, "0 0", _("^TC^TT^BG team captured %s^BG control point"), "") \ + MSG_CENTER_NOTIF(1, CENTER_ONS_CONTROLPOINT_SHIELDED, 0, 0, "", CPID_ONS_CAPSHIELD, "0 0", _("^BGThis control point currently cannot be captured"), "") \ + MSG_CENTER_NOTIF(1, CENTER_ONS_GENERATOR_SHIELDED, 0, 0, "", CPID_ONS_CAPSHIELD, "0 0", _("^BGThe enemy generator cannot be destroyed yet\n^F2Capture some control points to unshield it"), "") \ + MULTITEAM_CENTER(1, CENTER_ONS_NOTSHIELDED_, 4, 0, 0, "", CPID_ONSLAUGHT, "0 0", _("^BGThe ^TCenemy^BG generator is no longer shielded!"), "") \ + MSG_CENTER_NOTIF(1, CENTER_ONS_NOTSHIELDED_TEAM, 0, 0, "", CPID_ONSLAUGHT, "0 0", _("^K1Your generator is NOT shielded!\n^BGRe-capture control points to shield it!"), "") \ + MSG_CENTER_NOTIF(1, CENTER_ONS_TELEPORT, 0, 0, "pass_key", CPID_ONSLAUGHT, "0 0", _("^BGPress ^F2DROPFLAG%s^BG to teleport"), "") \ + MSG_CENTER_NOTIF(1, CENTER_ONS_TELEPORT_ANTISPAM, 0, 1, "f1secs", CPID_ONSLAUGHT, "0 0", _("^BGTeleporting disabled for %s"), "") \ MSG_CENTER_NOTIF(1, CENTER_OVERTIME_FRAG, 0, 0, "", CPID_OVERTIME, "0 0", _("^F2Now playing ^F4OVERTIME^F2!\nKeep fragging until we have a winner!"), _("^F2Now playing ^F4OVERTIME^F2!\nKeep scoring until we have a winner!")) \ MSG_CENTER_NOTIF(1, CENTER_OVERTIME_CONTROLPOINT, 0, 0, "", CPID_OVERTIME, "5 0", _("^F2Now playing ^F4OVERTIME^F2!\n\nGenerators are now decaying.\nThe more control points your team holds,\nthe faster the enemy generator decays"), "") \ MSG_CENTER_NOTIF(1, CENTER_OVERTIME_TIME, 0, 1, "f1time", CPID_OVERTIME, "0 0", _("^F2Now playing ^F4OVERTIME^F2!\n^BGAdded ^F4%s^BG to the game!"), "") \ @@ -852,7 +864,7 @@ void Send_Notification_WOCOVA( 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) \ @@ -1333,6 +1345,7 @@ enum { , CPID_MOTD , CPID_NIX , CPID_ONSLAUGHT +, CPID_ONS_CAPSHIELD , CPID_OVERTIME , CPID_POWERUP , CPID_RACE_FINISHLAP @@ -1353,7 +1366,7 @@ float NOTIF_CHOICE_COUNT; // notification limits -- INCREASE AS NECESSARY const float NOTIF_ANNCE_MAX = 100; -const float NOTIF_INFO_MAX = 300; +const float NOTIF_INFO_MAX = 350; const float NOTIF_CENTER_MAX = 250; const float NOTIF_MULTI_MAX = 200; const float NOTIF_CHOICE_MAX = 30; diff --git a/qcsrc/common/oo.qh b/qcsrc/common/oo.qh index aa660ab15d..add63b0cd8 100644 --- a/qcsrc/common/oo.qh +++ b/qcsrc/common/oo.qh @@ -97,7 +97,8 @@ ACCUMULATE_FUNCTION(__static_init, RegisterClasses) #define METHOD(cname, name, prototype) \ class(cname) .prototype name; \ prototype cname##_##name; \ - INIT_STATIC(cname) { this.name = cname##_##name; } + INIT_STATIC(cname) { this.name = cname##_##name; } \ + prototype cname##_##name #define ATTRIB(cname, name, type, val) \ class(cname) .type name; \ diff --git a/qcsrc/common/p2mathlib.qc b/qcsrc/common/p2mathlib.qc index ad569ffbc5..85c5396d7e 100644 --- a/qcsrc/common/p2mathlib.qc +++ b/qcsrc/common/p2mathlib.qc @@ -1,22 +1,22 @@ /* Copyright (C) 2015 Micah Talkiewicz. - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - + See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - + vector vec_bias(vector v, float f){ vector c; c_x = v_x + f; @@ -31,7 +31,7 @@ vector vec_to_min (vector a, vector b) { c_z = min (a_z, b_z); return c; } - + vector vec_to_max (vector a, vector b) { vector c; c_x = max (a_x, b_x); @@ -39,46 +39,46 @@ vector vec_to_max (vector a, vector b) { c_z = max (a_z, b_z); return c; } - + // there may already be a function for bounding a vector in this manner, however my very quick search did not reveal one -- Player_2 vector vec_bounds_in (vector point, vector a, vector b) { vector c, d, e; - + d = vec_to_min(a,b); e = vec_to_max(a,b); - + c = vec_to_max(point, d); c = vec_to_min(c, e); - + return c; - + } - + vector vec_bounds_out (vector point, vector a, vector b) { vector c, d, e; - + d = vec_to_max(a,b); e = vec_to_min(a,b); - + c = vec_to_max(point, d); c = vec_to_min(c, e); - + return c; - + } - + float angle_snap_f (float f, float increment){ - + float i; for (i = 0; i <= 360; ){ if (f <= i - increment) return i - increment; i = i + increment; } - + return 0; } - + vector angle_snap_vec (vector v, float increment) { vector c; c_x = angle_snap_f (v_x, increment); diff --git a/qcsrc/common/p2mathlib.qh b/qcsrc/common/p2mathlib.qh index a8dc7ab445..c92f26a912 100644 --- a/qcsrc/common/p2mathlib.qh +++ b/qcsrc/common/p2mathlib.qh @@ -1,17 +1,17 @@ /* Copyright (C) 2015 Micah Talkiewicz. - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - + See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. diff --git a/qcsrc/common/physics.qc b/qcsrc/common/physics.qc index 6c0bd616bc..e5b83443fb 100644 --- a/qcsrc/common/physics.qc +++ b/qcsrc/common/physics.qc @@ -327,7 +327,7 @@ void PM_ClientMovement_Move() vector trace1_plane_normal = '0 0 0'; vector trace2_plane_normal = '0 0 0'; vector trace3_plane_normal = '0 0 0'; - + PM_ClientMovement_UpdateStatus(false); primalvelocity = self.velocity; @@ -1668,7 +1668,7 @@ void PM_Main() PM_ClientMovement_UpdateStatus(true); #endif - + #ifdef SVQC WarpZone_PlayerPhysics_FixVAngle(); @@ -1936,7 +1936,7 @@ void CSQC_ClientMovement_PlayerMove_Frame(void) PM_Main(); #ifdef CSQC - self.pmove_flags = + self.pmove_flags = ((self.flags & FL_DUCKED) ? PMF_DUCKED : 0) | (!(self.flags & FL_JUMPRELEASED) ? 0 : PMF_JUMP_HELD) | ((self.flags & FL_ONGROUND) ? PMF_ONGROUND : 0); diff --git a/qcsrc/common/stats.qh b/qcsrc/common/stats.qh index eb6b0ea970..83afc1890b 100644 --- a/qcsrc/common/stats.qh +++ b/qcsrc/common/stats.qh @@ -119,7 +119,7 @@ const int STAT_SHIELD_TIME = 95; const int STAT_FUELREGEN_TIME = 96; const int STAT_JETPACK_TIME = 97; const int STAT_SUPERWEAPONS_TIME = 98; -// 99 empty? +const int STAT_ROUNDLOST = 99; /* The following stats change depending on the gamemode, so can share the same ID */ // IDs 100 to 104 reserved for gamemodes @@ -190,22 +190,22 @@ const int STAT_CTF_FLAGSTATUS = 124; // 137 empty? // 138 empty? // 139 empty? -// 140 empty? -// 141 empty? -// 142 empty? -// 143 empty? -// 144 empty? -// 145 empty? -// 146 empty? -// 147 empty? -// 148 empty? -// 149 empty? -// 150 empty? -// 151 empty? -// 152 empty? -// 153 empty? -// 154 empty? -// 155 empty? +// 140 reserved +// 141 reserved +// 142 reserved +// 143 reserved +// 144 reserved +// 145 reserved +// 146 reserved +// 147 reserved +// 148 reserved +// 149 reserved +// 150 reserved +// 151 reserved +// 152 reserved +// 153 reserved +// 154 reserved +// 155 reserved // 156 empty? // 157 empty? // 158 empty? diff --git a/qcsrc/common/triggers/func/door.qc b/qcsrc/common/triggers/func/door.qc index 1b62163416..04f8f24166 100644 --- a/qcsrc/common/triggers/func/door.qc +++ b/qcsrc/common/triggers/func/door.qc @@ -27,7 +27,7 @@ void() door_rotating_go_up; void door_blocked() { - if((self.spawnflags & 8) + if((self.spawnflags & 8) #ifdef SVQC && (other.takedamage != DAMAGE_NO) #elif defined(CSQC) diff --git a/qcsrc/common/triggers/func/pointparticles.qh b/qcsrc/common/triggers/func/pointparticles.qh index d446e72257..f08ea48751 100644 --- a/qcsrc/common/triggers/func/pointparticles.qh +++ b/qcsrc/common/triggers/func/pointparticles.qh @@ -2,4 +2,4 @@ void Ent_PointParticles(); -#endif \ No newline at end of file +#endif diff --git a/qcsrc/common/triggers/func/train.qc b/qcsrc/common/triggers/func/train.qc index 001a75985a..0de3489381 100644 --- a/qcsrc/common/triggers/func/train.qc +++ b/qcsrc/common/triggers/func/train.qc @@ -200,7 +200,7 @@ void spawnfunc_func_train() if (!InitMovingBrushTrigger()) return; self.effects |= EF_LOWPRECISION; - + if (self.spawnflags & 2) { self.platmovetype_turn = true; diff --git a/qcsrc/common/triggers/teleporters.qc b/qcsrc/common/triggers/teleporters.qc index a58371647b..89a5fa20df 100644 --- a/qcsrc/common/triggers/teleporters.qc +++ b/qcsrc/common/triggers/teleporters.qc @@ -15,8 +15,8 @@ #include "../../server/constants.qh" #include "../../server/defs.qh" #include "../deathtypes.qh" - #include "../../server/tturrets/include/turrets_early.qh" - #include "../vehicles/sv_vehicles.qh" + #include "../turrets/sv_turrets.qh" + #include "../vehicles/all.qh" #include "../mapinfo.qh" #include "../../server/anticheat.qh" #endif diff --git a/qcsrc/common/triggers/trigger/viewloc.qh b/qcsrc/common/triggers/trigger/viewloc.qh index c7fd150d57..6708a8e47f 100644 --- a/qcsrc/common/triggers/trigger/viewloc.qh +++ b/qcsrc/common/triggers/trigger/viewloc.qh @@ -12,4 +12,4 @@ void ent_viewloc(); void ent_viewloc_trigger(); #endif -#endif \ No newline at end of file +#endif diff --git a/qcsrc/common/triggers/triggers.qh b/qcsrc/common/triggers/triggers.qh index 474f797afe..c8e593f9cb 100644 --- a/qcsrc/common/triggers/triggers.qh +++ b/qcsrc/common/triggers/triggers.qh @@ -34,6 +34,8 @@ void target_voicescript_clear(entity pl); .vector dest; +void FixSize(entity e); + #ifdef CSQC void trigger_common_read(bool withtarget); void trigger_remove_generic(); diff --git a/qcsrc/common/turrets/all.qh b/qcsrc/common/turrets/all.qh new file mode 100644 index 0000000000..04bb10f6a5 --- /dev/null +++ b/qcsrc/common/turrets/all.qh @@ -0,0 +1,12 @@ +#include "unit/ewheel.qc" +#include "unit/flac.qc" +#include "unit/fusionreactor.qc" +#include "unit/hellion.qc" +#include "unit/hk.qc" +#include "unit/machinegun.qc" +#include "unit/mlrs.qc" +#include "unit/phaser.qc" +#include "unit/plasma.qc" +#include "unit/plasma_dual.qc" +#include "unit/tesla.qc" +#include "unit/walker.qc" diff --git a/qcsrc/common/turrets/checkpoint.qc b/qcsrc/common/turrets/checkpoint.qc new file mode 100644 index 0000000000..f2fc3a8cb1 --- /dev/null +++ b/qcsrc/common/turrets/checkpoint.qc @@ -0,0 +1,82 @@ +/** + turret_checkpoint +**/ + + +//.entity checkpoint_target; + +/* +#define checkpoint_cache_who flagcarried +#define checkpoint_cache_from lastrocket +#define checkpoint_cache_to selected_player +*/ + +.entity pathgoal; + +/* +entity path_makeorcache(entity forwho,entity start, entity end) +{ + entity oldself; + entity pth; + oldself = self; + self = forwho; + + //pth = pathlib_makepath(start.origin,end.origin,PFL_GROUNDSNAP,500,1.5,PT_QUICKSTAR); + + self = oldself; + return pth; +} +*/ + +void turret_checkpoint_use() +{ +} + +#if 0 +void turret_checkpoint_think() +{ + if(self.enemy) + te_lightning1(self,self.origin, self.enemy.origin); + + self.nextthink = time + 0.25; +} +#endif +/*QUAKED turret_checkpoint (1 0 1) (-32 -32 -32) (32 32 32) +-----------KEYS------------ +target: .targetname of next waypoint in chain. +wait: Pause at this point # seconds. +-----------SPAWNFLAGS----------- +---------NOTES---------- +If a loop is of targets are formed, any unit entering this loop will patrol it indefinitly. +If the checkpoint chain in not looped, the unit will go "Roaming" when the last point is reached. +*/ +//float tc_acum; +void turret_checkpoint_init() +{ + traceline(self.origin + '0 0 16', self.origin - '0 0 1024', MOVE_WORLDONLY, self); + setorigin(self, trace_endpos + '0 0 32'); + + if(self.target != "") + { + self.enemy = find(world, targetname, self.target); + if(self.enemy == world) + dprint("A turret_checkpoint faild to find its target!\n"); + } + //self.think = turret_checkpoint_think; + //self.nextthink = time + tc_acum + 0.25; + //tc_acum += 0.25; +} + +void spawnfunc_turret_checkpoint() +{ + setorigin(self,self.origin); + self.think = turret_checkpoint_init; + self.nextthink = time + 0.2; +} + +// Compat. +void spawnfunc_walker_checkpoint() +{ + self.classname = "turret_checkpoint"; + spawnfunc_turret_checkpoint(); +} diff --git a/qcsrc/common/turrets/cl_turrets.qc b/qcsrc/common/turrets/cl_turrets.qc new file mode 100644 index 0000000000..f0b3bdf0e0 --- /dev/null +++ b/qcsrc/common/turrets/cl_turrets.qc @@ -0,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/turret_moving.tga"; + else + txt = "gfx/vehicles/turret_stationary.tga"; + + vector pz = drawgetimagesize(txt) * autocvar_cl_vehicles_crosshair_size; + drawpic(o - pz * 0.5, txt, pz , '1 1 1', 0.7, DRAWFLAG_NORMAL); + } + } + + if(dist > self.maxdistance) + return; + + string spriteimage = self.netname; + float a = self.alpha * autocvar_hud_panel_fg_alpha; + vector rgb = spritelookupcolor(spriteimage, self.teamradar_color); + + + if(self.maxdistance > waypointsprite_normdistance) + a *= pow(bound(0, (self.maxdistance - dist) / (self.maxdistance - waypointsprite_normdistance), 1), waypointsprite_distancealphaexponent); + else if(self.maxdistance > 0) + a *= pow(bound(0, (waypointsprite_fadedistance - dist) / (waypointsprite_fadedistance - waypointsprite_normdistance), 1), waypointsprite_distancealphaexponent) * (1 - waypointsprite_minalpha) + waypointsprite_minalpha; + + if(rgb == '0 0 0') + { + self.teamradar_color = '1 0 1'; + printf("WARNING: sprite of name %s has no color, using pink so you notice it\n", spriteimage); + } + + txt = self.netname; + if(autocvar_g_waypointsprite_spam && waypointsprite_count >= autocvar_g_waypointsprite_spam) + txt = _("Spam"); + else + txt = spritelookuptext(spriteimage); + + if(time - floor(time) > 0.5 && t == self.team) + { + if(self.helpme && time < self.helpme) + { + a *= SPRITE_HELPME_BLINK; + txt = sprintf(_("%s under attack!"), txt); + } + else + a *= spritelookupblinkvalue(spriteimage); + } + + if(autocvar_g_waypointsprite_uppercase) + txt = strtoupper(txt); + + if(a > 1) + { + rgb *= a; + a = 1; + } + + if(a <= 0) + return; + + rgb = fixrgbexcess(rgb); + + o = project_3d_to_2d(self.origin + '0 0 64'); + if(o_z < 0 + || o_x < (vid_conwidth * waypointsprite_edgeoffset_left) + || o_y < (vid_conheight * waypointsprite_edgeoffset_top) + || o_x > (vid_conwidth - (vid_conwidth * waypointsprite_edgeoffset_right)) + || o_y > (vid_conheight - (vid_conheight * waypointsprite_edgeoffset_bottom))) + return; // Dont draw wp's for turrets out of view + + o_z = 0; + + float edgedistance_min, crosshairdistance; + edgedistance_min = min((o_y - (vid_conheight * waypointsprite_edgeoffset_top)), + (o_x - (vid_conwidth * waypointsprite_edgeoffset_left)), + (vid_conwidth - (vid_conwidth * waypointsprite_edgeoffset_right)) - o_x, + (vid_conheight - (vid_conheight * waypointsprite_edgeoffset_bottom)) - o_y); + + float vidscale = max(vid_conwidth / vid_width, vid_conheight / vid_height); + + crosshairdistance = sqrt( pow(o_x - vid_conwidth/2, 2) + pow(o_y - vid_conheight/2, 2) ); + + t = waypointsprite_scale * vidscale; + a *= waypointsprite_alpha; + + { + a = a * (1 - (1 - waypointsprite_distancefadealpha) * (bound(0, dist/waypointsprite_distancefadedistance, 1))); + t = t * (1 - (1 - waypointsprite_distancefadescale) * (bound(0, dist/waypointsprite_distancefadedistance, 1))); + } + if (edgedistance_min < waypointsprite_edgefadedistance) { + a = a * (1 - (1 - waypointsprite_edgefadealpha) * (1 - bound(0, edgedistance_min/waypointsprite_edgefadedistance, 1))); + t = t * (1 - (1 - waypointsprite_edgefadescale) * (1 - bound(0, edgedistance_min/waypointsprite_edgefadedistance, 1))); + } + if(crosshairdistance < waypointsprite_crosshairfadedistance) { + a = a * (1 - (1 - waypointsprite_crosshairfadealpha) * (1 - bound(0, crosshairdistance/waypointsprite_crosshairfadedistance, 1))); + t = t * (1 - (1 - waypointsprite_crosshairfadescale) * (1 - bound(0, crosshairdistance/waypointsprite_crosshairfadedistance, 1))); + } + + o = drawspritearrow(o, M_PI, rgb, a, SPRITE_ARROW_SCALE * t); + o = drawspritetext(o, M_PI, (SPRITE_HEALTHBAR_WIDTH + 2 * SPRITE_HEALTHBAR_BORDER) * t, rgb, a, waypointsprite_fontsize * '1 1 0', txt); + drawhealthbar( + o, + 0, + self.health / 255, + '0 0 0', + '0 0 0', + 0.5 * SPRITE_HEALTHBAR_WIDTH * t, + 0.5 * SPRITE_HEALTHBAR_HEIGHT * t, + SPRITE_HEALTHBAR_MARGIN * t + 0.5 * waypointsprite_fontsize, + SPRITE_HEALTHBAR_BORDER * t, + 0, + rgb, + a * SPRITE_HEALTHBAR_BORDERALPHA, + rgb, + a * SPRITE_HEALTHBAR_HEALTHALPHA, + DRAWFLAG_NORMAL + ); +} + +void turret_construct() +{ + entity tur = get_turretinfo(self.turretid); + + if(self.tur_head == world) + self.tur_head = spawn(); + + self.netname = TUR_NAME(self.turretid); + + setorigin(self, self.origin); + setmodel(self, tur.model); + setmodel(self.tur_head, tur.head_model); + setsize(self, tur.mins, tur.maxs); + setsize(self.tur_head, '0 0 0', '0 0 0'); + + if(self.turretid == TUR_EWHEEL) + setattachment(self.tur_head, self, ""); + else + setattachment(self.tur_head, self, "tag_head"); + + self.tur_head.classname = "turret_head"; + self.tur_head.owner = self; + self.tur_head.move_movetype = MOVETYPE_NOCLIP; + self.move_movetype = MOVETYPE_NOCLIP; + self.tur_head.angles = self.angles; + self.health = 255; + self.solid = SOLID_BBOX; + self.tur_head.solid = SOLID_NOT; + self.movetype = MOVETYPE_NOCLIP; + self.tur_head.movetype = MOVETYPE_NOCLIP; + self.draw = turret_draw; + self.entremove = turret_remove; + self.drawmask = MASK_NORMAL; + self.tur_head.drawmask = MASK_NORMAL; + self.anim_start_time = 0; + self.draw2d = turret_draw2d; + self.maxdistance = autocvar_g_waypointsprite_turrets_maxdist; + self.teamradar_color = '1 0 0'; + self.alpha = 1; + + TUR_ACTION(self.turretid, TR_SETUP); +} + +entity turret_gibtoss(string _model, vector _from, vector _to, vector _cmod, float _explode); +void turret_gibboom(); +void turret_gib_draw() +{ + Movetype_Physics_MatchTicrate(autocvar_cl_gibs_ticrate, autocvar_cl_gibs_sloppy); + + self.drawmask = MASK_NORMAL; + + if(self.cnt) + { + if(time >= self.nextthink) + { + turret_gibboom(); + remove(self); + } + } + else + { + self.alpha = bound(0, self.nextthink - time, 1); + if(self.alpha < ALPHA_MIN_VISIBLE) + remove(self); + } +} + +void turret_gibboom() +{ + float i; + + sound (self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM); + pointparticles(particleeffectnum("rocket_explode"), self.origin, '0 0 0', 1); + + for (i = 1; i < 5; i = i + 1) + turret_gibtoss(strcat("models/turrets/head-gib", ftos(i), ".md3"), self.origin + '0 0 2', self.velocity + randomvec() * 700, '0 0 0', false); +} + +entity turret_gibtoss(string _model, vector _from, vector _to, vector _cmod, float _explode) +{ + entity gib; + + traceline(_from, _to, MOVE_NOMONSTERS, world); + if(trace_startsolid) + return world; + + gib = spawn(); + setorigin(gib, _from); + setmodel(gib, _model); + gib.colormod = _cmod; + gib.solid = SOLID_CORPSE; + gib.draw = turret_gib_draw; + gib.cnt = _explode; + setsize(gib, '-1 -1 -1', '1 1 1'); + if(_explode) + { + gib.nextthink = time + 0.2 * (autocvar_cl_gibs_lifetime * (1 + prandom() * 0.15)); + gib.effects = EF_FLAME; + } + else + gib.nextthink = time + autocvar_cl_gibs_lifetime * (1 + prandom() * 0.15); + + gib.gravity = 1; + gib.move_movetype = MOVETYPE_BOUNCE; + gib.move_origin = _from; + setorigin(gib, _from); + gib.move_velocity = _to; + gib.move_avelocity = prandomvec() * 32; + gib.move_time = time; + gib.damageforcescale = 1; + gib.classname = "turret_gib"; + + return gib; +} + +void turret_die() +{ + sound (self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM); + pointparticles(particleeffectnum("rocket_explode"), self.origin, '0 0 0', 1); + if (!autocvar_cl_nogibs) + { + // Base + if(self.turretid == TUR_EWHEEL) + turret_gibtoss((get_turretinfo(self.turretid)).model, self.origin + '0 0 18', self.velocity + '0 0 400' + '0.1 0.1 1' * (random() * 400), '-1 -1 -1', true); + else if (self.turretid == TUR_WALKER) + turret_gibtoss((get_turretinfo(self.turretid)).model, self.origin + '0 0 18', self.velocity + '0 0 300' + '0.1 0.1 1' * (random() * 200), '-1 -1 -1', true); + else if (self.turretid == TUR_TESLA) + turret_gibtoss((get_turretinfo(self.turretid)).model, self.origin + '0 0 18', '0 0 200', '-1 -1 -1', false); + else + { + if (random() > 0.5) + { + turret_gibtoss("models/turrets/base-gib2.md3", self.origin + '0 0 8', '0 0 50' + randomvec() * 150, '0 0 0', false); + turret_gibtoss("models/turrets/base-gib3.md3", self.origin + '0 0 8', '0 0 50' + randomvec() * 150, '0 0 0', false); + turret_gibtoss("models/turrets/base-gib4.md3", self.origin + '0 0 8', '0 0 50' + randomvec() * 150, '0 0 0', false); + } + else + turret_gibtoss("models/turrets/base-gib1.md3", self.origin + '0 0 8', '0 0 0', '0 0 0', true); + + entity headgib = turret_gibtoss((get_turretinfo(self.turretid)).head_model, self.origin + '0 0 32', '0 0 200' + randomvec() * 200, '-1 -1 -1', true); + if(headgib) + { + headgib.angles = headgib.move_angles = self.tur_head.angles; + headgib.avelocity = headgib.move_avelocity = self.tur_head.move_avelocity + randomvec() * 45; + headgib.avelocity_y = headgib.move_avelocity_y = headgib.move_avelocity_y * 5; + headgib.gravity = 0.5; + } + } + } + + setmodel(self, "null"); + setmodel(self.tur_head, "null"); +} + +void ent_turret() +{ + float sf; + sf = ReadByte(); + + if(sf & TNSF_SETUP) + { + self.turretid = ReadByte(); + + self.origin_x = ReadCoord(); + self.origin_y = ReadCoord(); + self.origin_z = ReadCoord(); + setorigin(self, self.origin); + + self.angles_x = ReadAngle(); + self.angles_y = ReadAngle(); + + turret_construct(); + self.colormap = 1024; + self.glowmod = '0 1 1'; + self.tur_head.colormap = self.colormap; + self.tur_head.glowmod = self.glowmod; + } + + if(sf & TNSF_ANG) + { + if(self.tur_head == world) // aparenly this can happpen before TNSF_SETUP. great. + self.tur_head = spawn(); + + self.tur_head.move_angles_x = ReadShort(); + self.tur_head.move_angles_y = ReadShort(); + //self.tur_head.angles = self.angles + self.tur_head.move_angles; + self.tur_head.angles = self.tur_head.move_angles; + } + + if(sf & TNSF_AVEL) + { + if(self.tur_head == world) // aparenly this can happpen before TNSF_SETUP. great. + self.tur_head = spawn(); + + self.tur_head.move_avelocity_x = ReadShort(); + self.tur_head.move_avelocity_y = ReadShort(); + } + + if(sf & TNSF_MOVE) + { + self.origin_x = ReadShort(); + self.origin_y = ReadShort(); + self.origin_z = ReadShort(); + setorigin(self, self.origin); + + self.velocity_x = ReadShort(); + self.velocity_y = ReadShort(); + self.velocity_z = ReadShort(); + + self.move_angles_y = ReadShort(); + + self.move_time = time; + self.move_velocity = self.velocity; + self.move_origin = self.origin; + } + + if(sf & TNSF_ANIM) + { + self.frame1time = ReadCoord(); + self.frame = ReadByte(); + } + + if(sf & TNSF_STATUS) + { + float _tmp; + _tmp = ReadByte(); + if(_tmp != self.team) + { + self.team = _tmp; + turret_changeteam(); + } + + _tmp = ReadByte(); + if(_tmp == 0 && self.health != 0) + turret_die(); + else if(self.health && self.health != _tmp) + self.helpme = servertime + 10; + + self.health = _tmp; + } + //self.enemy.health = self.health / 255; +} diff --git a/qcsrc/common/turrets/cl_turrets.qh b/qcsrc/common/turrets/cl_turrets.qh new file mode 100644 index 0000000000..0f8ff94851 --- /dev/null +++ b/qcsrc/common/turrets/cl_turrets.qh @@ -0,0 +1,6 @@ +#ifndef CL_TURRETS_H +#define CL_TURRETS_H + +void ent_turret(); + +#endif diff --git a/qcsrc/common/turrets/config.qc b/qcsrc/common/turrets/config.qc new file mode 100644 index 0000000000..547b5c6f2a --- /dev/null +++ b/qcsrc/common/turrets/config.qc @@ -0,0 +1,62 @@ +// ========================== +// Turret Config Generator +// ========================== + +void T_Config_Queue_Swap(float root, float child, entity pass) +{ + string oldroot = tur_config_queue[root]; + tur_config_queue[root] = tur_config_queue[child]; + tur_config_queue[child] = oldroot; +} + +float T_Config_Queue_Compare(float root, float child, entity pass) +{ + float i, r, c; + + for(i = 1; i <= 100; ++i) + { + r = str2chr(tur_config_queue[root], i); + c = str2chr(tur_config_queue[child], i); + if(r == c) { continue; } + else if(c > r) { return -1; } + else { return 1; } + } + + return 0; +} + +void Dump_Turret_Settings(void) +{ + float i, x, totalsettings = 0; + for(i = TUR_FIRST; i <= TUR_LAST; ++i) + { + // step 1: clear the queue + TUR_CONFIG_COUNT = 0; + for(x = 0; x <= MAX_TUR_CONFIG; ++x) + { tur_config_queue[x] = string_null; } + + // step 2: build new queue + TUR_ACTION(i, TR_CONFIG); + + // step 3: sort queue + heapsort(TUR_CONFIG_COUNT, T_Config_Queue_Swap, T_Config_Queue_Compare, world); + + // step 4: write queue + TUR_CONFIG_WRITETOFILE(sprintf("// {{{ #%d: %s\n", i, TUR_NAME(i))) + for(x = 0; x <= TUR_CONFIG_COUNT; ++x) + { TUR_CONFIG_WRITETOFILE(tur_config_queue[x]) } + TUR_CONFIG_WRITETOFILE("// }}}\n") + + // step 5: debug info + print(sprintf("#%d: %s: %d settings...\n", i, TUR_NAME(i), TUR_CONFIG_COUNT)); + totalsettings += TUR_CONFIG_COUNT; + } + + // clear queue now that we're finished + TUR_CONFIG_COUNT = 0; + for(x = 0; x <= MAX_TUR_CONFIG; ++x) + { tur_config_queue[x] = string_null; } + + // extra information + print(sprintf("Totals: %d turrets, %d settings\n", (i - 1), totalsettings)); +} diff --git a/qcsrc/common/turrets/config.qh b/qcsrc/common/turrets/config.qh new file mode 100644 index 0000000000..85cbd2006c --- /dev/null +++ b/qcsrc/common/turrets/config.qh @@ -0,0 +1,34 @@ +#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 --git a/qcsrc/common/turrets/sv_turrets.qc b/qcsrc/common/turrets/sv_turrets.qc new file mode 100644 index 0000000000..fa5318dc2d --- /dev/null +++ b/qcsrc/common/turrets/sv_turrets.qc @@ -0,0 +1,1394 @@ +#ifdef SVQC +#include "../../server/autocvars.qh" + +// Generic aiming +vector turret_aim_generic() +{ + + vector pre_pos, prep; + float distance, impact_time = 0, i, mintime; + + turret_tag_fire_update(); + + if(self.aim_flags & TFL_AIM_SIMPLE) + return real_origin(self.enemy); + + mintime = max(self.attack_finished_single - time,0) + sys_frametime; + + // Baseline + pre_pos = real_origin(self.enemy); + + // Lead? + if (self.aim_flags & TFL_AIM_LEAD) + { + if (self.aim_flags & TFL_AIM_SHOTTIMECOMPENSATE) // Need to conpensate for shot traveltime + { + prep = pre_pos; + + distance = vlen(prep - self.tur_shotorg); + impact_time = distance / self.shot_speed; + + prep = pre_pos + (self.enemy.velocity * (impact_time + mintime)); + + if(self.aim_flags & TFL_AIM_ZPREDICT) + if(!(self.enemy.flags & FL_ONGROUND)) + if(self.enemy.movetype == MOVETYPE_WALK || self.enemy.movetype == MOVETYPE_TOSS || self.enemy.movetype == MOVETYPE_BOUNCE) + { + float vz; + prep_z = pre_pos_z; + vz = self.enemy.velocity_z; + for(i = 0; i < impact_time; i += sys_frametime) + { + vz = vz - (autocvar_sv_gravity * sys_frametime); + prep_z = prep_z + vz * sys_frametime; + } + } + pre_pos = prep; + } + else + pre_pos = pre_pos + self.enemy.velocity * mintime; + } + + if(self.aim_flags & TFL_AIM_SPLASH) + { + //tracebox(pre_pos + '0 0 32',self.enemy.mins,self.enemy.maxs,pre_pos -'0 0 64',MOVE_WORLDONLY,self.enemy); + traceline(pre_pos + '0 0 32',pre_pos -'0 0 64',MOVE_WORLDONLY,self.enemy); + if(trace_fraction != 1.0) + pre_pos = trace_endpos; + } + + return pre_pos; +} + +float turret_targetscore_support(entity _turret,entity _target) +{ + float score; // Total score + float s_score = 0, d_score; + + if (_turret.enemy == _target) s_score = 1; + + d_score = min(_turret.target_range_optimal,tvt_dist) / max(_turret.target_range_optimal,tvt_dist); + + score = (d_score * _turret.target_select_rangebias) + + (s_score * _turret.target_select_samebias); + + return score; +} + +/* +* Generic bias aware score system. +*/ +float turret_targetscore_generic(entity _turret, entity _target) +{ + float d_dist; // Defendmode Distance + float score; // Total score + float d_score; // Distance score + float a_score; // Angular score + float m_score = 0; // missile score + float p_score = 0; // player score + float ikr; // ideal kill range + + if (_turret.tur_defend) + { + d_dist = vlen(real_origin(_target) - _turret.tur_defend.origin); + ikr = vlen(_turret.origin - _turret.tur_defend.origin); + d_score = 1 - d_dist / _turret.target_range; + } + else + { + // Make a normlized value base on the targets distance from our optimal killzone + ikr = _turret.target_range_optimal; + d_score = min(ikr, tvt_dist) / max(ikr, tvt_dist); + } + + a_score = 1 - tvt_thadf / _turret.aim_maxrotate; + + if ((_turret.target_select_missilebias > 0) && (_target.flags & FL_PROJECTILE)) + m_score = 1; + + if ((_turret.target_select_playerbias > 0) && IS_CLIENT(_target)) + p_score = 1; + + d_score = max(d_score, 0); + a_score = max(a_score, 0); + m_score = max(m_score, 0); + p_score = max(p_score, 0); + + score = (d_score * _turret.target_select_rangebias) + + (a_score * _turret.target_select_anglebias) + + (m_score * _turret.target_select_missilebias) + + (p_score * _turret.target_select_playerbias); + + if(_turret.target_range < vlen(_turret.tur_shotorg - real_origin(_target))) + { + //dprint("Wtf?\n"); + score *= 0.001; + } + +#ifdef TURRET_DEBUG + string sd,sa,sm,sp,ss; + string sdt,sat,smt,spt; + + sd = ftos(d_score); + d_score *= _turret.target_select_rangebias; + sdt = ftos(d_score); + + //sv = ftos(v_score); + //v_score *= _turret.target_select_samebias; + //svt = ftos(v_score); + + sa = ftos(a_score); + a_score *= _turret.target_select_anglebias; + sat = ftos(a_score); + + sm = ftos(m_score); + m_score *= _turret.target_select_missilebias; + smt = ftos(m_score); + + sp = ftos(p_score); + p_score *= _turret.target_select_playerbias; + spt = ftos(p_score); + + + ss = ftos(score); + bprint("^3Target scores^7 \[ ",_turret.netname, " \] ^3for^7 \[ ", _target.netname," \]\n"); + bprint("^5Range:\[ ",sd, " \]^2+bias:\[ ",sdt," \]\n"); + bprint("^5Angle:\[ ",sa, " \]^2+bias:\[ ",sat," \]\n"); + bprint("^5Missile:\[ ",sm," \]^2+bias:\[ ",smt," \]\n"); + bprint("^5Player:\[ ",sp, " \]^2+bias:\[ ",spt," \]\n"); + bprint("^3Total (w/bias):\[^1",ss,"\]\n"); + +#endif + + return score; +} + +// Generic damage handling +void turret_hide() +{ + self.effects |= EF_NODRAW; + self.nextthink = time + self.respawntime - 0.2; + self.think = turret_respawn; +} + +void turret_die() +{ + self.deadflag = DEAD_DEAD; + self.tur_head.deadflag = self.deadflag; + +// Unsolidify and hide real parts + self.solid = SOLID_NOT; + self.tur_head.solid = self.solid; + + self.event_damage = func_null; + self.takedamage = DAMAGE_NO; + + self.health = 0; + +// Go boom + //RadiusDamage (self,self, min(self.ammo,50),min(self.ammo,50) * 0.25,250,world,min(self.ammo,50)*5,DEATH_TURRET,world); + + if(self.damage_flags & TFL_DMG_DEATH_NORESPAWN) + { + TUR_ACTION(self.turretid, TR_DEATH); + + remove(self.tur_head); + remove(self); + } + else + { + // Setup respawn + self.SendFlags |= TNSF_STATUS; + self.nextthink = time + 0.2; + self.think = turret_hide; + + TUR_ACTION(self.turretid, TR_DEATH); + } +} + +void turret_damage (entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector vforce) +{ + // Enough already! + if(self.deadflag == DEAD_DEAD) + return; + + // Inactive turrets take no damage. (hm..) + if(!self.active) + return; + + if(SAME_TEAM(self, attacker)) + { + if(autocvar_g_friendlyfire) + damage = damage * autocvar_g_friendlyfire; + else + return; + } + + self.health -= damage; + + // thorw head slightly off aim when hit? + if (self.damage_flags & TFL_DMG_HEADSHAKE) + { + self.tur_head.angles_x = self.tur_head.angles_x + (-0.5 + random()) * damage; + self.tur_head.angles_y = self.tur_head.angles_y + (-0.5 + random()) * damage; + + self.SendFlags |= TNSF_ANG; + } + + if (self.turret_flags & TUR_FLAG_MOVE) + self.velocity = self.velocity + vforce; + + if (self.health <= 0) + { + self.event_damage = func_null; + self.tur_head.event_damage = func_null; + self.takedamage = DAMAGE_NO; + self.nextthink = time; + self.think = turret_die; + } + + self.SendFlags |= TNSF_STATUS; +} + +void() turret_think; +void turret_respawn() +{ + // Make sure all parts belong to the same team since + // this function doubles as "teamchange" function. + self.tur_head.team = self.team; + self.effects &= ~EF_NODRAW; + self.deadflag = DEAD_NO; + self.effects = EF_LOWPRECISION; + self.solid = SOLID_BBOX; + self.takedamage = DAMAGE_AIM; + self.event_damage = turret_damage; + self.avelocity = '0 0 0'; + self.tur_head.avelocity = self.avelocity; + self.tur_head.angles = self.idle_aim; + self.health = self.max_health; + self.enemy = world; + self.volly_counter = self.shot_volly; + self.ammo = self.ammo_max; + + self.nextthink = time + self.ticrate; + self.think = turret_think; + + self.SendFlags = TNSF_FULL_UPDATE; + + TUR_ACTION(self.turretid, TR_SETUP); +} + + +// Main functions +#define cvar_base "g_turrets_unit_" +.float clientframe; +void turrets_setframe(float _frame, float client_only) +{ + if((client_only ? self.clientframe : self.frame ) != _frame) + { + self.SendFlags |= TNSF_ANIM; + self.anim_start_time = time; + } + + if(client_only) + self.clientframe = _frame; + else + self.frame = _frame; + +} + +float turret_send(entity to, float sf) +{ + + WriteByte(MSG_ENTITY, ENT_CLIENT_TURRET); + WriteByte(MSG_ENTITY, sf); + if(sf & TNSF_SETUP) + { + WriteByte(MSG_ENTITY, self.turretid); + + WriteCoord(MSG_ENTITY, self.origin_x); + WriteCoord(MSG_ENTITY, self.origin_y); + WriteCoord(MSG_ENTITY, self.origin_z); + + WriteAngle(MSG_ENTITY, self.angles_x); + WriteAngle(MSG_ENTITY, self.angles_y); + } + + if(sf & TNSF_ANG) + { + WriteShort(MSG_ENTITY, rint(self.tur_head.angles_x)); + WriteShort(MSG_ENTITY, rint(self.tur_head.angles_y)); + } + + if(sf & TNSF_AVEL) + { + WriteShort(MSG_ENTITY, rint(self.tur_head.avelocity_x)); + WriteShort(MSG_ENTITY, rint(self.tur_head.avelocity_y)); + } + + if(sf & TNSF_MOVE) + { + WriteShort(MSG_ENTITY, rint(self.origin_x)); + WriteShort(MSG_ENTITY, rint(self.origin_y)); + WriteShort(MSG_ENTITY, rint(self.origin_z)); + + WriteShort(MSG_ENTITY, rint(self.velocity_x)); + WriteShort(MSG_ENTITY, rint(self.velocity_y)); + WriteShort(MSG_ENTITY, rint(self.velocity_z)); + + WriteShort(MSG_ENTITY, rint(self.angles_y)); + } + + if(sf & TNSF_ANIM) + { + WriteCoord(MSG_ENTITY, self.anim_start_time); + WriteByte(MSG_ENTITY, self.frame); + } + + if(sf & TNSF_STATUS) + { + WriteByte(MSG_ENTITY, self.team); + + if(self.health <= 0) + WriteByte(MSG_ENTITY, 0); + else + WriteByte(MSG_ENTITY, ceil((self.health / self.max_health) * 255)); + } + + return true; +} + +void load_unit_settings(entity ent, string unitname, float is_reload) +{ + string sbase; + + if (ent == world) + return; + + if(!ent.turret_scale_damage) ent.turret_scale_damage = 1; + if(!ent.turret_scale_range) ent.turret_scale_range = 1; + if(!ent.turret_scale_refire) ent.turret_scale_refire = 1; + if(!ent.turret_scale_ammo) ent.turret_scale_ammo = 1; + if(!ent.turret_scale_aim) ent.turret_scale_aim = 1; + if(!ent.turret_scale_health) ent.turret_scale_health = 1; + if(!ent.turret_scale_respawn) ent.turret_scale_respawn = 1; + + sbase = strcat(cvar_base,unitname); + if (is_reload) + { + ent.enemy = world; + ent.tur_head.avelocity = '0 0 0'; + + ent.tur_head.angles = '0 0 0'; + } + + ent.health = cvar(strcat(sbase,"_health")) * ent.turret_scale_health; + ent.respawntime = cvar(strcat(sbase,"_respawntime")) * ent.turret_scale_respawn; + + ent.shot_dmg = cvar(strcat(sbase,"_shot_dmg")) * ent.turret_scale_damage; + ent.shot_refire = cvar(strcat(sbase,"_shot_refire")) * ent.turret_scale_refire; + ent.shot_radius = cvar(strcat(sbase,"_shot_radius")) * ent.turret_scale_damage; + ent.shot_speed = cvar(strcat(sbase,"_shot_speed")); + ent.shot_spread = cvar(strcat(sbase,"_shot_spread")); + ent.shot_force = cvar(strcat(sbase,"_shot_force")) * ent.turret_scale_damage; + ent.shot_volly = cvar(strcat(sbase,"_shot_volly")); + ent.shot_volly_refire = cvar(strcat(sbase,"_shot_volly_refire")) * ent.turret_scale_refire; + + ent.target_range = cvar(strcat(sbase,"_target_range")) * ent.turret_scale_range; + ent.target_range_min = cvar(strcat(sbase,"_target_range_min")) * ent.turret_scale_range; + ent.target_range_optimal = cvar(strcat(sbase,"_target_range_optimal")) * ent.turret_scale_range; + //ent.target_range_fire = cvar(strcat(sbase,"_target_range_fire")) * ent.turret_scale_range; + + ent.target_select_rangebias = cvar(strcat(sbase,"_target_select_rangebias")); + ent.target_select_samebias = cvar(strcat(sbase,"_target_select_samebias")); + ent.target_select_anglebias = cvar(strcat(sbase,"_target_select_anglebias")); + ent.target_select_playerbias = cvar(strcat(sbase,"_target_select_playerbias")); + //ent.target_select_fov = cvar(cvar_gets(sbase,"_target_select_fov")); + + ent.ammo_max = cvar(strcat(sbase,"_ammo_max")) * ent.turret_scale_ammo; + ent.ammo_recharge = cvar(strcat(sbase,"_ammo_recharge")) * ent.turret_scale_ammo; + + ent.aim_firetolerance_dist = cvar(strcat(sbase,"_aim_firetolerance_dist")); + ent.aim_speed = cvar(strcat(sbase,"_aim_speed")) * ent.turret_scale_aim; + ent.aim_maxrotate = cvar(strcat(sbase,"_aim_maxrot")); + ent.aim_maxpitch = cvar(strcat(sbase,"_aim_maxpitch")); + + ent.track_type = cvar(strcat(sbase,"_track_type")); + ent.track_accel_pitch = cvar(strcat(sbase,"_track_accel_pitch")); + ent.track_accel_rotate = cvar(strcat(sbase,"_track_accel_rot")); + ent.track_blendrate = cvar(strcat(sbase,"_track_blendrate")); + + if(is_reload) + TUR_ACTION(self.turretid, TR_SETUP); +} + +void turret_projectile_explode() +{ + + self.takedamage = DAMAGE_NO; + self.event_damage = func_null; +#ifdef TURRET_DEBUG + float d; + d = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, self, world, self.owner.shot_force, self.totalfrags, world); + self.owner.tur_debug_dmg_t_h = self.owner.tur_debug_dmg_t_h + d; + self.owner.tur_debug_dmg_t_f = self.owner.tur_debug_dmg_t_f + self.owner.shot_dmg; +#else + RadiusDamage (self, self.realowner, self.owner.shot_dmg, 0, self.owner.shot_radius, self, world, self.owner.shot_force, self.totalfrags, world); +#endif + remove(self); +} + +void turret_projectile_touch() +{ + PROJECTILE_TOUCH; + turret_projectile_explode(); +} + +void turret_projectile_damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector vforce) +{ + self.velocity += vforce; + self.health -= damage; + //self.realowner = attacker; // Dont change realowner, it does not make much sense for turrets + if(self.health <= 0) + W_PrepareExplosionByDamage(self.owner, turret_projectile_explode); +} + +entity turret_projectile(string _snd, float _size, float _health, float _death, float _proj_type, float _cull, float _cli_anim) +{ + entity proj; + + sound (self, CH_WEAPON_A, _snd, VOL_BASE, ATTEN_NORM); + proj = spawn (); + setorigin(proj, self.tur_shotorg); + setsize(proj, '-0.5 -0.5 -0.5' * _size, '0.5 0.5 0.5' * _size); + proj.owner = self; + proj.realowner = self; + proj.bot_dodge = true; + proj.bot_dodgerating = self.shot_dmg; + proj.think = turret_projectile_explode; + proj.touch = turret_projectile_touch; + proj.nextthink = time + 9; + proj.movetype = MOVETYPE_FLYMISSILE; + proj.velocity = normalize(self.tur_shotdir_updated + randomvec() * self.shot_spread) * self.shot_speed; + proj.flags = FL_PROJECTILE; + proj.enemy = self.enemy; + proj.totalfrags = _death; + PROJECTILE_MAKETRIGGER(proj); + if(_health) + { + proj.health = _health; + proj.takedamage = DAMAGE_YES; + proj.event_damage = turret_projectile_damage; + } + else + proj.flags |= FL_NOTARGET; + + CSQCProjectile(proj, _cli_anim, _proj_type, _cull); + + return proj; +} + +/** +** updates enemy distances, predicted impact point/time +** and updated aim<->predict impact distance. +**/ +void turret_do_updates(entity t_turret) +{ + vector enemy_pos; + entity oldself; + + oldself = self; + self = t_turret; + + enemy_pos = real_origin(self.enemy); + + turret_tag_fire_update(); + + self.tur_shotdir_updated = v_forward; + self.tur_dist_enemy = vlen(self.tur_shotorg - enemy_pos); + self.tur_dist_aimpos = vlen(self.tur_shotorg - self.tur_aimpos); + + /*if((self.firecheck_flags & TFL_FIRECHECK_VERIFIED) && (self.enemy)) + { + oldpos = self.enemy.origin; + setorigin(self.enemy, self.tur_aimpos); + tracebox(self.tur_shotorg, '-1 -1 -1', '1 1 1', self.tur_shotorg + (self.tur_shotdir_updated * self.tur_dist_aimpos), MOVE_NORMAL,self); + setorigin(self.enemy, oldpos); + + if(trace_ent == self.enemy) + self.tur_dist_impact_to_aimpos = 0; + else + self.tur_dist_impact_to_aimpos = vlen(trace_endpos - self.tur_aimpos); + } + else*/ + tracebox(self.tur_shotorg, '-1 -1 -1','1 1 1', self.tur_shotorg + (self.tur_shotdir_updated * self.tur_dist_aimpos), MOVE_NORMAL,self); + + self.tur_dist_impact_to_aimpos = vlen(trace_endpos - self.tur_aimpos) - (vlen(self.enemy.maxs - self.enemy.mins) * 0.5); + self.tur_impactent = trace_ent; + self.tur_impacttime = vlen(self.tur_shotorg - trace_endpos) / self.shot_speed; + + self = oldself; +} + +/** +** Handles head rotation according to +** the units .track_type and .track_flags +**/ +.float turret_framecounter; +void turret_track() +{ + vector target_angle; // This is where we want to aim + vector move_angle; // This is where we can aim + float f_tmp; + vector v1, v2; + v1 = self.tur_head.angles; + v2 = self.tur_head.avelocity; + + if (self.track_flags == TFL_TRACK_NO) + return; + + if(!self.active) + target_angle = self.idle_aim - ('1 0 0' * self.aim_maxpitch); + else if (self.enemy == world) + { + if(time > self.lip) + target_angle = self.idle_aim + self.angles; + else + target_angle = vectoangles(normalize(self.tur_aimpos - self.tur_shotorg)); + } + else + { + target_angle = vectoangles(normalize(self.tur_aimpos - self.tur_shotorg)); + } + + self.tur_head.angles_x = anglemods(self.tur_head.angles_x); + self.tur_head.angles_y = anglemods(self.tur_head.angles_y); + + // Find the diffrence between where we currently aim and where we want to aim + //move_angle = target_angle - (self.angles + self.tur_head.angles); + //move_angle = shortangle_vxy(move_angle,(self.angles + self.tur_head.angles)); + + move_angle = AnglesTransform_ToAngles(AnglesTransform_LeftDivide(AnglesTransform_FromAngles(self.angles), AnglesTransform_FromAngles(target_angle))) - self.tur_head.angles; + move_angle = shortangle_vxy(move_angle, self.tur_head.angles); + + switch(self.track_type) + { + case TFL_TRACKTYPE_STEPMOTOR: + f_tmp = self.aim_speed * self.ticrate; // dgr/sec -> dgr/tic + if (self.track_flags & TFL_TRACK_PITCH) + { + self.tur_head.angles_x += bound(-f_tmp,move_angle_x, f_tmp); + if(self.tur_head.angles_x > self.aim_maxpitch) + self.tur_head.angles_x = self.aim_maxpitch; + + if(self.tur_head.angles_x < -self.aim_maxpitch) + self.tur_head.angles_x = self.aim_maxpitch; + } + + if (self.track_flags & TFL_TRACK_ROTATE) + { + self.tur_head.angles_y += bound(-f_tmp, move_angle_y, f_tmp); + if(self.tur_head.angles_y > self.aim_maxrotate) + self.tur_head.angles_y = self.aim_maxrotate; + + if(self.tur_head.angles_y < -self.aim_maxrotate) + self.tur_head.angles_y = self.aim_maxrotate; + } + + // CSQC + self.SendFlags |= TNSF_ANG; + + return; + + case TFL_TRACKTYPE_FLUIDINERTIA: + f_tmp = self.aim_speed * self.ticrate; // dgr/sec -> dgr/tic + move_angle_x = bound(-self.aim_speed, move_angle_x * self.track_accel_pitch * f_tmp, self.aim_speed); + move_angle_y = bound(-self.aim_speed, move_angle_y * self.track_accel_rotate * f_tmp, self.aim_speed); + move_angle = (self.tur_head.avelocity * self.track_blendrate) + (move_angle * (1 - self.track_blendrate)); + break; + + case TFL_TRACKTYPE_FLUIDPRECISE: + + move_angle_y = bound(-self.aim_speed, move_angle_y, self.aim_speed); + move_angle_x = bound(-self.aim_speed, move_angle_x, self.aim_speed); + + break; + } + + // pitch + if (self.track_flags & TFL_TRACK_PITCH) + { + self.tur_head.avelocity_x = move_angle_x; + if((self.tur_head.angles_x + self.tur_head.avelocity_x * self.ticrate) > self.aim_maxpitch) + { + self.tur_head.avelocity_x = 0; + self.tur_head.angles_x = self.aim_maxpitch; + + self.SendFlags |= TNSF_ANG; + } + + if((self.tur_head.angles_x + self.tur_head.avelocity_x * self.ticrate) < -self.aim_maxpitch) + { + self.tur_head.avelocity_x = 0; + self.tur_head.angles_x = -self.aim_maxpitch; + + self.SendFlags |= TNSF_ANG; + } + } + + // rot + if (self.track_flags & TFL_TRACK_ROTATE) + { + self.tur_head.avelocity_y = move_angle_y; + + if((self.tur_head.angles_y + self.tur_head.avelocity_y * self.ticrate) > self.aim_maxrotate) + { + self.tur_head.avelocity_y = 0; + self.tur_head.angles_y = self.aim_maxrotate; + + self.SendFlags |= TNSF_ANG; + } + + if((self.tur_head.angles_y + self.tur_head.avelocity_y * self.ticrate) < -self.aim_maxrotate) + { + self.tur_head.avelocity_y = 0; + self.tur_head.angles_y = -self.aim_maxrotate; + + self.SendFlags |= TNSF_ANG; + } + } + + self.SendFlags |= TNSF_AVEL; + + // Force a angle update every 10'th frame + self.turret_framecounter += 1; + if(self.turret_framecounter >= 10) + { + self.SendFlags |= TNSF_ANG; + self.turret_framecounter = 0; + } +} + +/* + + TFL_TARGETSELECT_NO + + TFL_TARGETSELECT_LOS + + TFL_TARGETSELECT_PLAYERS + + TFL_TARGETSELECT_MISSILES + - TFL_TARGETSELECT_TRIGGERTARGET + + TFL_TARGETSELECT_ANGLELIMITS + + TFL_TARGETSELECT_RANGELIMITS + + TFL_TARGETSELECT_TEAMCHECK + - TFL_TARGETSELECT_NOBUILTIN + + TFL_TARGETSELECT_OWNTEAM +*/ + +/** +** Evaluate a entity for target valitity based on validate_flags +** NOTE: the caller must check takedamage before calling this, to inline this check. +**/ +float turret_validate_target(entity e_turret, entity e_target, float validate_flags) +{ + vector v_tmp; + + //if(!validate_flags & TFL_TARGETSELECT_NOBUILTIN) + // return -0.5; + + if(!e_target) + return -2; + + if(e_target.owner == e_turret) + return -0.5; + + if(!checkpvs(e_target.origin, e_turret)) + return -1; + + if(e_target.alpha <= 0.3) + return -1; + + if(g_onslaught) + if (substring(e_target.classname, 0, 10) == "onslaught_") // don't attack onslaught targets, that's the player's job! + return - 3; + + if (validate_flags & TFL_TARGETSELECT_NO) + return -4; + + // If only this was used more.. + if (e_target.flags & FL_NOTARGET) + return -5; + + // Cant touch this + if(IS_VEHICLE(e_target)) + { + if (e_target.vehicle_health <= 0) + return -6; + } + else if (e_target.health <= 0) + return -6; + else if(e_target.frozen > 0) + return -6; + + // player + if (IS_CLIENT(e_target)) + { + if(!(validate_flags & TFL_TARGETSELECT_PLAYERS)) + return -7; + + if (e_target.deadflag != DEAD_NO) + return -8; + } + + // enemy turrets + if(validate_flags & TFL_TARGETSELECT_NOTURRETS) + if(e_target.owner.tur_head == e_target) + if(e_target.team != e_turret.team) // Dont break support units. + return -9; + + // Missile + if (e_target.flags & FL_PROJECTILE) + if(!(validate_flags & TFL_TARGETSELECT_MISSILES)) + return -10; + + if (validate_flags & TFL_TARGETSELECT_MISSILESONLY) + if(!(e_target.flags & FL_PROJECTILE)) + return -10.5; + + // Team check + if (validate_flags & TFL_TARGETSELECT_TEAMCHECK) + { + if (validate_flags & TFL_TARGETSELECT_OWNTEAM) + { + if (e_target.team != e_turret.team) + return -11; + + if (e_turret.team != e_target.owner.team) + return -12; + } + else + { + if (e_target.team == e_turret.team) + return -13; + + if (e_turret.team == e_target.owner.team) + return -14; + } + } + + // Range limits? + tvt_dist = vlen(e_turret.origin - real_origin(e_target)); + if (validate_flags & TFL_TARGETSELECT_RANGELIMITS) + { + if (tvt_dist < e_turret.target_range_min) + return -15; + + if (tvt_dist > e_turret.target_range) + return -16; + } + + // Can we even aim this thing? + tvt_thadv = angleofs3(e_turret.tur_head.origin, e_turret.angles + e_turret.tur_head.angles, e_target); + tvt_tadv = shortangle_vxy(angleofs(e_turret, e_target), e_turret.angles); + tvt_thadf = vlen(tvt_thadv); + tvt_tadf = vlen(tvt_tadv); + + /* + if(validate_flags & TFL_TARGETSELECT_FOV) + { + if(e_turret.target_select_fov < tvt_thadf) + return -21; + } + */ + + if (validate_flags & TFL_TARGETSELECT_ANGLELIMITS) + { + if (fabs(tvt_tadv_x) > e_turret.aim_maxpitch) + return -17; + + if (fabs(tvt_tadv_y) > e_turret.aim_maxrotate) + return -18; + } + + // Line of sight? + if (validate_flags & TFL_TARGETSELECT_LOS) + { + v_tmp = real_origin(e_target) + ((e_target.mins + e_target.maxs) * 0.5); + + traceline(e_turret.origin + '0 0 16', v_tmp, 0, e_turret); + + if (e_turret.aim_firetolerance_dist < vlen(v_tmp - trace_endpos)) + return -19; + } + + if (e_target.classname == "grapplinghook") + return -20; + + /* + if (e_target.classname == "func_button") + return -21; + */ + +#ifdef TURRET_DEBUG_TARGETSELECT + dprint("Target:",e_target.netname," is a valid target for ",e_turret.netname,"\n"); +#endif + + return 1; +} + +entity turret_select_target() +{ + entity e; // target looper entity + float score; // target looper entity score + entity e_enemy; // currently best scoreing target + float m_score; // currently best scoreing target's score + + m_score = 0; + if(self.enemy && self.enemy.takedamage && turret_validate_target(self,self.enemy,self.target_validate_flags) > 0) + { + e_enemy = self.enemy; + m_score = self.turret_score_target(self,e_enemy) * self.target_select_samebias; + } + else + e_enemy = self.enemy = world; + + e = findradius(self.origin, self.target_range); + + // Nothing to aim at? + if (!e) + return world; + + while (e) + { + if(e.takedamage) + { + float f = turret_validate_target(self, e, self.target_select_flags); + //dprint("F is: ", ftos(f), "\n"); + if ( f > 0) + { + score = self.turret_score_target(self,e); + if ((score > m_score) && (score > 0)) + { + e_enemy = e; + m_score = score; + } + } + } + e = e.chain; + } + + return e_enemy; +} + + +/* + + = implemented + - = not implemented + + + TFL_FIRECHECK_NO + + TFL_FIRECHECK_WORLD + + TFL_FIRECHECK_DEAD + + TFL_FIRECHECK_DISTANCES + - TFL_FIRECHECK_LOS + + TFL_FIRECHECK_AIMDIST + + TFL_FIRECHECK_REALDIST + - TFL_FIRECHECK_ANGLEDIST + - TFL_FIRECHECK_TEAMCECK + + TFL_FIRECHECK_AFF + + TFL_FIRECHECK_AMMO_OWN + + TFL_FIRECHECK_AMMO_OTHER + + TFL_FIRECHECK_REFIRE +*/ + +/** +** Preforms pre-fire checks based on the uints firecheck_flags +**/ +float turret_firecheck() +{ + // This one just dont care =) + if (self.firecheck_flags & TFL_FIRECHECK_NO) + return 1; + + if (self.enemy == world) + return 0; + + // Ready? + if (self.firecheck_flags & TFL_FIRECHECK_REFIRE) + if (self.attack_finished_single > time) return 0; + + // Special case: volly fire turret that has to fire a full volly if a shot was fired. + if (self.shoot_flags & TFL_SHOOT_VOLLYALWAYS) + if (self.volly_counter != self.shot_volly) + if(self.ammo >= self.shot_dmg) + return 1; + + // Lack of zombies makes shooting dead things unnecessary :P + if (self.firecheck_flags & TFL_FIRECHECK_DEAD) + if (self.enemy.deadflag != DEAD_NO) + return 0; + + // Own ammo? + if (self.firecheck_flags & TFL_FIRECHECK_AMMO_OWN) + if (self.ammo < self.shot_dmg) + return 0; + + // Other's ammo? (support-supply units) + if (self.firecheck_flags & TFL_FIRECHECK_AMMO_OTHER) + if (self.enemy.ammo >= self.enemy.ammo_max) + return 0; + + // Target of opertunity? + if(turret_validate_target(self, self.tur_impactent, self.target_validate_flags) > 0) + { + self.enemy = self.tur_impactent; + return 1; + } + + if (self.firecheck_flags & TFL_FIRECHECK_DISTANCES) + { + // To close? + if (self.tur_dist_aimpos < self.target_range_min) + if(turret_validate_target(self, self.tur_impactent, self.target_validate_flags) > 0) + return 1; // Target of opertunity? + else + return 0; + } + + // Try to avoid FF? + if (self.firecheck_flags & TFL_FIRECHECK_AFF) + if (self.tur_impactent.team == self.team) + return 0; + + // aim<->predicted impact + if (self.firecheck_flags & TFL_FIRECHECK_AIMDIST) + if (self.tur_dist_impact_to_aimpos > self.aim_firetolerance_dist) + return 0; + + // Volly status + if (self.shot_volly > 1) + if (self.volly_counter == self.shot_volly) + if (self.ammo < (self.shot_dmg * self.shot_volly)) + return 0; + + /*if(self.firecheck_flags & TFL_FIRECHECK_VERIFIED) + if(self.tur_impactent != self.enemy) + return 0;*/ + + return 1; +} + +void turret_fire() +{ + if (autocvar_g_turrets_nofire != 0) + return; + + TUR_ACTION(self.turretid, TR_ATTACK); + + self.attack_finished_single = time + self.shot_refire; + self.ammo -= self.shot_dmg; + self.volly_counter = self.volly_counter - 1; + + if (self.volly_counter <= 0) + { + self.volly_counter = self.shot_volly; + + if (self.shoot_flags & TFL_SHOOT_CLEARTARGET) + self.enemy = world; + + if (self.shot_volly > 1) + self.attack_finished_single = time + self.shot_volly_refire; + } + +#ifdef TURRET_DEBUG + if (self.enemy) paint_target3(self.tur_aimpos, 64, self.tur_debug_rvec, self.tur_impacttime + 0.25); +#endif +} + +void turret_think() +{ + entity e; + + self.nextthink = time + self.ticrate; + + // ONS uses somewhat backwards linking. + if (teamplay) + { + if (g_onslaught) + if (self.target) + { + e = find(world, targetname,self.target); + if (e != world) + self.team = e.team; + } + + if (self.team != self.tur_head.team) + turret_respawn(); + } + +#ifdef TURRET_DEBUG + if (self.tur_debug_tmr1 < time) + { + if (self.enemy) paint_target (self.enemy,128,self.tur_debug_rvec,0.9); + paint_target(self,256,self.tur_debug_rvec,0.9); + self.tur_debug_tmr1 = time + 1; + } +#endif + + // Handle ammo + if (!(self.spawnflags & TSF_NO_AMMO_REGEN)) + if (self.ammo < self.ammo_max) + self.ammo = min(self.ammo + self.ammo_recharge, self.ammo_max); + + // Inactive turrets needs to run the think loop, + // So they can handle animation and wake up if need be. + if(!self.active) + { + turret_track(); + return; + } + + // This is typicaly used for zaping every target in range + // turret_fusionreactor uses this to recharge friendlys. + if (self.shoot_flags & TFL_SHOOT_HITALLVALID) + { + // Do a self.turret_fire for every valid target. + e = findradius(self.origin,self.target_range); + while (e) + { + if(e.takedamage) + { + if (turret_validate_target(self,e,self.target_validate_flags)) + { + self.enemy = e; + + turret_do_updates(self); + + if (self.turret_firecheckfunc()) + turret_fire(); + } + } + + e = e.chain; + } + self.enemy = world; + } + else if(self.shoot_flags & TFL_SHOOT_CUSTOM) + { + // This one is doing something.. oddball. assume its handles what needs to be handled. + + // Predict? + if(!(self.aim_flags & TFL_AIM_NO)) + self.tur_aimpos = turret_aim_generic(); + + // Turn & pitch? + if(!(self.track_flags & TFL_TRACK_NO)) + turret_track(); + + turret_do_updates(self); + + // Fire? + if (self.turret_firecheckfunc()) + turret_fire(); + } + else + { + // Special case for volly always. if it fired once it must compleate the volly. + if(self.shoot_flags & TFL_SHOOT_VOLLYALWAYS) + if(self.volly_counter != self.shot_volly) + { + // Predict or whatnot + if(!(self.aim_flags & TFL_AIM_NO)) + self.tur_aimpos = turret_aim_generic(); + + // Turn & pitch + if(!(self.track_flags & TFL_TRACK_NO)) + turret_track(); + + turret_do_updates(self); + + // Fire! + if (self.turret_firecheckfunc() != 0) + turret_fire(); + + TUR_ACTION(self.turretid, TR_THINK); + + return; + } + + // Check if we have a vailid enemy, and try to find one if we dont. + + // g_turrets_targetscan_maxdelay forces a target re-scan at least this often + float do_target_scan = 0; + if((self.target_select_time + autocvar_g_turrets_targetscan_maxdelay) < time) + do_target_scan = 1; + + // Old target (if any) invalid? + if(self.target_validate_time < time) + if (turret_validate_target(self, self.enemy, self.target_validate_flags) <= 0) + { + self.enemy = world; + self.target_validate_time = time + 0.5; + do_target_scan = 1; + } + + // But never more often then g_turrets_targetscan_mindelay! + if (self.target_select_time + autocvar_g_turrets_targetscan_mindelay > time) + do_target_scan = 0; + + if(do_target_scan) + { + self.enemy = turret_select_target(); + self.target_select_time = time; + } + + // No target, just go to idle, do any custom stuff and bail. + if (self.enemy == world) + { + // Turn & pitch + if(!(self.track_flags & TFL_TRACK_NO)) + turret_track(); + + TUR_ACTION(self.turretid, TR_THINK); + + // And bail. + return; + } + else + self.lip = time + autocvar_g_turrets_aimidle_delay; // Keep track of the last time we had a target. + + // Predict? + if(!(self.aim_flags & TFL_AIM_NO)) + self.tur_aimpos = turret_aim_generic(); + + // Turn & pitch? + if(!(self.track_flags & TFL_TRACK_NO)) + turret_track(); + + turret_do_updates(self); + + // Fire? + if (self.turret_firecheckfunc()) + turret_fire(); + } + + TUR_ACTION(self.turretid, TR_THINK); +} + +/* + When .used a turret switch team to activator.team. + If activator is world, the turret go inactive. +*/ +void turret_use() +{ + dprint("Turret ",self.netname, " used by ", activator.classname, "\n"); + + self.team = activator.team; + + if(self.team == 0) + self.active = ACTIVE_NOT; + else + self.active = ACTIVE_ACTIVE; + +} + +void turret_link() +{ + Net_LinkEntity(self, true, 0, turret_send); + self.think = turret_think; + self.nextthink = time; + self.tur_head.effects = EF_NODRAW; +} + +void turrets_manager_think() +{ + self.nextthink = time + 1; + + entity e; + if (autocvar_g_turrets_reloadcvars == 1) + { + e = nextent(world); + while (e) + { + if (IS_TURRET(e)) + { + load_unit_settings(e,e.cvar_basename,1); + TUR_ACTION(self.turretid, TR_THINK); + } + + e = nextent(e); + } + cvar_set("g_turrets_reloadcvars","0"); + } +} + +float turret_initialize(float tur_id) +{ + if(!autocvar_g_turrets) + return false; + + entity e; + entity tur = get_turretinfo(tur_id); + if(tur.turretid == 0) + return false; // invalid turret + + if(!self.tur_head) { TUR_ACTION(tur_id, TR_PRECACHE); } // if tur_head exists, we can assume this turret re-spawned + + e = find(world, classname, "turret_manager"); + if(!e) + { + e = spawn(); + e.classname = "turret_manager"; + e.think = turrets_manager_think; + e.nextthink = time + 2; + } + + if(!(self.spawnflags & TSF_SUSPENDED)) + builtin_droptofloor(); + + self.cvar_basename = tur.cvar_basename; + load_unit_settings(self, self.cvar_basename, 0); + + if(!self.team || !teamplay) { self.team = MAX_SHOT_DISTANCE; } + if(!self.ticrate) { self.ticrate = ((self.turret_flags & TUR_FLAG_SUPPORT) ? 0.2 : 0.1); } + if(!self.health) { self.health = 1000; } + if(!self.shot_refire) { self.shot_refire = 1; } + if(!self.tur_shotorg) { self.tur_shotorg = '50 0 50'; } + if(!self.turret_flags) { self.turret_flags = TUR_FLAG_SPLASH | TUR_FLAG_MEDPROJ | TUR_FLAG_PLAYER; } + if(!self.damage_flags) { self.damage_flags = TFL_DMG_YES | TFL_DMG_RETALIATE | TFL_DMG_AIMSHAKE; } + if(!self.aim_flags) { self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE; } + if(!self.track_type) { self.track_type = TFL_TRACKTYPE_STEPMOTOR; } + if(!self.track_flags) { self.track_flags = TFL_TRACK_PITCH | TFL_TRACK_ROTATE; } + if(!self.ammo_flags) { self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE; } + if(!self.target_select_flags) { self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_ANGLELIMITS; } + if(!self.firecheck_flags) { self.firecheck_flags = TFL_FIRECHECK_DEAD | TFL_FIRECHECK_DISTANCES | TFL_FIRECHECK_LOS + | TFL_FIRECHECK_AIMDIST | TFL_FIRECHECK_TEAMCHECK | TFL_FIRECHECK_AMMO_OWN | TFL_FIRECHECK_REFIRE; } + + if(self.track_type != TFL_TRACKTYPE_STEPMOTOR) + { + // Fluid / Ineria mode. Looks mutch nicer. + // Can reduce aim preformance alot, needs a bit diffrent aimspeed + + self.aim_speed = bound(0.1, ((!self.aim_speed) ? 180 : self.aim_speed), 1000); + + if(!self.track_accel_pitch) { self.track_accel_pitch = 0.5; } + if(!self.track_accel_rotate) { self.track_accel_rotate = 0.5; } + if(!self.track_blendrate) { self.track_blendrate = 0.35; } + } + + self.respawntime = max(-1, ((!self.respawntime) ? 60 : self.respawntime)); + self.shot_refire = bound(0.01, ((!self.shot_refire) ? 1 : self.shot_refire), 9999); + self.shot_dmg = max(1, ((!self.shot_dmg) ? self.shot_refire * 50 : self.shot_dmg)); + self.shot_radius = max(1, ((!self.shot_radius) ? self.shot_dmg * 0.5 : self.shot_radius)); + self.shot_speed = max(1, ((!self.shot_speed) ? 2500 : self.shot_speed)); + self.shot_spread = bound(0.0001, ((!self.shot_spread) ? 0.0125 : self.shot_spread), 500); + self.shot_force = bound(0.001, ((!self.shot_force) ? self.shot_dmg * 0.5 + self.shot_radius * 0.5 : self.shot_force), 5000); + self.shot_volly = bound(1, ((!self.shot_volly) ? 1 : self.shot_volly), floor(self.ammo_max / self.shot_dmg)); + self.shot_volly_refire = bound(self.shot_refire, ((!self.shot_volly_refire) ? self.shot_refire * self.shot_volly : self.shot_volly_refire), 60); + self.target_range = bound(0, ((!self.target_range) ? self.shot_speed * 0.5 : self.target_range), MAX_SHOT_DISTANCE); + self.target_range_min = bound(0, ((!self.target_range_min) ? self.shot_radius * 2 : self.target_range_min), MAX_SHOT_DISTANCE); + self.target_range_optimal = bound(0, ((!self.target_range_optimal) ? self.target_range * 0.5 : self.target_range_optimal), MAX_SHOT_DISTANCE); + self.aim_maxrotate = bound(0, ((!self.aim_maxrotate) ? 90 : self.aim_maxrotate), 360); + self.aim_maxpitch = bound(0, ((!self.aim_maxpitch) ? 20 : self.aim_maxpitch), 90); + self.aim_speed = bound(0.1, ((!self.aim_speed) ? 36 : self.aim_speed), 1000); + self.aim_firetolerance_dist = bound(0.1, ((!self.aim_firetolerance_dist) ? 5 + (self.shot_radius * 2) : self.aim_firetolerance_dist), MAX_SHOT_DISTANCE); + self.target_select_rangebias = bound(-10, ((!self.target_select_rangebias) ? 1 : self.target_select_rangebias), 10); + self.target_select_samebias = bound(-10, ((!self.target_select_samebias) ? 1 : self.target_select_samebias), 10); + self.target_select_anglebias = bound(-10, ((!self.target_select_anglebias) ? 1 : self.target_select_anglebias), 10); + self.target_select_missilebias = bound(-10, ((!self.target_select_missilebias) ? 1 : self.target_select_missilebias), 10); + self.target_select_playerbias = bound(-10, ((!self.target_select_playerbias) ? 1 : self.target_select_playerbias), 10); + self.ammo_max = max(self.shot_dmg, ((!self.ammo_max) ? self.shot_dmg * 10 : self.ammo_max)); + self.ammo_recharge = max(0, ((!self.ammo_recharge) ? self.shot_dmg * 0.5 : self.ammo_recharge)); + + self.turret_flags = TUR_FLAG_ISTURRET | (tur.spawnflags); + + if(self.turret_flags & TUR_FLAG_SPLASH) + self.aim_flags |= TFL_AIM_SPLASH; + + if(self.turret_flags & TUR_FLAG_MISSILE) + self.target_select_flags |= TFL_TARGETSELECT_MISSILES; + + if(self.turret_flags & TUR_FLAG_PLAYER) + self.target_select_flags |= TFL_TARGETSELECT_PLAYERS; + + if(self.spawnflags & TSL_NO_RESPAWN) + self.damage_flags |= TFL_DMG_DEATH_NORESPAWN; + + if (self.turret_flags & TUR_FLAG_SUPPORT) + self.turret_score_target = turret_targetscore_support; + else + self.turret_score_target = turret_targetscore_generic; + + ++turret_count; + + setmodel(self, tur.model); + setsize(self, tur.mins, tur.maxs); + + self.turretid = tur_id; + self.classname = "turret_main"; + self.active = ACTIVE_ACTIVE; + self.effects = EF_NODRAW; + self.netname = TUR_NAME(tur_id); + self.ticrate = bound(sys_frametime, self.ticrate, 60); + self.max_health = self.health; + self.target_validate_flags = self.target_select_flags; + self.ammo = self.ammo_max; + self.ammo_recharge *= self.ticrate; + self.solid = SOLID_BBOX; + self.takedamage = DAMAGE_AIM; + self.movetype = MOVETYPE_NOCLIP; + self.view_ofs = '0 0 0'; + self.turret_firecheckfunc = turret_firecheck; + self.event_damage = turret_damage; + self.use = turret_use; + self.bot_attack = true; + self.nextthink = time + 1; + self.nextthink += turret_count * sys_frametime; + + self.tur_head = spawn(); + setmodel(self.tur_head, tur.head_model); + setsize(self.tur_head, '0 0 0', '0 0 0'); + setorigin(self.tur_head, '0 0 0'); + setattachment(self.tur_head, self, "tag_head"); + + self.tur_head.netname = self.tur_head.classname = "turret_head"; + self.tur_head.team = self.team; + self.tur_head.owner = self; + self.tur_head.takedamage = DAMAGE_NO; + self.tur_head.solid = SOLID_NOT; + self.tur_head.movetype = self.movetype; + + if(!self.tur_defend) + if(self.target != "") + { + self.tur_defend = find(world, targetname, self.target); + if (self.tur_defend == world) + { + self.target = ""; + dprint("Turret has invalid defendpoint!\n"); + } + } + + if (self.tur_defend) + self.idle_aim = self.tur_head.angles + angleofs(self.tur_head, self.tur_defend); + else + self.idle_aim = '0 0 0'; + +#ifdef TURRET_DEBUG + self.tur_debug_start = self.nextthink; + while (vlen(self.tur_debug_rvec) < 2) + self.tur_debug_rvec = randomvec() * 4; + + self.tur_debug_rvec_x = fabs(self.tur_debug_rvec_x); + self.tur_debug_rvec_y = fabs(self.tur_debug_rvec_y); + self.tur_debug_rvec_z = fabs(self.tur_debug_rvec_z); +#endif + + turret_link(); + turret_respawn(); + turret_tag_fire_update(); + + TUR_ACTION(tur_id, TR_SETUP); + + if(MUTATOR_CALLHOOK(TurretSpawn, self)) + return false; + + return true; +} +#endif diff --git a/qcsrc/common/turrets/sv_turrets.qh b/qcsrc/common/turrets/sv_turrets.qh new file mode 100644 index 0000000000..8bba1c4a4a --- /dev/null +++ b/qcsrc/common/turrets/sv_turrets.qh @@ -0,0 +1,117 @@ +#ifndef SV_TURRETS_H +#define SV_TURRETS_H + +// turret fields +.float ticrate; // interal ai think rate +.vector aim_idle; // where to aim while idle +.entity tur_head; // top part of the turret +.entity tur_defend; // defend this entity +.vector tur_shotorg; // shot origin +.vector tur_aimpos; // aiming location +.float tur_impacttime; // predicted projectile impact time +.entity tur_impactent; // entity the projectile hit +.float tur_dist_enemy; // distance to enemy +.float tur_dist_aimpos; // distance to aim location +.float tur_dist_impact_to_aimpos; // distance impact<->aim +.float volly_counter; // decrement counter from .shot_volly to 0 + +.float shot_refire; // attack refire +.float shot_speed; // projectile speed +.float shot_spread; // inaccuracy +.float shot_dmg; // core damage of projectile +.float shot_radius; // projectile damage radius +.float shot_force; // projectile damage force +.float shot_volly; // smaller than 1 = shoot # times at target +.float shot_volly_refire; // refire after completed volly + +.float target_range; +.float target_range_min; +.float target_range_optimal; + +.float target_select_rangebias; +.float target_select_samebias; +.float target_select_anglebias; +.float target_select_missilebias; +.float target_select_playerbias; +.float target_select_time; // last time turret had a valid target +.float target_validate_time; // throttle re-validation of current target + +.float aim_firetolerance_dist; +.float aim_speed; +.float aim_maxpitch; +.float aim_maxrotate; + +.float ammo; // current ammo +.float ammo_recharge; // recharge rate +.float ammo_max; // maximum ammo + +.vector idle_aim; + +/// Map time control over pain inflicted +.float turret_scale_damage; +/// Map time control targetting range +.float turret_scale_range; +/// Map time control refire +.float turret_scale_refire; +/// Map time control ammo held and recharged +.float turret_scale_ammo; +/// Map time control aim speed +.float turret_scale_aim; +/// Map time control health +.float turret_scale_health; +/// Map time control respawn time +.float turret_scale_respawn; + +// tracking type +.float track_type; +const float TFL_TRACKTYPE_STEPMOTOR = 1; // hard angle increments, ugly for fast turning with best accuracy +const float TFL_TRACKTYPE_FLUIDPRECISE = 2; // smooth absolute movement, looks OK with fair accuracy +const float TFL_TRACKTYPE_FLUIDINERTIA = 3; // simulated inertia ("wobbly" mode), worst accuracy, depends on below flags +.float track_accel_pitch; +.float track_accel_rotate; +.float track_blendrate; + +void() turret_respawn; + +/// updates aim org, shot org, shot dir and enemy org for selected turret +void turret_do_updates(entity e_turret); +.vector tur_shotdir_updated; + +.float() turret_firecheckfunc; // TODO: deprecate! + +void turrets_setframe(float _frame, float client_only); + +float turret_initialize(float tur_id); + +/// Function to use for target evaluation. usualy turret_targetscore_generic +.float(entity _turret, entity _target) turret_score_target; + +.float(entity e_target,entity e_sender) turret_addtarget; + +.entity pathcurrent; + +float turret_count; + +// debugging +// Uncomment below to enable various debug output. +//#define TURRET_DEBUG +//#define TURRET_DEBUG_TARGETVALIDATE +//#define TURRET_DEBUG_TARGETSELECT +#ifdef TURRET_DEBUG +.float tur_debug_dmg_t_h; // total damage that hit something (can be more than tur_debug_dmg_t_f since it should count radius damage) +.float tur_debug_dmg_t_f; // total damage +.float tur_debug_start; // turret initialization time +.float tur_debug_tmr1; // random timer +.float tur_debug_tmr2; // random timer +.float tur_debug_tmr3; // random timer +.vector tur_debug_rvec; // random vector +#endif + +// aiming +vector tvt_thadv; // turret head angle diff vector, updated by a successful call to turret_validate_target +vector tvt_tadv; // turret angle diff vector, updated by a successful call to turret_validate_target +float tvt_thadf; // turret head angle diff float, updated by a successful call to turret_validate_target +float tvt_tadf; // turret angle diff float, updated by a successful call to turret_validate_target +float tvt_dist; // turret distance, updated by a successful call to turret_validate_target + +#endif diff --git a/qcsrc/common/turrets/targettrigger.qc b/qcsrc/common/turrets/targettrigger.qc new file mode 100644 index 0000000000..65510645b1 --- /dev/null +++ b/qcsrc/common/turrets/targettrigger.qc @@ -0,0 +1,38 @@ +void spawnfunc_turret_targettrigger(); +void turret_targettrigger_touch(); + +void turret_targettrigger_touch() +{ + entity e; + if (self.cnt > time) return; + entity oldself; + oldself = self; + + e = find(world, targetname, self.target); + while (e) + { + if (e.turret_flags & TUR_FLAG_RECIEVETARGETS) + { + self = e; + if(e.turret_addtarget) + e.turret_addtarget(other,oldself); + } + + e = find(e, targetname, oldself.target); + } + + oldself.cnt = time + 0.5; + + self = oldself; +} + +/*QUAKED turret_targettrigger (.5 .5 .5) ? +*/ +void spawnfunc_turret_targettrigger() +{ + if(!autocvar_g_turrets) { remove(self); return; } + + InitTrigger (); + + self.touch = turret_targettrigger_touch; +} diff --git a/qcsrc/common/turrets/turrets.qc b/qcsrc/common/turrets/turrets.qc new file mode 100644 index 0000000000..a47b975690 --- /dev/null +++ b/qcsrc/common/turrets/turrets.qc @@ -0,0 +1,77 @@ +#include "all.qh" + +// TURRET PLUGIN SYSTEM +entity turret_info[TUR_MAXCOUNT]; +entity dummy_turret_info; + +void turrets_common_precache() +{ + precache_sound ("weapons/rocket_impact.wav"); + precache_model ("models/turrets/base-gib1.md3"); + precache_model ("models/turrets/base-gib2.md3"); + precache_model ("models/turrets/base-gib3.md3"); + precache_model ("models/turrets/base-gib4.md3"); + precache_model ("models/turrets/head-gib1.md3"); + precache_model ("models/turrets/head-gib2.md3"); + precache_model ("models/turrets/head-gib3.md3"); + precache_model ("models/turrets/head-gib4.md3"); + precache_model ("models/turrets/base.md3"); + precache_model ("models/turrets/rocket.md3"); + + precache_model ("models/turrets/c512.md3"); + precache_model ("models/marker.md3"); + +#ifdef TURRET_DEBUG + precache_model ("models/turrets/c512.md3"); + precache_model ("models/pathlib/goodsquare.md3"); + precache_model ("models/pathlib/badsquare.md3"); + precache_model ("models/pathlib/square.md3"); + precache_model ("models/pathlib/edge.md3"); +#endif +} + +void register_turret(float id, float(float) func, float turretflags, vector min_s, vector max_s, string modelname, string headmodelname, string shortname, string mname) +{ + entity e; + turret_info[id - 1] = e = spawn(); + e.classname = "turret_info"; + e.turretid = id; + e.netname = shortname; + e.turret_name = mname; + e.turret_func = func; + e.mdl = modelname; + e.cvar_basename = shortname; + e.spawnflags = turretflags; + e.mins = min_s; + e.maxs = max_s; + e.model = strzone(strcat("models/turrets/", modelname)); + e.head_model = strzone(strcat("models/turrets/", headmodelname)); + + #ifndef MENUQC + turrets_common_precache(); + #endif +} +float t_null(float dummy) { return 0; } +void register_turrets_done() +{ + dummy_turret_info = spawn(); + dummy_turret_info.classname = "turret_info"; + dummy_turret_info.turretid = 0; // you can recognize dummies by this + dummy_turret_info.netname = ""; + dummy_turret_info.turret_name = "Turret"; + dummy_turret_info.turret_func = t_null; + dummy_turret_info.mdl = ""; + dummy_turret_info.mins = '-0 -0 -0'; + dummy_turret_info.maxs = '0 0 0'; + dummy_turret_info.model = ""; +} +entity get_turretinfo(float id) +{ + entity m; + if(id < TUR_FIRST || id > TUR_LAST) + return dummy_turret_info; + m = turret_info[id - 1]; + if(m) + return m; + return dummy_turret_info; +} diff --git a/qcsrc/common/turrets/turrets.qh b/qcsrc/common/turrets/turrets.qh new file mode 100644 index 0000000000..b3736aff9c --- /dev/null +++ b/qcsrc/common/turrets/turrets.qh @@ -0,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(int id); + +// fields: +.entity tur_head; + +// target selection flags +.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 +.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 +.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 +.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 +.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 +.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 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 +.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 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 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 int TNSF_ANIM = 128; + +const int TNSF_FULL_UPDATE = 16777215; + + +// entity properties of turretinfo: +.int turretid; // TUR_... +.string netname; // short name +.string turret_name; // human readable name +.float(float) turret_func; // m_... +.string mdl; // currently a copy of the model +.string model; // full name of model +.string head_model; // full name of tur_head model +.string cvar_basename; // TODO: deprecate! +.float spawnflags; +.vector mins, maxs; // turret hitbox size + +// other useful macros +#define TUR_ACTION(turrettype,mrequest) (get_turretinfo(turrettype)).turret_func(mrequest) +#define TUR_NAME(turrettype) (get_turretinfo(turrettype)).turret_name + +// ===================== +// Turret Registration +// ===================== + +float t_null(float dummy); +void register_turret(float id, float(float) func, float turretflags, vector min_s, vector max_s, string modelname, string headmodelname, string shortname, string mname); +void register_turrets_done(); + +const float TUR_MAXCOUNT = 24; +#define TUR_FIRST 1 +float TUR_COUNT; +float TUR_LAST; + +#define REGISTER_TURRET_2(id,func,turretflags,min_s,max_s,modelname,headmodelname,shortname,mname) \ + float id; \ + float func(float); \ + void RegisterTurrets_##id() \ + { \ + TUR_LAST = (id = TUR_FIRST + TUR_COUNT); \ + ++TUR_COUNT; \ + register_turret(id,func,turretflags,min_s,max_s,modelname,headmodelname,shortname,mname); \ + } \ + ACCUMULATE_FUNCTION(RegisterTurrets, RegisterTurrets_##id) +#ifdef MENUQC +#define REGISTER_TURRET(id,func,turretflags,min_s,max_s,modelname,headmodelname,shortname,mname) \ + REGISTER_TURRET_2(TUR_##id,t_null,turretflags,min_s,max_s,modelname,headmodelname,shortname,mname) +#else +#define REGISTER_TURRET(id,func,turretflags,min_s,max_s,modelname,headmodelname,shortname,mname) \ + REGISTER_TURRET_2(TUR_##id,func,turretflags,min_s,max_s,modelname,headmodelname,shortname,mname) +#endif + +#define TUR_DUPECHECK(dupecheck,cvar) \ + #ifndef dupecheck \ + #define dupecheck \ + float cvar; \ + #else \ + #error DUPLICATE TURRET CVAR: cvar \ + #endif + +#define TUR_ADD_CVAR(turret,name) \ + TUR_DUPECHECK(TUR_CVAR_##turret##_##name, autocvar_g_turrets_unit_##turret##_##name) + +#define TUR_CVAR(turret,name) autocvar_g_turrets_unit_##turret##_##name + +#include "all.qh" + +#undef TUR_ADD_CVAR +#undef REGISTER_TURRET +ACCUMULATE_FUNCTION(RegisterTurrets, register_turrets_done); + +#endif diff --git a/qcsrc/common/turrets/unit/ewheel.qc b/qcsrc/common/turrets/unit/ewheel.qc new file mode 100644 index 0000000000..495e60ff39 --- /dev/null +++ b/qcsrc/common/turrets/unit/ewheel.qc @@ -0,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); +} + +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; + + Send_Effect("laser_muzzleflash", self.tur_shotorg, self.tur_shotdir_updated * 1000, 1); + + self.tur_head.frame += 2; + + if (self.tur_head.frame > 3) + self.tur_head.frame = 0; + } + + return true; + } + case TR_THINK: + { + float vz; + vector wish_angle, real_angle; + + vz = self.velocity_z; + + self.angles_x = anglemods(self.angles_x); + self.angles_y = anglemods(self.angles_y); + + fixedmakevectors(self.angles); + + wish_angle = normalize(self.steerto); + wish_angle = vectoangles(wish_angle); + real_angle = wish_angle - self.angles; + real_angle = shortangle_vxy(real_angle, self.tur_head.angles); + + self.tur_head.spawnshieldtime = fabs(real_angle_y); + real_angle_y = bound(-self.tur_head.aim_speed, real_angle_y, self.tur_head.aim_speed); + self.angles_y = (self.angles_y + real_angle_y); + + if(self.enemy) + ewheel_move_enemy(); + else if(self.pathcurrent) + ewheel_move_path(); + else + ewheel_move_idle(); + + self.velocity_z = vz; + + if(vlen(self.velocity)) + self.SendFlags |= TNSF_MOVE; + + return true; + } + case TR_DEATH: + { + self.velocity = '0 0 0'; + +#ifdef EWHEEL_FANCYPATH + if (self.pathcurrent) + pathlib_deletepath(self.pathcurrent.owner); +#endif + self.pathcurrent = world; + + return true; + } + case TR_SETUP: + { + entity e; + + if(self.movetype == MOVETYPE_WALK) + { + self.velocity = '0 0 0'; + self.enemy = world; + + setorigin(self, self.pos1); + + if (self.target != "") + { + e = find(world, targetname, self.target); + if (!e) + { + dprint("Initital waypoint for ewheel does NOT exsist, fix your map!\n"); + self.target = ""; + } + + if (e.classname != "turret_checkpoint") + dprint("Warning: not a turrret path\n"); + else + { + +#ifdef EWHEEL_FANCYPATH + self.pathcurrent = WALKER_PATH(self.origin,e.origin); + self.pathgoal = e; +#else + self.pathcurrent = e; +#endif + } + } + } + + self.iscreature = true; + self.teleportable = TELEPORT_NORMAL; + self.damagedbycontents = true; + self.movetype = MOVETYPE_WALK; + self.solid = SOLID_SLIDEBOX; + self.takedamage = DAMAGE_AIM; + self.idle_aim = '0 0 0'; + self.pos1 = self.origin; + self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS; + self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS; + self.frame = self.tur_head.frame = 1; + self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE; + + // Convert from dgr / sec to dgr / tic + self.tur_head.aim_speed = (autocvar_g_turrets_unit_ewheel_turnrate); + self.tur_head.aim_speed = self.tur_head.aim_speed / (1 / self.ticrate); + + return true; + } + case TR_PRECACHE: + { + precache_model ("models/turrets/ewheel-base2.md3"); + precache_model ("models/turrets/ewheel-gun1.md3"); + return true; + } + } + + return true; +} + +#endif // SVQC +#ifdef CSQC + +void ewheel_draw() +{ + 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; + } + case TR_PRECACHE: + { + return true; + } + } + + return true; +} + +#endif // CSQC +#endif // REGISTER_TURRET diff --git a/qcsrc/common/turrets/unit/flac.qc b/qcsrc/common/turrets/unit/flac.qc new file mode 100644 index 0000000000..614df1d2f0 --- /dev/null +++ b/qcsrc/common/turrets/unit/flac.qc @@ -0,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); + Send_Effect("laser_muzzleflash", self.tur_shotorg, self.tur_shotdir_updated * 1000, 1); + proj.think = turret_flac_projectile_think_explode; + proj.nextthink = time + self.tur_impacttime + (random() * 0.01 - random() * 0.01); + proj.missile_flags = MIF_SPLASH | MIF_PROXY; + + self.tur_head.frame = self.tur_head.frame + 1; + if (self.tur_head.frame >= 4) + self.tur_head.frame = 0; + + return true; + } + case TR_THINK: + { + return true; + } + case TR_DEATH: + { + return true; + } + case TR_SETUP: + { + self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE; + self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE; + self.damage_flags |= TFL_DMG_HEADSHAKE; + self.target_select_flags |= TFL_TARGETSELECT_NOTURRETS | TFL_TARGETSELECT_MISSILESONLY; + + return true; + } + case TR_PRECACHE: + { + precache_model ("models/turrets/base.md3"); + precache_model ("models/turrets/flac.md3"); + return true; + } + } + + return true; +} + +#endif // SVQC +#ifdef CSQC +float t_flac(float req) +{ + switch(req) + { + case TR_SETUP: + { + return true; + } + case TR_PRECACHE: + { + return true; + } + } + + return true; +} + +#endif // CSQC +#endif // REGISTER_TURRET diff --git a/qcsrc/common/turrets/unit/fusionreactor.qc b/qcsrc/common/turrets/unit/fusionreactor.qc new file mode 100644 index 0000000000..459c1263a7 --- /dev/null +++ b/qcsrc/common/turrets/unit/fusionreactor.qc @@ -0,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; + } + case TR_THINK: + { + self.tur_head.avelocity = '0 250 0' * (self.ammo / self.ammo_max); + + return true; + } + case TR_DEATH: + { + return true; + } + case TR_SETUP: + { + self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE; + self.target_select_flags = TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_OWNTEAM | TFL_TARGETSELECT_RANGELIMITS; + self.firecheck_flags = TFL_FIRECHECK_AMMO_OWN | TFL_FIRECHECK_AMMO_OTHER | TFL_FIRECHECK_DISTANCES | TFL_FIRECHECK_DEAD; + self.shoot_flags = TFL_SHOOT_HITALLVALID; + self.aim_flags = TFL_AIM_NO; + self.track_flags = TFL_TRACK_NO; + + self.tur_head.scale = 0.75; + self.tur_head.avelocity = '0 50 0'; + + self.turret_firecheckfunc = turret_fusionreactor_firecheck; + + return true; + } + case TR_PRECACHE: + { + precache_model ("models/turrets/base.md3"); + precache_model ("models/turrets/reactor.md3"); + return true; + } + } + + return true; +} + +#endif // SVQC +#ifdef CSQC +float t_fusionreactor(float req) +{ + switch(req) + { + case TR_SETUP: + { + return true; + } + case TR_PRECACHE: + { + return true; + } + } + + return true; +} + +#endif // CSQC +#endif // REGISTER_TURRET diff --git a/qcsrc/common/turrets/unit/hellion.qc b/qcsrc/common/turrets/unit/hellion.qc new file mode 100644 index 0000000000..f64534f862 --- /dev/null +++ b/qcsrc/common/turrets/unit/hellion.qc @@ -0,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; + } + case TR_THINK: + { + if (self.tur_head.frame != 0) + self.tur_head.frame += 1; + + if (self.tur_head.frame >= 7) + self.tur_head.frame = 0; + + return true; + } + case TR_DEATH: + { + return true; + } + case TR_SETUP: + { + self.aim_flags = TFL_AIM_SIMPLE; + self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK ; + self.firecheck_flags = TFL_FIRECHECK_DEAD | TFL_FIRECHECK_DISTANCES | TFL_FIRECHECK_TEAMCHECK | TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AFF | TFL_FIRECHECK_AMMO_OWN; + self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE; + + return true; + } + case TR_PRECACHE: + { + precache_model ("models/turrets/base.md3"); + precache_model ("models/turrets/hellion.md3"); + return true; + } + } + + return true; +} + +#endif // SVQC +#ifdef CSQC +float t_hellion(float req) +{ + switch(req) + { + case TR_SETUP: + { + return true; + } + case TR_PRECACHE: + { + return true; + } + } + + return true; +} + +#endif // CSQC +#endif // REGISTER_TURRET diff --git a/qcsrc/common/turrets/unit/hk.qc b/qcsrc/common/turrets/unit/hk.qc new file mode 100644 index 0000000000..64d9a8c6a7 --- /dev/null +++ b/qcsrc/common/turrets/unit/hk.qc @@ -0,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); + ve = normalize(pre_pos - self.origin); + fe = trace_fraction; + + } + else + { + edist = 0; + ve = '0 0 0'; + fe = 0; + } + + if ((fe != 1) || (self.enemy == world) || (edist > 1000)) + { + myspeed = vlen(self.velocity); + + lt_for = myspeed * 3; + lt_seek = myspeed * 2.95; + + // Trace forward + traceline(self.origin, self.origin + v_forward * lt_for,false,self); + vf = trace_endpos; + ff = trace_fraction; + + // Find angular offset + ad = vlen(vectoangles(normalize(self.enemy.origin - self.origin)) - self.angles); + + // To close to something, Slow down! + if ( ((ff < 0.7) || (ad > 4)) && (myspeed > (autocvar_g_turrets_unit_hk_shot_speed)) ) + myspeed = max(myspeed * (autocvar_g_turrets_unit_hk_shot_speed_decel), (autocvar_g_turrets_unit_hk_shot_speed)); + + // Failry clear, accelerate. + if ( (ff > 0.7) && (myspeed < (autocvar_g_turrets_unit_hk_shot_speed_max)) ) + myspeed = min(myspeed * (autocvar_g_turrets_unit_hk_shot_speed_accel), (autocvar_g_turrets_unit_hk_shot_speed_max)); + + // Setup trace pitch + pt_seek = 1 - ff; + pt_seek = bound(0.15,pt_seek,0.8); + if (ff < 0.5) pt_seek = 1; + + // Trace left + traceline(self.origin, self.origin + (-1 * (v_right * pt_seek) + (v_forward * ff)) * lt_seek,false,self); + vl = trace_endpos; + fl = trace_fraction; + + // Trace right + traceline(self.origin, self.origin + ((v_right * pt_seek) + (v_forward * ff)) * lt_seek ,false,self); + vr = trace_endpos; + fr = trace_fraction; + + // Trace up + traceline(self.origin, self.origin + ((v_up * pt_seek) + (v_forward * ff)) * lt_seek ,false,self); + vu = trace_endpos; + fu = trace_fraction; + + // Trace down + traceline(self.origin, self.origin + (-1 * (v_up * pt_seek) + (v_forward * ff)) * lt_seek ,false,self); + vd = trace_endpos; + fd = trace_fraction; + + vl = normalize(vl - self.origin); + vr = normalize(vr - self.origin); + vu = normalize(vu - self.origin); + vd = normalize(vd - self.origin); + + // Panic tresh passed, find a single direction and turn as hard as we can + if (pt_seek == 1) + { + wishdir = v_right; + if (fl > fr) wishdir = -1 * v_right; + if (fu > fl) wishdir = v_up; + if (fd > fu) wishdir = -1 * v_up; + } + else + { + // Normalize our trace vectors to make a smooth path + wishdir = normalize( (vl * fl) + (vr * fr) + (vu * fu) + (vd * fd) ); + } + + if (self.enemy) + { + if (fe < 0.1) fe = 0.1; // Make sure we always try to move sligtly towards our target + wishdir = (wishdir * (1 - fe)) + (ve * fe); + } + } + else + { + // Got a clear path to target, speed up fast (if not at full speed) and go straight for it. + myspeed = vlen(self.velocity); + if (myspeed < (autocvar_g_turrets_unit_hk_shot_speed_max)) + myspeed = min(myspeed * (autocvar_g_turrets_unit_hk_shot_speed_accel2),(autocvar_g_turrets_unit_hk_shot_speed_max)); + + wishdir = ve; + } + + if ((myspeed > (autocvar_g_turrets_unit_hk_shot_speed)) && (self.cnt > time)) + myspeed = min(myspeed * (autocvar_g_turrets_unit_hk_shot_speed_accel2),(autocvar_g_turrets_unit_hk_shot_speed_max)); + + // Ranoutagazfish? + if (self.cnt < time) + { + self.cnt = time + 0.25; + self.nextthink = 0; + self.movetype = MOVETYPE_BOUNCE; + return; + } + + // Calculate new heading + olddir = normalize(self.velocity); + newdir = normalize(olddir + wishdir * (autocvar_g_turrets_unit_hk_shot_speed_turnrate)); + + // Set heading & speed + self.velocity = newdir * myspeed; + + // Align model with new heading + self.angles = vectoangles(self.velocity); + + +#ifdef TURRET_DEBUG_HK + //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; + } + case TR_THINK: + { + if (self.tur_head.frame != 0) + self.tur_head.frame = self.tur_head.frame + 1; + + if (self.tur_head.frame > 5) + self.tur_head.frame = 0; + + return true; + } + case TR_DEATH: + { + return true; + } + case TR_SETUP: + { + self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE; + self.aim_flags = TFL_AIM_SIMPLE; + self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_TRIGGERTARGET | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK; + self.firecheck_flags = TFL_FIRECHECK_DEAD | TFL_FIRECHECK_TEAMCHECK | TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AFF; + self.shoot_flags = TFL_SHOOT_CLEARTARGET; + self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_TEAMCHECK; + + self.turret_addtarget = turret_hk_addtarget; + + return true; + } + case TR_PRECACHE: + { + precache_model ("models/turrets/base.md3"); + precache_model ("models/turrets/hk.md3"); + return true; + } + } + + return true; +} + +#endif // SVQC +#ifdef CSQC +float t_hk(float req) +{ + switch(req) + { + case TR_SETUP: + { + return true; + } + case TR_PRECACHE: + { + return true; + } + } + + return true; +} + +#endif // CSQC +#endif // REGISTER_TURRET diff --git a/qcsrc/common/turrets/unit/machinegun.qc b/qcsrc/common/turrets/unit/machinegun.qc new file mode 100644 index 0000000000..f952d4b158 --- /dev/null +++ b/qcsrc/common/turrets/unit/machinegun.qc @@ -0,0 +1,81 @@ +#ifdef REGISTER_TURRET +REGISTER_TURRET( +/* TUR_##id */ MACHINEGUN, +/* function */ t_machinegun, +/* spawnflags */ TUR_FLAG_PLAYER, +/* mins,maxs */ '-32 -32 0', '32 32 64', +/* model */ "base.md3", +/* head_model */ "machinegun.md3", +/* netname */ "machinegun", +/* fullname */ _("Machinegun Turret") +); +#else +#ifdef SVQC +void spawnfunc_turret_machinegun() { if(!turret_initialize(TUR_MACHINEGUN)) remove(self); } + +void W_MachineGun_MuzzleFlash(void); + +float t_machinegun(float req) +{ + 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; + } + case TR_THINK: + { + return true; + } + case TR_DEATH: + { + return true; + } + case TR_SETUP: + { + self.damage_flags |= TFL_DMG_HEADSHAKE; + self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK; + self.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE; + self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE; + self.turret_flags |= TUR_FLAG_HITSCAN; + + return true; + } + 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; +} + +#endif // SVQC +#ifdef CSQC +float t_machinegun(float req) +{ + switch(req) + { + case TR_SETUP: + { + return true; + } + case TR_PRECACHE: + { + return true; + } + } + + return true; +} + +#endif // CSQC +#endif // REGISTER_TURRET diff --git a/qcsrc/common/turrets/unit/mlrs.qc b/qcsrc/common/turrets/unit/mlrs.qc new file mode 100644 index 0000000000..0142202157 --- /dev/null +++ b/qcsrc/common/turrets/unit/mlrs.qc @@ -0,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; + } + case TR_THINK: + { + // 0 = full, 6 = empty + self.tur_head.frame = bound(0, 6 - floor(0.1 + self.ammo / self.shot_dmg), 6); + if(self.tur_head.frame < 0) + { + dprint("ammo:",ftos(self.ammo),"\n"); + dprint("shot_dmg:",ftos(self.shot_dmg),"\n"); + } + + return true; + } + case TR_DEATH: + { + return true; + } + case TR_SETUP: + { + self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE; + self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE; + + self.damage_flags |= TFL_DMG_HEADSHAKE; + self.shoot_flags |= TFL_SHOOT_VOLLYALWAYS; + self.volly_counter = self.shot_volly; + + return true; + } + case TR_PRECACHE: + { + precache_model ("models/turrets/base.md3"); + precache_model ("models/turrets/mlrs.md3"); + return true; + } + } + + return true; +} + +#endif // SVQC +#ifdef CSQC +float t_mlrs(float req) +{ + switch(req) + { + case TR_SETUP: + { + return true; + } + case TR_PRECACHE: + { + return true; + } + } + + return true; +} + +#endif // CSQC +#endif // REGISTER_TURRET diff --git a/qcsrc/common/turrets/unit/phaser.qc b/qcsrc/common/turrets/unit/phaser.qc new file mode 100644 index 0000000000..449c09f859 --- /dev/null +++ b/qcsrc/common/turrets/unit/phaser.qc @@ -0,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_dodgerating = beam.shot_dmg; + sound (beam, CH_SHOTS_SINGLE, "turrets/phaser.wav", VOL_BASE, ATTEN_NORM); + self.fireflag = 1; + + beam.attack_finished_single = self.attack_finished_single; + self.attack_finished_single = time; // + autocvar_sys_ticrate; + + setattachment(beam,self.tur_head,"tag_fire"); + + soundat (self, trace_endpos, CH_SHOTS, "weapons/neximpact.wav", VOL_BASE, ATTEN_NORM); + + if (self.tur_head.frame == 0) + self.tur_head.frame = 1; + + return true; + } + case TR_THINK: + { + if (self.tur_head.frame != 0) + { + if (self.fireflag == 1) + { + if (self.tur_head.frame == 10) + self.tur_head.frame = 1; + else + self.tur_head.frame = self.tur_head.frame +1; + } + else if (self.fireflag == 2 ) + { + self.tur_head.frame = self.tur_head.frame +1; + if (self.tur_head.frame == 15) + { + self.tur_head.frame = 0; + self.fireflag = 0; + } + } + } + + return true; + } + case TR_DEATH: + { + return true; + } + case TR_SETUP: + { + self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE; + self.aim_flags = TFL_AIM_LEAD; + + self.turret_firecheckfunc = turret_phaser_firecheck; + + return true; + } + case TR_PRECACHE: + { + precache_model ("models/turrets/base.md3"); + precache_model ("models/turrets/phaser.md3"); + precache_model ("models/turrets/phaser_beam.md3"); + precache_sound ("turrets/phaser.wav"); + return true; + } + } + + return true; +} + +#endif // SVQC +#ifdef CSQC +float t_phaser(float req) +{ + switch(req) + { + case TR_SETUP: + { + return true; + } + case TR_PRECACHE: + { + return true; + } + } + + return true; +} + +#endif // CSQC +#endif // REGISTER_TURRET diff --git a/qcsrc/common/turrets/unit/plasma.qc b/qcsrc/common/turrets/unit/plasma.qc new file mode 100644 index 0000000000..da86d3bf77 --- /dev/null +++ b/qcsrc/common/turrets/unit/plasma.qc @@ -0,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); + + Send_Effect("nex_muzzleflash", self.tur_shotorg, self.tur_shotdir_updated * 1000, 1); + + // teamcolor / hit beam effect + vector v; + string s; + v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos); + s = strcat("TE_TEI_G3", ((self.team) ? Static_Team_ColorName_Upper(self.team) : "")); + + WarpZone_TrailParticles(world, particleeffectnum(s), self.tur_shotorg, v); + + if (self.tur_head.frame == 0) + self.tur_head.frame = 1; + } + else + { + entity missile = turret_projectile("weapons/hagar_fire.wav", 1, 0, DEATH_TURRET_PLASMA, PROJECTILE_ELECTRO_BEAM, TRUE, TRUE); + missile.missile_flags = MIF_SPLASH; + + Send_Effect("laser_muzzleflash", self.tur_shotorg, self.tur_shotdir_updated * 1000, 1); + if (self.tur_head.frame == 0) + self.tur_head.frame = 1; + } + + return true; + } + case TR_THINK: + { + if (self.tur_head.frame != 0) + self.tur_head.frame = self.tur_head.frame + 1; + + if (self.tur_head.frame > 5) + self.tur_head.frame = 0; + + return true; + } + case TR_DEATH: + { + return true; + } + case TR_SETUP: + { + self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE; + self.damage_flags |= TFL_DMG_HEADSHAKE; + self.firecheck_flags |= TFL_FIRECHECK_AFF; + self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_SPLASH; + + turret_do_updates(self); + + return true; + } + case TR_PRECACHE: + { + precache_model ("models/turrets/base.md3"); + precache_model ("models/turrets/plasma.md3"); + return true; + } + } + + return true; +} + +#endif // SVQC +#ifdef CSQC +float t_plasma(float req) +{ + switch(req) + { + case TR_SETUP: + { + return true; + } + case TR_PRECACHE: + { + return true; + } + } + + return true; +} + +#endif // CSQC +#endif // REGISTER_TURRET diff --git a/qcsrc/common/turrets/unit/plasma_dual.qc b/qcsrc/common/turrets/unit/plasma_dual.qc new file mode 100644 index 0000000000..f7cf549415 --- /dev/null +++ b/qcsrc/common/turrets/unit/plasma_dual.qc @@ -0,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); + + + Send_Effect("nex_muzzleflash", self.tur_shotorg, self.tur_shotdir_updated * 1000, 1); + + // teamcolor / hit beam effect + vector v; + string s; + v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos); + s = strcat("TE_TEI_G3", ((self.team) ? Static_Team_ColorName_Upper(self.team) : "")); + + WarpZone_TrailParticles(world, particleeffectnum(s), self.tur_shotorg, v); + + self.tur_head.frame += 1; + } + else + { + entity missile = turret_projectile("weapons/hagar_fire.wav", 1, 0, DEATH_TURRET_PLASMA, PROJECTILE_ELECTRO_BEAM, TRUE, TRUE); + missile.missile_flags = MIF_SPLASH; + Send_Effect("laser_muzzleflash", self.tur_shotorg, self.tur_shotdir_updated * 1000, 1); + self.tur_head.frame += 1; + } + + return true; + } + case TR_THINK: + { + if ((self.tur_head.frame != 0) && (self.tur_head.frame != 3)) + self.tur_head.frame = self.tur_head.frame + 1; + + if (self.tur_head.frame > 6) + self.tur_head.frame = 0; + + return true; + } + case TR_DEATH: + { + return true; + } + case TR_SETUP: + { + self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE; + self.damage_flags |= TFL_DMG_HEADSHAKE; + self.firecheck_flags |= TFL_FIRECHECK_AFF; + self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_SPLASH; + + turret_do_updates(self); + + return true; + } + case TR_PRECACHE: + { + precache_model ("models/turrets/base.md3"); + precache_model ("models/turrets/plasmad.md3"); + return true; + } + } + + return true; +} + +#endif // SVQC +#ifdef CSQC +float t_plasma_dual(float req) +{ + switch(req) + { + case TR_SETUP: + { + return true; + } + case TR_PRECACHE: + { + return true; + } + } + + return true; +} + +#endif // CSQC +#endif // REGISTER_TURRET diff --git a/qcsrc/common/turrets/unit/tesla.qc b/qcsrc/common/turrets/unit/tesla.qc new file mode 100644 index 0000000000..05dbffbcbb --- /dev/null +++ b/qcsrc/common/turrets/unit/tesla.qc @@ -0,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; + + self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES | TFL_TARGETSELECT_TEAMCHECK; + + self.attack_finished_single = time + self.shot_refire; + for (i = 0; i < 10; ++i) + { + d *= 0.75; + r *= 0.85; + t = toast(t, r, d); + if (t == world) break; + + } + + e = findchainfloat(railgunhit, 1); + while (e) + { + e.railgunhit = 0; + e = e.chain; + } + + return true; + } + case TR_THINK: + { + if(!self.active) + { + self.tur_head.avelocity = '0 0 0'; + return true; + } + + if(self.ammo < self.shot_dmg) + { + self.tur_head.avelocity = '0 45 0' * (self.ammo / self.shot_dmg); + } + else + { + self.tur_head.avelocity = '0 180 0' * (self.ammo / self.shot_dmg); + + if(self.attack_finished_single > time) + return true; + + float f; + f = (self.ammo / self.ammo_max); + f = f * f; + if(f > random()) + if(random() < 0.1) + te_csqc_lightningarc(self.tur_shotorg,self.tur_shotorg + (randomvec() * 350)); + } + + return true; + } + case TR_DEATH: + { + return true; + } + case TR_SETUP: + { + self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES | + TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK; + + self.turret_firecheckfunc = turret_tesla_firecheck; + self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES | + TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK; + + self.firecheck_flags = TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AMMO_OWN; + self.shoot_flags = TFL_SHOOT_CUSTOM; + self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE; + self.aim_flags = TFL_AIM_NO; + self.track_flags = TFL_TRACK_NO; + + return true; + } + case TR_PRECACHE: + { + precache_model ("models/turrets/tesla_base.md3"); + precache_model ("models/turrets/tesla_head.md3"); + return true; + } + } + + return true; +} + +#endif // SVQC +#ifdef CSQC +float t_tesla(float req) +{ + switch(req) + { + case TR_SETUP: + { + return true; + } + case TR_PRECACHE: + { + return true; + } + } + + return true; +} + +#endif // CSQC +#endif // REGISTER_TURRET diff --git a/qcsrc/common/turrets/unit/walker.qc b/qcsrc/common/turrets/unit/walker.qc new file mode 100644 index 0000000000..4a63f9dee7 --- /dev/null +++ b/qcsrc/common/turrets/unit/walker.qc @@ -0,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); + 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_dodgerating = 50; + rocket.takedamage = DAMAGE_YES; + rocket.damageforcescale = 2; + rocket.health = 25; + rocket.tur_shotorg = randomvec() * 512; + rocket.cnt = time + 1; + rocket.enemy = self.enemy; + + if (random() < 0.01) + rocket.think = walker_rocket_loop; + else + rocket.think = walker_rocket_think; + + rocket.event_damage = walker_rocket_damage; + + rocket.nextthink = time; + rocket.movetype = MOVETYPE_FLY; + rocket.velocity = normalize((v_forward + v_up * 0.5) + (randomvec() * 0.2)) * (autocvar_g_turrets_unit_walker_rocket_speed); + rocket.angles = vectoangles(rocket.velocity); + rocket.touch = walker_rocket_explode; + rocket.flags = FL_PROJECTILE; + rocket.solid = SOLID_BBOX; + rocket.max_health = time + 9; + rocket.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_GUIDED_HEAT; + + CSQCProjectile(rocket, false, PROJECTILE_ROCKET, false); // no culling, has fly sound +} + +.vector enemy_last_loc; +.float enemy_last_time; +void walker_move_to(vector _target, float _dist) +{ + 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); + Send_Effect("laser_muzzleflash", self.tur_shotorg, self.tur_shotdir_updated * 1000, 1); + + return true; + } + case TR_THINK: + { + fixedmakevectors(self.angles); + + if (self.spawnflags & TSF_NO_PATHBREAK && self.pathcurrent) + walker_move_path(); + else if (self.enemy == world) + { + if(self.pathcurrent) + walker_move_path(); + else + { + if(self.enemy_last_time != 0) + { + if(vlen(self.origin - self.enemy_last_loc) < 128 || time - self.enemy_last_time > 10) + self.enemy_last_time = 0; + else + walker_move_to(self.enemy_last_loc, 0); + } + else + { + if(self.animflag != ANIM_NO) + { + traceline(self.origin + '0 0 64', self.origin + '0 0 64' + v_forward * 128, MOVE_NORMAL, self); + + if(trace_fraction != 1.0) + self.tur_head.idletime = -1337; + else + { + traceline(trace_endpos, trace_endpos - '0 0 256', MOVE_NORMAL, self); + if(trace_fraction == 1.0) + self.tur_head.idletime = -1337; + } + + if(self.tur_head.idletime == -1337) + { + self.moveto = self.origin + randomvec() * 256; + self.tur_head.idletime = 0; + } + + self.moveto = self.moveto * 0.9 + ((self.origin + v_forward * 500) + randomvec() * 400) * 0.1; + self.moveto_z = self.origin_z + 64; + walker_move_to(self.moveto, 0); + } + + if(self.idletime < time) + { + if(random() < 0.5 || !(self.spawnflags & TSL_ROAM)) + { + self.idletime = time + 1 + random() * 5; + self.moveto = self.origin; + self.animflag = ANIM_NO; + } + else + { + self.animflag = ANIM_WALK; + self.idletime = time + 4 + random() * 2; + self.moveto = self.origin + randomvec() * 256; + self.tur_head.moveto = self.moveto; + self.tur_head.idletime = 0; + } + } + } + } + } + else + { + if (self.tur_dist_enemy < (autocvar_g_turrets_unit_walker_melee_range) && self.animflag != ANIM_MELEE) + { + vector wish_angle; + + wish_angle = angleofs(self, self.enemy); + if (self.animflag != ANIM_SWIM) + if (fabs(wish_angle_y) < 15) + { + self.moveto = self.enemy.origin; + self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95); + self.animflag = ANIM_MELEE; + } + } + else if (self.tur_head.attack_finished_single < time) + { + if(self.tur_head.shot_volly) + { + self.animflag = ANIM_NO; + + self.tur_head.shot_volly = self.tur_head.shot_volly -1; + if(self.tur_head.shot_volly == 0) + self.tur_head.attack_finished_single = time + (autocvar_g_turrets_unit_walker_rocket_refire); + else + self.tur_head.attack_finished_single = time + 0.2; + + if(self.tur_head.shot_volly > 1) + walker_fire_rocket(gettaginfo(self, gettagindex(self, "tag_rocket01"))); + else + walker_fire_rocket(gettaginfo(self, gettagindex(self, "tag_rocket02"))); + } + else + { + if (self.tur_dist_enemy > (autocvar_g_turrets_unit_walker_rocket_range_min)) + if (self.tur_dist_enemy < (autocvar_g_turrets_unit_walker_rocket_range)) + self.tur_head.shot_volly = 4; + } + } + else + { + if (self.animflag != ANIM_MELEE) + walker_move_to(self.enemy.origin, self.tur_dist_enemy); + } + } + + { + vector real_angle; + float turny = 0, turnx = 0; + float vz; + + real_angle = vectoangles(self.steerto) - self.angles; + vz = self.velocity_z; + + switch (self.animflag) + { + case ANIM_NO: + movelib_beak_simple((autocvar_g_turrets_unit_walker_speed_stop)); + break; + + case ANIM_TURN: + turny = (autocvar_g_turrets_unit_walker_turn); + movelib_beak_simple((autocvar_g_turrets_unit_walker_speed_stop)); + break; + + case ANIM_WALK: + turny = (autocvar_g_turrets_unit_walker_turn_walk); + movelib_move_simple(v_forward, (autocvar_g_turrets_unit_walker_speed_walk), 0.6); + break; + + case ANIM_RUN: + turny = (autocvar_g_turrets_unit_walker_turn_run); + movelib_move_simple(v_forward, (autocvar_g_turrets_unit_walker_speed_run), 0.6); + break; + + case ANIM_STRAFE_L: + turny = (autocvar_g_turrets_unit_walker_turn_strafe); + movelib_move_simple(v_right * -1, (autocvar_g_turrets_unit_walker_speed_walk), 0.8); + break; + + case ANIM_STRAFE_R: + turny = (autocvar_g_turrets_unit_walker_turn_strafe); + movelib_move_simple(v_right, (autocvar_g_turrets_unit_walker_speed_walk), 0.8); + break; + + case ANIM_JUMP: + self.velocity += '0 0 1' * (autocvar_g_turrets_unit_walker_speed_jump); + break; + + case ANIM_LAND: + break; + + case ANIM_PAIN: + if(self.frame != ANIM_PAIN) + defer(0.25, walker_setnoanim); + + break; + + case ANIM_MELEE: + if(self.frame != ANIM_MELEE) + { + defer(0.41, walker_setnoanim); + defer(0.21, walker_melee_do_dmg); + } + + movelib_beak_simple((autocvar_g_turrets_unit_walker_speed_stop)); + break; + + case ANIM_SWIM: + turny = (autocvar_g_turrets_unit_walker_turn_swim); + turnx = (autocvar_g_turrets_unit_walker_turn_swim); + + self.angles_x += bound(-10, shortangle_f(real_angle_x, self.angles_x), 10); + movelib_move_simple(v_forward, (autocvar_g_turrets_unit_walker_speed_swim), 0.3); + vz = self.velocity_z + sin(time * 4) * 8; + break; + + case ANIM_ROAM: + turny = (autocvar_g_turrets_unit_walker_turn_walk); + movelib_move_simple(v_forward ,(autocvar_g_turrets_unit_walker_speed_roam), 0.5); + break; + } + + if(turny) + { + turny = bound( turny * -1, shortangle_f(real_angle_y, self.angles_y), turny ); + self.angles_y += turny; + } + + if(turnx) + { + turnx = bound( turnx * -1, shortangle_f(real_angle_x, self.angles_x), turnx ); + self.angles_x += turnx; + } + + self.velocity_z = vz; + } + + + if(self.origin != self.oldorigin) + self.SendFlags |= TNSF_MOVE; + + self.oldorigin = self.origin; + turrets_setframe(self.animflag, false); + + return true; + } + case TR_DEATH: + { +#ifdef WALKER_FANCYPATHING + if (self.pathcurrent) + pathlib_deletepath(self.pathcurrent.owner); +#endif + self.pathcurrent = world; + + return true; + } + case TR_SETUP: + { + self.ticrate = 0.05; + + entity e; + + // Respawn is called & first spawn to, to set team. need to make sure we do not move the initial spawn. + if(self.movetype == MOVETYPE_WALK) + { + if(self.pos1) + setorigin(self, self.pos1); + if(self.pos2) + self.angles = self.pos2; + } + + self.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE; + self.aim_flags = TFL_AIM_LEAD; + self.turret_flags |= TUR_FLAG_HITSCAN; + + self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS; + self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS; + self.iscreature = true; + self.teleportable = TELEPORT_NORMAL; + self.damagedbycontents = true; + self.solid = SOLID_SLIDEBOX; + self.takedamage = DAMAGE_AIM; + if(self.movetype != MOVETYPE_WALK) + { + setorigin(self, self.origin); + tracebox(self.origin + '0 0 128', self.mins, self.maxs, self.origin - '0 0 10000', MOVE_NORMAL, self); + setorigin(self, trace_endpos + '0 0 4'); + self.pos1 = self.origin; + self.pos2 = self.angles; + } + self.movetype = MOVETYPE_WALK; + self.idle_aim = '0 0 0'; + self.turret_firecheckfunc = walker_firecheck; + + if (self.target != "") + { + e = find(world, targetname, self.target); + if (!e) + { + dprint("Initital waypoint for walker does NOT exsist, fix your map!\n"); + self.target = ""; + } + + if (e.classname != "turret_checkpoint") + dprint("Warning: not a turrret path\n"); + else + { +#ifdef WALKER_FANCYPATHING + self.pathcurrent = WALKER_PATH(self.origin, e.origin); + self.pathgoal = e; +#else + self.pathcurrent = e; +#endif + } + } + + return true; + } + case TR_PRECACHE: + { + precache_model ("models/turrets/walker_body.md3"); + precache_model ("models/turrets/walker_head_minigun.md3"); + precache_model ("models/turrets/rocket.md3"); + precache_sound ("weapons/rocket_impact.wav"); + return true; + } + } + + return true; +} + +#endif // SVQC +#ifdef CSQC + +#include "../../../server/movelib.qh" + +void walker_draw() +{ + float dt; + + dt = time - self.move_time; + self.move_time = time; + if(dt <= 0) + return; + + fixedmakevectors(self.angles); + movelib_groundalign4point(300, 100, 0.25, 45); + setorigin(self, self.origin + self.velocity * dt); + self.tur_head.angles += dt * self.tur_head.move_avelocity; + self.angles_y = self.move_angles_y; + + if (self.health < 127) + if(random() < 0.15) + te_spark(self.origin + '0 0 40', randomvec() * 256 + '0 0 256', 16); +} + +float t_walker(float req) +{ + switch(req) + { + case TR_SETUP: + { + self.gravity = 1; + self.movetype = MOVETYPE_BOUNCE; + self.move_movetype = MOVETYPE_BOUNCE; + self.move_origin = self.origin; + self.move_time = time; + self.draw = walker_draw; + + return true; + } + case TR_PRECACHE: + { + return true; + } + } + + return true; +} + +#endif // CSQC +#endif // REGISTER_TURRET diff --git a/qcsrc/common/turrets/util.qc b/qcsrc/common/turrets/util.qc new file mode 100644 index 0000000000..477df7b680 --- /dev/null +++ b/qcsrc/common/turrets/util.qc @@ -0,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. +*/ +float turret_tag_fire_update() +{ + if(!self.tur_head) + { + error("Call to turret_tag_fire_update with self.tur_head missing!\n"); + self.tur_shotorg = '0 0 0'; + return false; + } + + self.tur_shotorg = gettaginfo(self.tur_head, gettagindex(self.tur_head, "tag_fire")); + v_forward = normalize(v_forward); + + return true; +} + +/* +* Railgun-like beam, but has thickness and suppots slowing of target +*/ +void FireImoBeam (vector start, vector end, vector smin, vector smax, + float bforce, float f_dmg, float f_velfactor, int deathtype) + +{ + vector hitloc, force, endpoint, dir; + entity ent; + + dir = normalize(end - start); + force = dir * bforce; + + // go a little bit into the wall because we need to hit this wall later + end = end + dir; + + // trace multiple times until we hit a wall, each obstacle will be made unsolid. + // note down which entities were hit so we can damage them later + while (1) + { + tracebox(start, smin, smax, end, false, self); + + // if it is world we can't hurt it so stop now + if (trace_ent == world || trace_fraction == 1) + break; + + if (trace_ent.solid == SOLID_BSP) + break; + + // make the entity non-solid so we can hit the next one + trace_ent.railgunhit = true; + trace_ent.railgunhitloc = end; + trace_ent.railgunhitsolidbackup = trace_ent.solid; + + // stop if this is a wall + + // make the entity non-solid + trace_ent.solid = SOLID_NOT; + } + + endpoint = trace_endpos; + + // find all the entities the railgun hit and restore their solid state + ent = findfloat(world, railgunhit, true); + while (ent) + { + // restore their solid type + ent.solid = ent.railgunhitsolidbackup; + ent = findfloat(ent, railgunhit, true); + } + + // find all the entities the railgun hit and hurt them + ent = findfloat(world, railgunhit, true); + while (ent) + { + // get the details we need to call the damage function + hitloc = ent.railgunhitloc; + ent.railgunhitloc = '0 0 0'; + ent.railgunhitsolidbackup = SOLID_NOT; + ent.railgunhit = false; + + // apply the damage + if (ent.takedamage) + { + Damage (ent, self, self, f_dmg, deathtype, hitloc, force); + ent.velocity = ent.velocity * f_velfactor; + //ent.alpha = 0.25 + random() * 0.75; + } + + // advance to the next entity + ent = findfloat(ent, railgunhit, true); + } + trace_endpos = endpoint; +} + +#ifdef TURRET_DEBUG +void SUB_Remove(); +void marker_think() +{ + if(self.cnt) + if(self.cnt < time) + { + self.think = SUB_Remove; + self.nextthink = time; + return; + } + + self.frame += 1; + if(self.frame > 29) + self.frame = 0; + + self.nextthink = time; +} + +void mark_error(vector where,float lifetime) +{ + entity err; + + err = spawn(); + err.classname = "error_marker"; + setmodel(err,"models/marker.md3"); + setorigin(err,where); + err.movetype = MOVETYPE_NONE; + err.think = marker_think; + err.nextthink = time; + err.skin = 0; + if(lifetime) + err.cnt = lifetime + time; +} + +void mark_info(vector where,float lifetime) +{ + entity err; + + err = spawn(); + err.classname = "info_marker"; + setmodel(err,"models/marker.md3"); + setorigin(err,where); + err.movetype = MOVETYPE_NONE; + err.think = marker_think; + err.nextthink = time; + err.skin = 1; + if(lifetime) + err.cnt = lifetime + time; +} + +entity mark_misc(vector where,float lifetime) +{ + entity err; + + err = spawn(); + err.classname = "mark_misc"; + setmodel(err,"models/marker.md3"); + setorigin(err,where); + err.movetype = MOVETYPE_NONE; + err.think = marker_think; + err.nextthink = time; + err.skin = 3; + if(lifetime) + err.cnt = lifetime + time; + return err; +} + +/* +* Paint a v_color colord circle on target onwho +* that fades away over f_time +*/ +void paint_target(entity onwho, float f_size, vector v_color, float f_time) +{ + entity e; + + e = spawn(); + setmodel(e, "models/turrets/c512.md3"); // precision set above + e.scale = (f_size/512); + //setsize(e, '0 0 0', '0 0 0'); + //setattachment(e,onwho,""); + setorigin(e,onwho.origin + '0 0 1'); + e.alpha = 0.15; + e.movetype = MOVETYPE_FLY; + + e.velocity = (v_color * 32); // + '0 0 1' * 64; + + e.colormod = v_color; + SUB_SetFade(e,time,f_time); +} + +void paint_target2(entity onwho, float f_size, vector v_color, float f_time) +{ + entity e; + + e = spawn(); + setmodel(e, "models/turrets/c512.md3"); // precision set above + e.scale = (f_size/512); + setsize(e, '0 0 0', '0 0 0'); + + setorigin(e,onwho.origin + '0 0 1'); + e.alpha = 0.15; + e.movetype = MOVETYPE_FLY; + + e.velocity = (v_color * 32); // + '0 0 1' * 64; + e.avelocity_x = -128; + + e.colormod = v_color; + SUB_SetFade(e,time,f_time); +} + +void paint_target3(vector where, float f_size, vector v_color, float f_time) +{ + entity e; + e = spawn(); + setmodel(e, "models/turrets/c512.md3"); // precision set above + e.scale = (f_size/512); + setsize(e, '0 0 0', '0 0 0'); + setorigin(e,where+ '0 0 1'); + e.movetype = MOVETYPE_NONE; + e.velocity = '0 0 0'; + e.colormod = v_color; + SUB_SetFade(e,time,f_time); +} +#endif diff --git a/qcsrc/common/turrets/util.qh b/qcsrc/common/turrets/util.qh new file mode 100644 index 0000000000..71ba0662e6 --- /dev/null +++ b/qcsrc/common/turrets/util.qh @@ -0,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 --git a/qcsrc/common/util-pre.qh b/qcsrc/common/util-pre.qh index b96e78d514..fc916d4dba 100644 --- a/qcsrc/common/util-pre.qh +++ b/qcsrc/common/util-pre.qh @@ -117,4 +117,8 @@ #define BITSET(var, mask, flag) ((var) ^ (-(flag) ^ (var)) & (mask)) #endif +#define CVAR_DESCRIBE(var, desc) localcmd(sprintf("\nset %s \"%s\" \"%s\"\n", #var, ftos(autocvar_##var), desc)) +#define CVAR_DESCRIBESTR(var, desc) localcmd(sprintf("\nset %s \"%s\" \"%s\"\n", #var, autocvar_##var, desc)) +#define CVAR_DESCRIBEVEC(var, desc) localcmd(sprintf("\nset %s \"%s %s %s\" \"%s\"\n", #var, ftos(autocvar_##var##.x), ftos(autocvar_##var##.y), ftos(autocvar_##var##.z), desc)) + #endif diff --git a/qcsrc/common/vehicles/all.inc b/qcsrc/common/vehicles/all.inc new file mode 100644 index 0000000000..eda4e00bbb --- /dev/null +++ b/qcsrc/common/vehicles/all.inc @@ -0,0 +1,6 @@ +#include "unit/spiderbot.qc" +#include "unit/raptor.qc" +#include "unit/racer.qc" +#ifndef VEHICLES_NO_UNSTABLE + #include "unit/bumblebee.qc" +#endif diff --git a/qcsrc/common/vehicles/all.qc b/qcsrc/common/vehicles/all.qc new file mode 100644 index 0000000000..f0316ab1fa --- /dev/null +++ b/qcsrc/common/vehicles/all.qc @@ -0,0 +1,56 @@ +#ifndef VEHICLES_ALL_C +#define VEHICLES_ALL_C + +#include "all.qh" + +#if defined(SVQC) + #include "sv_vehicles.qc" +#elif defined(CSQC) + #include "cl_vehicles.qc" +#endif + +#define IMPLEMENTATION +#include "all.inc" +#undef IMPLEMENTATION + +#ifndef MENUQC +STATIC_INIT(vehicles_common_initialize) +{ +#ifdef CSQC + precache_model("models/vehicles/bomblet.md3"); + precache_model("models/vehicles/clusterbomb.md3"); + precache_model("models/vehicles/clusterbomb_fragment.md3"); + precache_model("models/vehicles/rocket01.md3"); + precache_model("models/vehicles/rocket02.md3"); + + precache_sound ("vehicles/alarm.wav"); + precache_sound ("vehicles/alarm_shield.wav"); +#endif // CSQC +#ifdef SVQC + precache_sound("onslaught/ons_hit2.wav"); + precache_sound("onslaught/electricity_explode.wav"); + + addstat(STAT_HUD, AS_INT, hud); + addstat(STAT_VEHICLESTAT_HEALTH, AS_INT, vehicle_health); + addstat(STAT_VEHICLESTAT_SHIELD, AS_INT, vehicle_shield); + addstat(STAT_VEHICLESTAT_ENERGY, AS_INT, vehicle_energy); + + addstat(STAT_VEHICLESTAT_W2MODE, AS_INT, vehicle_weapon2mode); + + addstat(STAT_VEHICLESTAT_AMMO1, AS_INT, vehicle_ammo1); + addstat(STAT_VEHICLESTAT_RELOAD1, AS_INT, vehicle_reload1); + + addstat(STAT_VEHICLESTAT_AMMO2, AS_INT, vehicle_ammo2); + addstat(STAT_VEHICLESTAT_RELOAD2, AS_INT, vehicle_reload2); +#endif // SVQC +} +#endif + +entity get_vehicleinfo(int id) +{ + if (id < VEH_FIRST || id > VEH_LAST) return VEH_NULL; + entity m = vehicle_info[id]; + return m ? m : VEH_NULL; +} + +#endif diff --git a/qcsrc/common/vehicles/all.qh b/qcsrc/common/vehicles/all.qh index 48ff80418c..fa9e83f485 100644 --- a/qcsrc/common/vehicles/all.qh +++ b/qcsrc/common/vehicles/all.qh @@ -1,10 +1,83 @@ +#ifndef VEHICLES_ALL_H +#define VEHICLES_ALL_H + #if defined(SVQC) #include "sv_vehicles.qh" #elif defined(CSQC) #include "cl_vehicles.qh" #endif -# ifndef VEHICLES_NO_UNSTABLE -# include "unit/bumblebee.qh" -# include "unit/raptor.qh" -# endif + +// vehicle requests +const int VR_SETUP = 1; // (BOTH) setup vehicle data +const int VR_THINK = 2; // (SERVER) logic to run every frame +const int VR_DEATH = 3; // (SERVER) called when vehicle dies +const int VR_PRECACHE = 4; // (BOTH) precaches models/sounds used by this vehicle +const int VR_ENTER = 5; // (SERVER) called when a player enters this vehicle +const int VR_SPAWN = 6; // (SERVER) called when the vehicle re-spawns +const int VR_IMPACT = 7; // (SERVER) called when a vehicle hits something +const int VR_HUD = 8; // (CLIENT) logic to run every frame + +// vehicle spawn flags (need them here for common registrations) +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 + +// functions: +entity get_vehicleinfo(float id); + +// fields: +.entity tur_head; + + +// other useful macros +#define VEH_ACTION(vehicletype,mrequest) (get_vehicleinfo(vehicletype)).vehicle_func(mrequest) +#define VEH_NAME(vehicletype) (get_vehicleinfo(vehicletype)).vehicle_name + +// ===================== +// Vehicle Registration +// ===================== + +void RegisterVehicles(); +const int VEH_MAXCOUNT = 24; +entity vehicle_info[VEH_MAXCOUNT], vehicle_info_first, vehicle_info_last; +int VEH_COUNT; +const int VEH_FIRST = 1; +#define VEH_LAST (VEH_FIRST + VEH_COUNT - 1) +/** If you register a new vehicle, make sure to add it to all.inc */ +#define REGISTER_VEHICLE(id, class) REGISTER(RegisterVehicles, VEH, vehicle_info, VEH_COUNT, id, vehicleid, NEW(class)) +#include "vehicle.qh" +#define REGISTER_VEHICLE_SIMPLE(id, vehicleflags, min_s, max_s, modelname, headmodelname, hudmodelname, headtag, hudtag, viewtag, shortname, vname) \ + REGISTER_VEHICLE(id, Vehicle) { \ + this.netname = shortname; \ + this.vehicle_name = vname; \ + this.mdl = modelname; \ + this.spawnflags = vehicleflags; \ + this.mins = min_s; \ + this.maxs = max_s; \ + this.model = modelname; \ + this.head_model = headmodelname; \ + this.hud_model = hudmodelname; \ + this.tag_head = headtag; \ + this.tag_hud = hudtag; \ + this.tag_view = viewtag; \ + } \ + REGISTER_INIT(VEH, id) +REGISTER_REGISTRY(RegisterVehicles) + +REGISTER_VEHICLE(NULL, Vehicle); + +#include "all.inc" + +#endif diff --git a/qcsrc/common/vehicles/cl_vehicles.qc b/qcsrc/common/vehicles/cl_vehicles.qc index 2511defb43..141f8fc42d 100644 --- a/qcsrc/common/vehicles/cl_vehicles.qc +++ b/qcsrc/common/vehicles/cl_vehicles.qc @@ -295,7 +295,7 @@ void Vehicles_drawHUD( } // Bumblebee gunner crosshairs - if(hud == VEH_BUMBLEBEE) + if(hud == VEH_BUMBLEBEE.vehicleid) { tmpSize = '1 1 1' * hud_fontsize; tmpPos.x = hudPos.x + hudSize.x * (520/768); @@ -314,7 +314,7 @@ void Vehicles_drawHUD( } // Raptor bomb crosshair - if(hud == VEH_RAPTOR && weapon2mode != RSM_FLARE) + if(hud == VEH_RAPTOR.vehicleid && weapon2mode != RSM_FLARE) { vector where; diff --git a/qcsrc/common/vehicles/sv_vehicles.qc b/qcsrc/common/vehicles/sv_vehicles.qc index b06596bbc9..d4b1e1acf4 100644 --- a/qcsrc/common/vehicles/sv_vehicles.qc +++ b/qcsrc/common/vehicles/sv_vehicles.qc @@ -1,6 +1,5 @@ -#include "../effects.qh" -#include "vehicles.qh" #include "sv_vehicles.qh" +#include "../effects.qh" #if 0 bool vehicle_send(entity to, int sf) @@ -1124,10 +1123,10 @@ void vehicles_enter(entity pl, entity veh) void vehicles_think() { self.nextthink = time; - + if(self.owner) self.owner.vehicle_weapon2mode = self.vehicle_weapon2mode; - + VEH_ACTION(self.vehicleid, VR_THINK); CSQCMODEL_AUTOUPDATE(); @@ -1184,17 +1183,15 @@ void vehicles_spawn() CSQCMODEL_AUTOINIT(); } -bool vehicle_initialize(int vehicle_id, bool nodrop) +bool vehicle_initialize(entity veh, bool nodrop) { if(!autocvar_g_vehicles) return false; - entity veh = get_vehicleinfo(vehicle_id); - if(!veh.vehicleid) return false; - - if(!veh.tur_head) { VEH_ACTION(vehicle_id, VR_PRECACHE); } + + if(!veh.tur_head) { VEH_ACTION(veh.vehicleid, VR_PRECACHE); } if(self.targetname && self.targetname != "") { @@ -1239,7 +1236,7 @@ bool vehicle_initialize(int vehicle_id, bool nodrop) self.iscreature = true; self.teleportable = false; // no teleporting for vehicles, too buggy self.damagedbycontents = true; - self.vehicleid = vehicle_id; + self.vehicleid = veh.vehicleid; self.PlayerPhysplug = veh.PlayerPhysplug; self.event_damage = func_null; self.touch = vehicles_touch; @@ -1287,7 +1284,7 @@ bool vehicle_initialize(int vehicle_id, bool nodrop) self.pos2 = self.angles; self.tur_head.team = self.team; - VEH_ACTION(vehicle_id, VR_SETUP); + VEH_ACTION(veh.vehicleid, VR_SETUP); if(self.active == ACTIVE_NOT) self.nextthink = 0; // wait until activated diff --git a/qcsrc/common/vehicles/sv_vehicles.qh b/qcsrc/common/vehicles/sv_vehicles.qh index 0de7184fea..b3f252e3b1 100644 --- a/qcsrc/common/vehicles/sv_vehicles.qh +++ b/qcsrc/common/vehicles/sv_vehicles.qh @@ -2,8 +2,7 @@ #define VEHICLES_DEF_H #ifdef SVQC -#include "../server/tturrets/include/turrets_early.qh" -#include "sv_vehicles.qh" +#include "../turrets/sv_turrets.qh" // #define VEHICLES_USE_ODE @@ -101,10 +100,9 @@ float vehicles_exit_running; .float vehicle_enter_delay; // prevent players jumping to and from vehicles instantly void vehicles_exit(float eject); -float vehicle_initialize(float vehicle_id, float nodrop); +float vehicle_initialize(entity vehicle, float nodrop); bool vehicle_impulse(int imp); bool vehicles_crushable(entity e); #endif - #endif diff --git a/qcsrc/common/vehicles/unit/all.qh b/qcsrc/common/vehicles/unit/all.qh deleted file mode 100644 index 7dfca83a2d..0000000000 --- a/qcsrc/common/vehicles/unit/all.qh +++ /dev/null @@ -1,6 +0,0 @@ -#include "spiderbot.qc" -#include "raptor.qc" -#include "racer.qc" -#ifndef VEHICLES_NO_UNSTABLE - #include "bumblebee.qc" -#endif diff --git a/qcsrc/common/vehicles/unit/bumblebee.qc b/qcsrc/common/vehicles/unit/bumblebee.qc index cc52716c79..f6cfb65fec 100644 --- a/qcsrc/common/vehicles/unit/bumblebee.qc +++ b/qcsrc/common/vehicles/unit/bumblebee.qc @@ -1,7 +1,11 @@ -#ifdef REGISTER_VEHICLE -REGISTER_VEHICLE( +#ifndef VEHICLE_BUMBLEBEE +#define VEHICLE_BUMBLEBEE +#include "bumblebee.qh" +#ifndef MENUQC +int v_bumblebee(int); +#endif +REGISTER_VEHICLE_SIMPLE( /* VEH_##id */ BUMBLEBEE, -/* function */ v_bumblebee, /* spawnflags */ VHF_DMGSHAKE, /* mins,maxs */ '-245 -130 -130', '230 130 130', /* model */ "models/vehicles/bumblebee_body.dpm", @@ -10,8 +14,15 @@ REGISTER_VEHICLE( /* tags */ "", "", "tag_viewport", /* netname */ "bumblebee", /* fullname */ _("Bumblebee") -); -#else +) { + this.m_icon = "vehicle_bumble"; +#ifndef MENUQC + this.vehicle_func = v_bumblebee; +#endif +} +#endif + +#ifdef IMPLEMENTATION const float BRG_SETUP = 2; const float BRG_START = 4; @@ -419,7 +430,7 @@ float bumblebee_pilot_frame() { entity pilot, vehic; vector newvel; - + if(intermission_running) { self.vehicle.velocity = '0 0 0'; @@ -650,13 +661,13 @@ void bumblebee_land() self.think = vehicles_think; self.nextthink = time; - + CSQCMODEL_AUTOUPDATE(); } void bumblebee_exit(float eject) { - if(self.owner.vehicleid == VEH_BUMBLEBEE) + if(self.owner.vehicleid == VEH_BUMBLEBEE.vehicleid) { bumblebee_gunner_exit(eject); return; @@ -669,7 +680,7 @@ void bumblebee_exit(float eject) self.think = bumblebee_land; self.nextthink = time; } - + self.movetype = MOVETYPE_TOSS; if(!self.owner) @@ -771,7 +782,7 @@ float v_bumblebee(float req) { if(autocvar_g_vehicle_bumblebee_bouncepain) vehicles_impact(autocvar_g_vehicle_bumblebee_bouncepain_x, autocvar_g_vehicle_bumblebee_bouncepain_y, autocvar_g_vehicle_bumblebee_bouncepain_z); - + return true; } case VR_ENTER: @@ -785,12 +796,12 @@ float v_bumblebee(float req) { self.angles_z *= 0.8; self.angles_x *= 0.8; - + self.nextthink = time; - + if(!self.owner) { - entity oldself = self; + entity oldself = self; if(self.gunner1) { self = self.gunner1; @@ -803,7 +814,7 @@ float v_bumblebee(float req) other = oldother; return true; } - + if(self.gunner2) { self = self.gunner2; @@ -815,9 +826,9 @@ float v_bumblebee(float req) self.touch(); other = oldother; return true; - } + } } - + return true; } case VR_DEATH: @@ -829,7 +840,7 @@ float v_bumblebee(float req) // Hide beam if(self.gun3.enemy || !wasfreed(self.gun3.enemy)) self.gun3.enemy.effects |= EF_NODRAW; - + if(self.gunner1) { self = self.gunner1; @@ -857,7 +868,7 @@ float v_bumblebee(float req) _body.touch = bumblebee_blowup; else _body.touch = func_null; - + _body.think = bumblebee_diethink; _body.nextthink = time; _body.wait = time + 2 + (random() * 8); @@ -867,7 +878,7 @@ float v_bumblebee(float req) _body.angles = self.angles; Send_Effect("explosion_medium", findbetterlocation(self.origin, 16), '0 0 0', 1); - + self.health = 0; self.event_damage = func_null; self.solid = SOLID_NOT; @@ -941,14 +952,14 @@ float v_bumblebee(float req) setorigin(self.gun2.vehicle_viewport, '-85 0 50'); self.scale = 1.5; - + // Raygun beam if(self.gun3.enemy == world) - { + { self.gun3.enemy = spawn(); 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.SendFlags = BRG_SETUP; + self.gun3.enemy.cnt = autocvar_g_vehicle_bumblebee_raygun; self.gun3.enemy.effects = EF_NODRAW | EF_LOWPRECISION; } } @@ -958,9 +969,9 @@ float v_bumblebee(float req) self.solid = SOLID_BBOX; self.movetype = MOVETYPE_TOSS; self.damageforcescale = 0.025; - + self.PlayerPhysplug = bumblebee_pilot_frame; - + setorigin(self, self.origin + '0 0 25'); return true; } @@ -978,13 +989,13 @@ float v_bumblebee(float req) if(autocvar_g_vehicle_bumblebee_health_regen) self.vehicle_flags |= VHF_HEALTHREGEN; - + self.vehicle_exit = bumblebee_exit; self.respawntime = autocvar_g_vehicle_bumblebee_respawntime; self.vehicle_health = autocvar_g_vehicle_bumblebee_health; self.max_health = self.vehicle_health; self.vehicle_shield = autocvar_g_vehicle_bumblebee_shield; - + return true; } case VR_PRECACHE: @@ -1096,7 +1107,7 @@ float v_bumblebee(float req) { case VR_HUD: { - Vehicles_drawHUD("vehicle_bumble", "vehicle_bumble_weapon1", "vehicle_bumble_weapon2", + Vehicles_drawHUD(VEH_BUMBLEBEE.m_icon, "vehicle_bumble_weapon1", "vehicle_bumble_weapon2", "vehicle_icon_ammo1", autocvar_hud_progressbar_vehicles_ammo1_color, "vehicle_icon_ammo1", autocvar_hud_progressbar_vehicles_ammo1_color, vCROSS_HEAL); diff --git a/qcsrc/common/vehicles/unit/racer.qc b/qcsrc/common/vehicles/unit/racer.qc index 80cde03135..d6fbbcc2f4 100644 --- a/qcsrc/common/vehicles/unit/racer.qc +++ b/qcsrc/common/vehicles/unit/racer.qc @@ -1,7 +1,10 @@ -#ifdef REGISTER_VEHICLE -REGISTER_VEHICLE( +#ifndef VEHICLE_RACER +#define VEHICLE_RACER +#ifndef MENUQC +int v_racer(int); +#endif +REGISTER_VEHICLE_SIMPLE( /* VEH_##id */ RACER, -/* function */ v_racer, /* spawnflags */ VHF_DMGSHAKE | VHF_DMGROLL, /* mins,maxs */ '-120 -120 -40' * 0.5, '120 120 40' * 0.5, /* model */ "models/vehicles/wakizashi.dpm", @@ -10,8 +13,15 @@ REGISTER_VEHICLE( /* tags */ "", "", "tag_viewport", /* netname */ "racer", /* fullname */ _("Racer") -); -#else +) { + this.m_icon = "vehicle_racer"; +#ifndef MENUQC + this.vehicle_func = v_racer; +#endif +} +#endif + +#ifdef IMPLEMENTATION #ifdef SVQC #include "../../effects.qh" #include "../../triggers/trigger/impulse.qh" @@ -124,7 +134,7 @@ void racer_align4point(float _delta) self.velocity += push_vector * _delta; float uforce = autocvar_g_vehicle_racer_upforcedamper; - + int cont = pointcontents(self.origin - '0 0 64'); if(cont == CONTENT_WATER || cont == CONTENT_LAVA || cont == CONTENT_SLIME) { @@ -135,7 +145,7 @@ void racer_align4point(float _delta) else self.velocity_z += 200; } - + // Anti ocilation if(self.velocity_z > 0) @@ -218,7 +228,7 @@ void racer_rocket_groundhugger() self.velocity = olddir * newvel; self.velocity_z -= 1600 * sys_frametime; // 2x grav looks better for this one } - + int cont = pointcontents(self.origin - '0 0 32'); if(cont == CONTENT_WATER || cont == CONTENT_LAVA || cont == CONTENT_SLIME) self.velocity_z += 200; @@ -568,7 +578,7 @@ void racer_think() self.angles_x *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * pushdeltatime); self.angles_z *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * pushdeltatime); - + CSQCMODEL_AUTOUPDATE(); } @@ -642,10 +652,10 @@ void racer_blowup() void racer_blowup_think() { self.nextthink = time; - + if(time >= self.delay) racer_blowup(); - + CSQCMODEL_AUTOUPDATE(); } @@ -694,7 +704,7 @@ void racer_draw() self.move_angles_x *= 1 - (getstatf(STAT_VEH_RACER_ANGLESTABILIZER) * pushdeltatime); self.move_angles_z *= 1 - (getstatf(STAT_VEH_RACER_ANGLESTABILIZER) * pushdeltatime); - + Movetype_Physics_MatchServer(false); } #endif @@ -726,7 +736,7 @@ bool v_racer(int req) self.move_movetype = MOVETYPE_BOUNCE; #endif - + return true; } @@ -757,9 +767,9 @@ bool v_racer(int req) self.solid = SOLID_SLIDEBOX; self.delay = time; self.scale = 0.5; - + self.PlayerPhysplug = racer_frame; - + self.bouncefactor = autocvar_g_vehicle_racer_bouncefactor; self.bouncestop = autocvar_g_vehicle_racer_bouncestop; self.damageforcescale = 0.5; @@ -804,7 +814,7 @@ bool v_racer(int req) #ifdef CSQC case VR_HUD: { - Vehicles_drawHUD("vehicle_racer", "vehicle_racer_weapon1", "vehicle_racer_weapon2", + Vehicles_drawHUD(VEH_RACER.m_icon, "vehicle_racer_weapon1", "vehicle_racer_weapon2", "vehicle_icon_ammo1", autocvar_hud_progressbar_vehicles_ammo1_color, "vehicle_icon_ammo2", autocvar_hud_progressbar_vehicles_ammo2_color, vCROSS_GUIDE); @@ -856,9 +866,10 @@ bool v_racer(int req) precache_model ("models/vhshield.md3"); #endif - + #ifndef MENUQC precache_model ("models/vehicles/wakizashi.dpm"); precache_model ("models/vehicles/wakizashi_cockpit.dpm"); + #endif return true; } } diff --git a/qcsrc/common/vehicles/unit/raptor.qc b/qcsrc/common/vehicles/unit/raptor.qc index bff81b7d86..93e1605aef 100644 --- a/qcsrc/common/vehicles/unit/raptor.qc +++ b/qcsrc/common/vehicles/unit/raptor.qc @@ -1,7 +1,11 @@ -#ifdef REGISTER_VEHICLE -REGISTER_VEHICLE( +#ifndef VEHICLE_RAPTOR +#define VEHICLE_RAPTOR +#include "raptor.qh" +#ifndef MENUQC +int v_raptor(int); +#endif +REGISTER_VEHICLE_SIMPLE( /* VEH_##id */ RAPTOR, -/* function */ v_raptor, /* spawnflags */ VHF_DMGSHAKE | VHF_DMGROLL, /* mins,maxs */ '-80 -80 0', '80 80 70', /* model */ "models/vehicles/raptor.dpm", @@ -10,8 +14,15 @@ REGISTER_VEHICLE( /* tags */ "", "tag_hud", "tag_camera", /* netname */ "raptor", /* fullname */ _("Raptor") -); -#else +) { + this.m_icon = "vehicle_raptor"; +#ifndef MENUQC + this.vehicle_func = v_raptor; +#endif +} +#endif + +#ifdef IMPLEMENTATION #ifdef SVQC bool autocvar_g_vehicle_raptor; @@ -214,7 +225,7 @@ void raptor_land() } self.nextthink = time; - + CSQCMODEL_AUTOUPDATE(); } @@ -310,7 +321,7 @@ float raptor_frame() player = self; raptor = self.vehicle; self = raptor; - + vehicles_painframe(); /* ftmp = vlen(self.velocity); @@ -642,11 +653,11 @@ float raptor_takeoff() player = self; raptor = self.vehicle; self = raptor; - + self.nextthink = time; CSQCMODEL_AUTOUPDATE(); self.nextthink = 0; // will this work? - + if(self.sound_nexttime < time) { self.sound_nexttime = time + 7.955812; //soundlength("vehicles/raptor_fly.wav"); @@ -720,7 +731,7 @@ void raptor_diethink() Send_Effect("explosion_small", randomvec() * 80 + (self.origin + '0 0 100'), '0 0 0', 1); } self.nextthink = time; - + CSQCMODEL_AUTOUPDATE(); } @@ -792,7 +803,7 @@ float v_raptor(float req) { if(autocvar_g_vehicle_raptor_bouncepain) vehicles_impact(autocvar_g_vehicle_raptor_bouncepain_x, autocvar_g_vehicle_raptor_bouncepain_y, autocvar_g_vehicle_raptor_bouncepain_z); - + return true; } case VR_ENTER: @@ -919,12 +930,12 @@ float v_raptor(float req) self.movetype = MOVETYPE_TOSS; self.solid = SOLID_SLIDEBOX; self.vehicle_energy = 1; - + self.PlayerPhysplug = raptor_frame; self.bomb1.gun1.avelocity_y = 90; self.bomb1.gun2.avelocity_y = -90; - + self.delay = time; self.bouncefactor = autocvar_g_vehicle_raptor_bouncefactor; @@ -947,13 +958,13 @@ float v_raptor(float req) if(autocvar_g_vehicle_raptor_energy_regen) self.vehicle_flags |= VHF_ENERGYREGEN; - + self.vehicle_exit = raptor_exit; self.respawntime = autocvar_g_vehicle_raptor_respawntime; self.vehicle_health = autocvar_g_vehicle_raptor_health; self.vehicle_shield = autocvar_g_vehicle_raptor_shield; self.max_health = self.vehicle_health; - + return true; } case VR_PRECACHE: @@ -968,7 +979,7 @@ float v_raptor(float req) precache_sound ("vehicles/raptor_fly.wav"); precache_sound ("vehicles/raptor_speed.wav"); precache_sound ("vehicles/missile_alarm.wav"); - + return true; } } @@ -1037,8 +1048,8 @@ float v_raptor(float req) case RSM_BOMB: crosshair = vCROSS_BURST; break; default: crosshair = vCROSS_BURST; } - - Vehicles_drawHUD("vehicle_raptor", "vehicle_raptor_weapon1", "vehicle_raptor_weapon2", + + Vehicles_drawHUD(VEH_RAPTOR.m_icon, "vehicle_raptor_weapon1", "vehicle_raptor_weapon2", "vehicle_icon_ammo1", autocvar_hud_progressbar_vehicles_ammo1_color, "vehicle_icon_ammo2", autocvar_hud_progressbar_vehicles_ammo2_color, crosshair); diff --git a/qcsrc/common/vehicles/unit/spiderbot.qc b/qcsrc/common/vehicles/unit/spiderbot.qc index 0aa2ebe792..0ad0da41dc 100644 --- a/qcsrc/common/vehicles/unit/spiderbot.qc +++ b/qcsrc/common/vehicles/unit/spiderbot.qc @@ -1,7 +1,10 @@ -#ifdef REGISTER_VEHICLE -REGISTER_VEHICLE( +#ifndef VEHICLE_SPIDERBOT +#define VEHICLE_SPIDERBOT +#ifndef MENUQC +int v_spiderbot(int); +#endif +REGISTER_VEHICLE_SIMPLE( /* VEH_##id */ SPIDERBOT, -/* function */ v_spiderbot, /* spawnflags */ VHF_DMGSHAKE, /* mins,maxs */ '-75 -75 10', '75 75 125', /* model */ "models/vehicles/spiderbot.dpm", @@ -10,8 +13,15 @@ REGISTER_VEHICLE( /* tags */ "tag_head", "tag_hud", "", /* netname */ "spiderbot", /* fullname */ _("Spiderbot") -); -#else +) { + this.m_icon = "vehicle_spider"; +#ifndef MENUQC + this.vehicle_func = v_spiderbot; +#endif +} +#endif + +#ifdef IMPLEMENTATION const int SBRM_FIRST = 1; const int SBRM_VOLLY = 1; @@ -250,7 +260,7 @@ void spiderbot_rocket_do() if(self.wait != -10) if(!self.owner.BUTTON_ATCK2) return; - + if(forbidWeaponUse(self.owner)) return; @@ -815,7 +825,7 @@ float v_spiderbot(float req) { if(autocvar_g_vehicle_spiderbot_bouncepain) vehicles_impact(autocvar_g_vehicle_spiderbot_bouncepain_x, autocvar_g_vehicle_spiderbot_bouncepain_y, autocvar_g_vehicle_spiderbot_bouncepain_z); - + return true; } case VR_ENTER: @@ -831,14 +841,14 @@ float v_spiderbot(float req) setattachment(self.owner.flagcarried, self.tur_head, ""); setorigin(self.owner.flagcarried, '-20 0 120'); } - + return true; } case VR_THINK: { if(self.flags & FL_ONGROUND) movelib_beak_simple(autocvar_g_vehicle_spiderbot_speed_stop); - + return true; } case VR_DEATH: @@ -856,7 +866,7 @@ float v_spiderbot(float req) self.colormod = self.tur_head.colormod = '-1 -1 -1'; self.frame = 10; self.movetype = MOVETYPE_TOSS; - + CSQCModel_UnlinkEntity(); // networking the death scene would be a nightmare return true; @@ -889,7 +899,7 @@ float v_spiderbot(float req) self.damageforcescale = 0.03; self.vehicle_health = autocvar_g_vehicle_spiderbot_health; self.vehicle_shield = autocvar_g_vehicle_spiderbot_shield; - + self.PlayerPhysplug = spiderbot_frame; return true; @@ -959,7 +969,7 @@ float v_spiderbot(float req) default: crosshair = vCROSS_BURST; } - Vehicles_drawHUD("vehicle_spider", "vehicle_spider_weapon1", "vehicle_spider_weapon2", + Vehicles_drawHUD(VEH_SPIDERBOT.m_icon, "vehicle_spider_weapon1", "vehicle_spider_weapon2", "vehicle_icon_ammo1", autocvar_hud_progressbar_vehicles_ammo1_color, "vehicle_icon_ammo2", autocvar_hud_progressbar_vehicles_ammo2_color, crosshair); @@ -969,7 +979,7 @@ float v_spiderbot(float req) { AuxiliaryXhair[0].axh_image = vCROSS_HINT; // Minigun1 AuxiliaryXhair[1].axh_image = vCROSS_HINT; // Minigun2 - + return true; } case VR_PRECACHE: diff --git a/qcsrc/common/vehicles/vehicle.qh b/qcsrc/common/vehicles/vehicle.qh new file mode 100644 index 0000000000..7df34206fc --- /dev/null +++ b/qcsrc/common/vehicles/vehicle.qh @@ -0,0 +1,40 @@ +#ifndef VEHICLE_H +#define VEHICLE_H + +int v_null(int) { return 0; } + +CLASS(Vehicle, Object) + ATTRIB(Vehicle, vehicleid, int, 0) + /** hud icon */ + ATTRIB(Vehicle, m_icon, string, string_null) + /** short name */ + ATTRIB(Vehicle, netname, string, "") + /** human readable name */ + ATTRIB(Vehicle, vehicle_name, string, "Vehicle") + /** */ + ATTRIB(Vehicle, vehicle_func, int(int), v_null) + /** full name of model */ + ATTRIB(Vehicle, model, string, "") + /** currently a copy of the model */ + ATTRIB(Vehicle, mdl, string, "") + /** full name of tur_head model */ + ATTRIB(Vehicle, head_model, string, "") + /** cockpit model */ + ATTRIB(Vehicle, hud_model, string, "") + /** tur_head model tag */ + ATTRIB(Vehicle, tag_head, string, string_null) + /** hud model tag */ + ATTRIB(Vehicle, tag_hud, string, string_null) + /** cockpit model tag */ + ATTRIB(Vehicle, tag_view, string, string_null) + /** player physics mod */ + ATTRIB(Vehicle, PlayerPhysplug, int(), func_null) + /** */ + ATTRIB(Vehicle, spawnflags, int, 0) + /** vehicle hitbox size */ + ATTRIB(Vehicle, mins, vector, '-0 -0 -0') + /** vehicle hitbox size */ + ATTRIB(Vehicle, maxs, vector, '0 0 0') +ENDCLASS(Vehicle) + +#endif diff --git a/qcsrc/common/vehicles/vehicles.qc b/qcsrc/common/vehicles/vehicles.qc deleted file mode 100644 index e982c6f397..0000000000 --- a/qcsrc/common/vehicles/vehicles.qc +++ /dev/null @@ -1,89 +0,0 @@ -#include "unit/all.qh" - -#include "vehicles_include.qc" - -// VEHICLE PLUGIN SYSTEM -entity vehicle_info[VEH_MAXCOUNT]; -entity dummy_vehicle_info; - -void vehicles_common_initialize() -{ -#ifdef CSQC - precache_model("models/vehicles/bomblet.md3"); - precache_model("models/vehicles/clusterbomb.md3"); - precache_model("models/vehicles/clusterbomb_fragment.md3"); - precache_model("models/vehicles/rocket01.md3"); - precache_model("models/vehicles/rocket02.md3"); - - precache_sound ("vehicles/alarm.wav"); - precache_sound ("vehicles/alarm_shield.wav"); -#endif // CSQC -#ifdef SVQC - precache_sound("onslaught/ons_hit2.wav"); - precache_sound("onslaught/electricity_explode.wav"); - - addstat(STAT_HUD, AS_INT, hud); - addstat(STAT_VEHICLESTAT_HEALTH, AS_INT, vehicle_health); - addstat(STAT_VEHICLESTAT_SHIELD, AS_INT, vehicle_shield); - addstat(STAT_VEHICLESTAT_ENERGY, AS_INT, vehicle_energy); - - addstat(STAT_VEHICLESTAT_W2MODE, AS_INT, vehicle_weapon2mode); - - addstat(STAT_VEHICLESTAT_AMMO1, AS_INT, vehicle_ammo1); - addstat(STAT_VEHICLESTAT_RELOAD1, AS_INT, vehicle_reload1); - - addstat(STAT_VEHICLESTAT_AMMO2, AS_INT, vehicle_ammo2); - addstat(STAT_VEHICLESTAT_RELOAD2, AS_INT, vehicle_reload2); -#endif // SVQC -} - -void register_vehicle(float id, float(float) func, float vehicleflags, vector min_s, vector max_s, string modelname, string headmodelname, string hudmodelname, string headtag, string hudtag, string viewtag, string shortname, string vname) -{ - entity e; - vehicle_info[id - 1] = e = spawn(); - e.classname = "vehicle_info"; - e.vehicleid = id; - e.netname = shortname; - e.vehicle_name = vname; - e.vehicle_func = func; - e.mdl = modelname; - e.spawnflags = vehicleflags; - e.mins = min_s; - e.maxs = max_s; - e.model = modelname; - e.head_model = headmodelname; - e.hud_model = hudmodelname; - e.tag_head = headtag; - e.tag_hud = hudtag; - e.tag_view = viewtag; - - #ifndef MENUQC - vehicles_common_initialize(); - #endif -} -float v_null(float dummy) { return 0; } -void register_vehicles_done() -{ - dummy_vehicle_info = spawn(); - dummy_vehicle_info.classname = "vehicle_info"; - dummy_vehicle_info.vehicleid = 0; // you can recognize dummies by this - dummy_vehicle_info.netname = ""; - dummy_vehicle_info.vehicle_name = "Vehicle"; - dummy_vehicle_info.vehicle_func = v_null; - dummy_vehicle_info.mdl = ""; - dummy_vehicle_info.mins = '-0 -0 -0'; - dummy_vehicle_info.maxs = '0 0 0'; - dummy_vehicle_info.model = ""; - dummy_vehicle_info.head_model = ""; - dummy_vehicle_info.hud_model = ""; -} -entity get_vehicleinfo(float id) -{ - entity m; - if(id < VEH_FIRST || id > VEH_LAST) - return dummy_vehicle_info; - m = vehicle_info[id - 1]; - if(m) - return m; - return dummy_vehicle_info; -} diff --git a/qcsrc/common/vehicles/vehicles.qh b/qcsrc/common/vehicles/vehicles.qh deleted file mode 100644 index b0f28b557e..0000000000 --- a/qcsrc/common/vehicles/vehicles.qh +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef VEHICLES_H -#define VEHICLES_H - -#include "sv_vehicles.qh" - -// vehicle requests -const int VR_SETUP = 1; // (BOTH) setup vehicle data -const int VR_THINK = 2; // (SERVER) logic to run every frame -const int VR_DEATH = 3; // (SERVER) called when vehicle dies -const int VR_PRECACHE = 4; // (BOTH) precaches models/sounds used by this vehicle -const int VR_ENTER = 5; // (SERVER) called when a player enters this vehicle -const int VR_SPAWN = 6; // (SERVER) called when the vehicle re-spawns -const int VR_IMPACT = 7; // (SERVER) called when a vehicle hits something -const int VR_HUD = 8; // (CLIENT) logic to run every frame - -// vehicle spawn flags (need them here for common registrations) -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 - -// functions: -entity get_vehicleinfo(float id); - -// fields: -.entity tur_head; - - -// entity properties of vehicleinfo: -.int vehicleid; // VEH_... -.string netname; // short name -.string vehicle_name; // human readable name -.int(int) vehicle_func; // v_... -.string mdl; // currently a copy of the model -.string model; // full name of model -.string head_model; // full name of tur_head model -.string hud_model; // cockpit model -.string tag_head; // tur_head model tag -.string tag_hud; // hud model tag -.string tag_view; // cockpit model tag -.int() PlayerPhysplug; // player physics mod -.int spawnflags; -.vector mins, maxs; // vehicle hitbox size - -// other useful macros -#define VEH_ACTION(vehicletype,mrequest) (get_vehicleinfo(vehicletype)).vehicle_func(mrequest) -#define VEH_NAME(vehicletype) (get_vehicleinfo(vehicletype)).vehicle_name - -// ===================== -// Vehicle Registration -// ===================== - -int v_null(int dummy); -void register_vehicle(int id, int(int) func, float vehicleflags, vector min_s, vector max_s, string modelname, string headmodelname, string hudmodelname, string headtag, string hudtag, string viewtag, string shortname, string vname); -void register_vehicles_done(); - -const int VEH_MAXCOUNT = 24; -#define VEH_FIRST 1 -int VEH_COUNT; -int VEH_LAST; - -#define REGISTER_VEHICLE_2(id,func,vehicleflags,min_s,max_s,modelname,headmodelname,hudmodelname,headtag,hudtag,viewtag,shortname,vname) \ - int id; \ - int func(int); \ - void RegisterVehicles_##id() \ - { \ - VEH_LAST = (id = VEH_FIRST + VEH_COUNT); \ - ++VEH_COUNT; \ - register_vehicle(id,func,vehicleflags,min_s,max_s,modelname,headmodelname,hudmodelname,headtag,hudtag,viewtag,shortname,vname); \ - } \ - ACCUMULATE_FUNCTION(RegisterVehicles, RegisterVehicles_##id) -#ifdef MENUQC -#define REGISTER_VEHICLE(id,func,vehicleflags,min_s,max_s,modelname,headmodelname,hudmodelname,headtag,hudtag,viewtag,shortname,vname) \ - REGISTER_VEHICLE_2(VEH_##id,v_null,vehicleflags,min_s,max_s,modelname,headmodelname,hudmodelname,headtag,hudtag,viewtag,shortname,vname) -#else -#define REGISTER_VEHICLE(id,func,vehicleflags,min_s,max_s,modelname,headmodelname,hudmodelname,headtag,hudtag,viewtag,shortname,vname) \ - REGISTER_VEHICLE_2(VEH_##id,func,vehicleflags,min_s,max_s,modelname,headmodelname,hudmodelname,headtag,hudtag,viewtag,shortname,vname) -#endif - -#include "unit/all.qh" - -#undef REGISTER_VEHICLE -ACCUMULATE_FUNCTION(RegisterVehicles, register_vehicles_done); - -#endif diff --git a/qcsrc/common/vehicles/vehicles_include.qc b/qcsrc/common/vehicles/vehicles_include.qc deleted file mode 100644 index 1bd181d503..0000000000 --- a/qcsrc/common/vehicles/vehicles_include.qc +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef VEHICLES_INCLUDE_C -#define VEHICLES_INCLUDE_C - -#include "vehicles_include.qh" - -#ifdef CSQC -#include "cl_vehicles.qc" -#include "vehicles.qc" -#endif // CSQC -#ifdef SVQC -#include "sv_vehicles.qc" -#include "vehicles.qc" -#endif // SVQC - -#endif diff --git a/qcsrc/common/vehicles/vehicles_include.qh b/qcsrc/common/vehicles/vehicles_include.qh deleted file mode 100644 index 26e52e4814..0000000000 --- a/qcsrc/common/vehicles/vehicles_include.qh +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef VEHICLES_INCLUDE_H -#define VEHICLES_INCLUDE_H - -#include "all.qh" - -#ifdef CSQC -#include "vehicles.qh" -#include "cl_vehicles.qh" -#elif defined(SVQC) -#include "vehicles.qh" -#include "sv_vehicles.qh" -#endif // SVQC - -#endif diff --git a/qcsrc/common/viewloc.qc b/qcsrc/common/viewloc.qc index ebcdc05c60..24e6d08ebe 100644 --- a/qcsrc/common/viewloc.qc +++ b/qcsrc/common/viewloc.qc @@ -83,7 +83,7 @@ void viewloc_SetViewLocation() position_a = view.viewloc.enemy.origin; position_b = view.viewloc.goalentity.origin; -#if 0 +#if 0 /*TODO: have the camera only move when a player moves too much from the center of the camera * basically the player can move around in a "box" in the center of th screen with out changing the camera position or angles */ @@ -97,22 +97,22 @@ void viewloc_SetViewLocation() camera_angle = '0 0 0'; - // a tracking camera follows the player when it leaves the world box + // a tracking camera follows the player when it leaves the world box if (cvar("cam_track")) { camera_angle = aim_vec (camera_position, view.origin); } - + // hard snap changes the angle as soon as it crosses over the nearest 90 degree mark if (cvar("cam_snap_hard")){ camera_angle = angle_snap_vec(aim_vec(camera_position, view.origin), 90); } - + // tries to avoid snapping unless it *really* needs to if (cvar("cam_snap_close")){ - + // like hard snap, but don't snap angles yet. camera_angle = aim_vec(camera_position, view.origin); - + /* if the difference between the old and new angle is 60 degrees or more, switch angles. * NOTE: bug/feature: this will use non-snaped angles for one frame. * doing this resualts in less code, faster code, and a smoother transisition between angles. @@ -124,13 +124,13 @@ void viewloc_SetViewLocation() else camera_angle_y = old_camera_angle_y; } - + //unlocking this allows the camera to look up and down. this also allows a top-down view. if (!cvar("cam_snap_unlock")) { camera_angle_x = 0; camera_angle_z = 0; } - + #if 0 dprint(vtos(camera_position), "\n"); dprint(vtos(old_camera_angle), "\n"); @@ -141,10 +141,10 @@ void viewloc_SetViewLocation() freeze_ang = getpropertyvec(VF_ANGLES); setproperty(VF_ORIGIN, camera_position); setproperty(VF_ANGLES, camera_angle); - + forward = vectoangles(normalize(vec_to_min(position_b, position_a) - vec_to_max(position_b, position_a))); backward = vectoangles(normalize(vec_to_max(position_b, position_a) - vec_to_min(position_b, position_a))); - + if(input_movevalues_y < 0) // left view.angles_y = backward_y; if(input_movevalues_y > 0) // favour right diff --git a/qcsrc/csqcmodellib/cl_player.qc b/qcsrc/csqcmodellib/cl_player.qc index ee0340dd5d..30dab91f2e 100644 --- a/qcsrc/csqcmodellib/cl_player.qc +++ b/qcsrc/csqcmodellib/cl_player.qc @@ -143,7 +143,7 @@ void PM_Movement_Move() { runstandardplayerphysics(self); #ifdef CSQC - self.flags = + self.flags = ((self.pmove_flags & PMF_DUCKED) ? FL_DUCKED : 0) | (!(self.pmove_flags & PMF_JUMP_HELD) ? FL_JUMPRELEASED : 0) | ((self.pmove_flags & PMF_ONGROUND) ? FL_ONGROUND : 0); diff --git a/qcsrc/dpdefs/upstream/dpextensions.qc b/qcsrc/dpdefs/upstream/dpextensions.qc index 07142e9437..fb3dcda7c4 100644 --- a/qcsrc/dpdefs/upstream/dpextensions.qc +++ b/qcsrc/dpdefs/upstream/dpextensions.qc @@ -436,7 +436,7 @@ void(entity e, entity tagentity, string tagname) setattachment = #443; // attach //darkplaces implementation: Blub\0 //cvar definitions: // utf8_enable: enable utf8 encoding -//description: utf8 characters are allowed inside cvars, protocol strings, files, progs strings, etc., +//description: utf8 characters are allowed inside cvars, protocol strings, files, progs strings, etc., //and count as 1 char for string functions like strlen, substring, etc. // note: utf8_enable is run-time cvar, could be changed during execution // note: beware that str2chr() could return value bigger than 255 once utf8 is enabled @@ -498,7 +498,7 @@ void(entity e, entity tagentity, string tagname) setattachment = #443; // attach // description: allows alternative 'static' lightstyle syntax : "=value" // examples: "=0.5", "=2.0", "=2.75" // could be used to control switchable lights or making styled lights with brightness > 2 -// Warning: this extension is experimental. It safely works in CSQC, but SVQC use is limited by the fact +// Warning: this extension is experimental. It safely works in CSQC, but SVQC use is limited by the fact // that other engines (which do not support this extension) could connect to a game and misunderstand this kind of lightstyle syntax //DP_LITSPRITES @@ -1360,14 +1360,14 @@ float(string sample) soundlength = #534; // returns length of sound sample in se //syntax of .dpsubs files: each line in .dpsubs file defines 1 subtitle, there are three tokens: // "string" // start: subtitle start time in seconds -// end: subtitle time-to-show in seconds, if 0 - subtitle will be showed until next subtitle is started, +// end: subtitle time-to-show in seconds, if 0 - subtitle will be showed until next subtitle is started, // if below 0 - show until next subtitles minus this number of seconds // text: subtitle text, color codes (Q3-style and ^xRGB) are allowed //example of subtitle file: // 3 0 "Vengeance! Vengeance for my eternity of suffering!" // 9 0 "Whelp! As if you knew what eternity was!" // 13 0 "Grovel before your true master." -// 17 0 "Never!" +// 17 0 "Never!" // 18 7 "I'll hack you from crotch to gizzard and feed what's left of you to your brides..." //DP_SOLIDCORPSE @@ -1734,11 +1734,11 @@ const float FORCETYPE_TORQUE = 3; .vector massofs; // offsets a mass center out of object center, if not set a center of model bounds is used .float friction; // a friction of object, get multiplied by second objects's friction on contact .float bouncefactor; -.float bouncestop; +.float bouncestop; .float jointtype; // type of joint .float forcetype; // type of force -.float erp; // error restitution parameter, makes ODE solver attempt to fix errors in contacts, - // bringing together 2 joints or fixing object being stuch in other object, +.float erp; // error restitution parameter, makes ODE solver attempt to fix errors in contacts, + // bringing together 2 joints or fixing object being stuch in other object, // a value of 0.1 will fix slightly, a value of 1.0 attempts to fix whole error in one frame // use with care as high values makes system unstable and likely to explode //builtin definitions: diff --git a/qcsrc/dpdefs/upstream/menudefs.qc b/qcsrc/dpdefs/upstream/menudefs.qc index 8caab4a927..d1a67ab085 100644 --- a/qcsrc/dpdefs/upstream/menudefs.qc +++ b/qcsrc/dpdefs/upstream/menudefs.qc @@ -304,7 +304,7 @@ float drawstring(vector position, string text, vector scale, vector rgb, float a float drawcolorcodedstring(vector position, string text, vector scale, float alpha, float flag) = #467; vector drawcolorcodedstring2(vector position, string text, vector scale, vector rgb, float alpha, float flag) = #467; - + float drawpic(vector position, string pic, vector size, vector rgb, float alpha, float flag) = #456; float drawfill(vector position, vector size, vector rgb, float alpha, float flag) = #457; diff --git a/qcsrc/menu/anim/animation.qc b/qcsrc/menu/anim/animation.qc index 3039d85b8d..d52ae4f719 100644 --- a/qcsrc/menu/anim/animation.qc +++ b/qcsrc/menu/anim/animation.qc @@ -3,19 +3,19 @@ #include "../oo/base.qh" void setterDummy(entity, float); CLASS(Animation, Object) - METHOD(Animation, configureAnimation, void(entity, entity, void(entity, float), float, float, float, float)) - METHOD(Animation, setTimeStartEnd, void(entity, float, float)) - METHOD(Animation, setTimeStartDuration, void(entity, float, float)) - METHOD(Animation, setValueStartEnd, void(entity, float, float)) - METHOD(Animation, setValueStartDelta, void(entity, float, float)) - METHOD(Animation, setObjectSetter, void(entity, entity, void(entity, float))) - METHOD(Animation, tick, void(entity, float)) - METHOD(Animation, calcValue, float(entity, float, float, float, float)) - METHOD(Animation, isStopped, float(entity)) - METHOD(Animation, stopAnim, void(entity)) - METHOD(Animation, resumeAnim, void(entity)) - METHOD(Animation, isFinished, float(entity)) - METHOD(Animation, finishAnim, void(entity)) + METHOD(Animation, configureAnimation, void(entity, entity, void(entity, float), float, float, float, float)); + METHOD(Animation, setTimeStartEnd, void(entity, float, float)); + METHOD(Animation, setTimeStartDuration, void(entity, float, float)); + METHOD(Animation, setValueStartEnd, void(entity, float, float)); + METHOD(Animation, setValueStartDelta, void(entity, float, float)); + METHOD(Animation, setObjectSetter, void(entity, entity, void(entity, float))); + METHOD(Animation, tick, void(entity, float)); + METHOD(Animation, calcValue, float(entity, float, float, float, float)); + METHOD(Animation, isStopped, float(entity)); + METHOD(Animation, stopAnim, void(entity)); + METHOD(Animation, resumeAnim, void(entity)); + METHOD(Animation, isFinished, float(entity)); + METHOD(Animation, finishAnim, void(entity)); ATTRIB(Animation, object, entity, NULL) ATTRIB(Animation, setter, void(entity, float), setterDummy) ATTRIB(Animation, value, float, 0) diff --git a/qcsrc/menu/anim/animhost.qc b/qcsrc/menu/anim/animhost.qc index 61a040cff9..4489de3d5a 100644 --- a/qcsrc/menu/anim/animhost.qc +++ b/qcsrc/menu/anim/animhost.qc @@ -4,17 +4,17 @@ #define ANIM_ANIMHOST_H #include "../oo/base.qh" CLASS(AnimHost, Object) - METHOD(AnimHost, addAnim, void(entity, entity)) - METHOD(AnimHost, removeAnim, void(entity, entity)) - METHOD(AnimHost, removeAllAnim, void(entity)) - METHOD(AnimHost, removeObjAnim, void(entity, entity)) - METHOD(AnimHost, stopAllAnim, void(entity)) - METHOD(AnimHost, stopObjAnim, void(entity, entity)) - METHOD(AnimHost, resumeAllAnim, void(entity)) - METHOD(AnimHost, resumeObjAnim, void(entity, entity)) - METHOD(AnimHost, finishAllAnim, void(entity)) - METHOD(AnimHost, finishObjAnim, void(entity, entity)) - METHOD(AnimHost, tickAll, void(entity)) + METHOD(AnimHost, addAnim, void(entity, entity)); + METHOD(AnimHost, removeAnim, void(entity, entity)); + METHOD(AnimHost, removeAllAnim, void(entity)); + METHOD(AnimHost, removeObjAnim, void(entity, entity)); + METHOD(AnimHost, stopAllAnim, void(entity)); + METHOD(AnimHost, stopObjAnim, void(entity, entity)); + METHOD(AnimHost, resumeAllAnim, void(entity)); + METHOD(AnimHost, resumeObjAnim, void(entity, entity)); + METHOD(AnimHost, finishAllAnim, void(entity)); + METHOD(AnimHost, finishObjAnim, void(entity, entity)); + METHOD(AnimHost, tickAll, void(entity)); ATTRIB(AnimHost, firstChild, entity, NULL) ATTRIB(AnimHost, lastChild, entity, NULL) ENDCLASS(AnimHost) diff --git a/qcsrc/menu/anim/easing.qc b/qcsrc/menu/anim/easing.qc index fe4c0fb65a..f1962719f8 100644 --- a/qcsrc/menu/anim/easing.qc +++ b/qcsrc/menu/anim/easing.qc @@ -8,8 +8,8 @@ float easingQuadIn(float, float, float, float); float easingQuadOut(float, float, float, float); float easingQuadInOut(float, float, float, float); CLASS(Easing, Animation) - METHOD(Easing, calcValue, float(entity, float, float, float, float)) - METHOD(Easing, setMath, void(entity, float(float, float, float, float))) + METHOD(Easing, calcValue, float(entity, float, float, float, float)); + METHOD(Easing, setMath, void(entity, float(float, float, float, float))); ATTRIB(Easing, math, float(float, float, float, float), easingLinear) ENDCLASS(Easing) #endif diff --git a/qcsrc/menu/anim/keyframe.qc b/qcsrc/menu/anim/keyframe.qc index d310ef72c7..d83a2cbd49 100644 --- a/qcsrc/menu/anim/keyframe.qc +++ b/qcsrc/menu/anim/keyframe.qc @@ -2,9 +2,9 @@ #define ANIM_KEYFRAME_H #include "animation.qc" CLASS(Keyframe, Animation) - METHOD(Keyframe, addEasing, entity(entity, float, float, float(float, float, float, float))) - METHOD(Keyframe, addAnim, void(entity, entity)) - METHOD(Keyframe, calcValue, float(entity, float, float, float, float)) + METHOD(Keyframe, addEasing, entity(entity, float, float, float(float, float, float, float))); + METHOD(Keyframe, addAnim, void(entity, entity)); + METHOD(Keyframe, calcValue, float(entity, float, float, float, float)); ATTRIB(Keyframe, currentChild, entity, NULL) ATTRIB(Keyframe, firstChild, entity, NULL) ATTRIB(Keyframe, lastChild, entity, NULL) diff --git a/qcsrc/menu/item.qc b/qcsrc/menu/item.qc index cb24866d1f..8788f2e84d 100644 --- a/qcsrc/menu/item.qc +++ b/qcsrc/menu/item.qc @@ -3,21 +3,21 @@ #include "skin.qh" #include "oo/base.qh" CLASS(Item, Object) - METHOD(Item, draw, void(entity)) - METHOD(Item, keyDown, float(entity, float, float, float)) - METHOD(Item, keyUp, float(entity, float, float, float)) - METHOD(Item, mouseMove, float(entity, vector)) - METHOD(Item, mousePress, float(entity, vector)) - METHOD(Item, mouseDrag, float(entity, vector)) - METHOD(Item, mouseRelease, float(entity, vector)) - METHOD(Item, focusEnter, void(entity)) - METHOD(Item, focusLeave, void(entity)) - METHOD(Item, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(Item, relinquishFocus, void(entity)) - METHOD(Item, showNotify, void(entity)) - METHOD(Item, hideNotify, void(entity)) - METHOD(Item, toString, string(entity)) - METHOD(Item, destroy, void(entity)) + METHOD(Item, draw, void(entity)); + METHOD(Item, keyDown, float(entity, float, float, float)); + METHOD(Item, keyUp, float(entity, float, float, float)); + METHOD(Item, mouseMove, float(entity, vector)); + METHOD(Item, mousePress, float(entity, vector)); + METHOD(Item, mouseDrag, float(entity, vector)); + METHOD(Item, mouseRelease, float(entity, vector)); + METHOD(Item, focusEnter, void(entity)); + METHOD(Item, focusLeave, void(entity)); + METHOD(Item, resizeNotify, void(entity, vector, vector, vector, vector)); + METHOD(Item, relinquishFocus, void(entity)); + METHOD(Item, showNotify, void(entity)); + METHOD(Item, hideNotify, void(entity)); + METHOD(Item, toString, string(entity)); + METHOD(Item, destroy, void(entity)); ATTRIB(Item, focused, float, 0) ATTRIB(Item, focusable, float, 0) ATTRIB(Item, allowFocusSound, float, 0) diff --git a/qcsrc/menu/item/borderimage.qc b/qcsrc/menu/item/borderimage.qc index 6b6f4693dc..bcbd408edd 100644 --- a/qcsrc/menu/item/borderimage.qc +++ b/qcsrc/menu/item/borderimage.qc @@ -2,11 +2,11 @@ #define ITEM_BORDERIMAGE_H #include "label.qc" CLASS(BorderImage, Label) - METHOD(BorderImage, configureBorderImage, void(entity, string, float, vector, string, float)) - METHOD(BorderImage, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(BorderImage, recalcPositionWithText, void(entity, string)) + METHOD(BorderImage, configureBorderImage, void(entity, string, float, vector, string, float)); + METHOD(BorderImage, resizeNotify, void(entity, vector, vector, vector, vector)); + METHOD(BorderImage, recalcPositionWithText, void(entity, string)); ATTRIB(BorderImage, isBold, float, 1) - METHOD(BorderImage, draw, void(entity)) + METHOD(BorderImage, draw, void(entity)); ATTRIB(BorderImage, src, string, string_null) ATTRIB(BorderImage, borderHeight, float, 0) ATTRIB(BorderImage, borderVec, vector, '0 0 0') diff --git a/qcsrc/menu/item/button.qc b/qcsrc/menu/item/button.qc index 796ce40a33..343bf1d932 100644 --- a/qcsrc/menu/item/button.qc +++ b/qcsrc/menu/item/button.qc @@ -2,15 +2,15 @@ #define ITEM_BUTTON_H #include "label.qc" CLASS(Button, Label) - METHOD(Button, configureButton, void(entity, string, float, string)) - METHOD(Button, draw, void(entity)) - METHOD(Button, showNotify, void(entity)) - METHOD(Button, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(Button, keyDown, float(entity, float, float, float)) - METHOD(Button, mousePress, float(entity, vector)) - METHOD(Button, mouseDrag, float(entity, vector)) - METHOD(Button, mouseRelease, float(entity, vector)) - METHOD(Button, playClickSound, void(entity)) + METHOD(Button, configureButton, void(entity, string, float, string)); + METHOD(Button, draw, void(entity)); + METHOD(Button, showNotify, void(entity)); + METHOD(Button, resizeNotify, void(entity, vector, vector, vector, vector)); + METHOD(Button, keyDown, float(entity, float, float, float)); + METHOD(Button, mousePress, float(entity, vector)); + METHOD(Button, mouseDrag, float(entity, vector)); + METHOD(Button, mouseRelease, float(entity, vector)); + METHOD(Button, playClickSound, void(entity)); ATTRIB(Button, onClick, void(entity, entity), func_null) ATTRIB(Button, onClickEntity, entity, NULL) ATTRIB(Button, src, string, string_null) diff --git a/qcsrc/menu/item/checkbox.qc b/qcsrc/menu/item/checkbox.qc index e8b4e15e33..cda07c518b 100644 --- a/qcsrc/menu/item/checkbox.qc +++ b/qcsrc/menu/item/checkbox.qc @@ -3,11 +3,11 @@ #include "button.qc" void CheckBox_Click(entity me, entity other); CLASS(CheckBox, Button) - METHOD(CheckBox, configureCheckBox, void(entity, string, float, string)) - METHOD(CheckBox, draw, void(entity)) - METHOD(CheckBox, playClickSound, void(entity)) - METHOD(CheckBox, toString, string(entity)) - METHOD(CheckBox, setChecked, void(entity, float)) + METHOD(CheckBox, configureCheckBox, void(entity, string, float, string)); + METHOD(CheckBox, draw, void(entity)); + METHOD(CheckBox, playClickSound, void(entity)); + METHOD(CheckBox, toString, string(entity)); + METHOD(CheckBox, setChecked, void(entity, float)); ATTRIB(CheckBox, useDownAsChecked, float, 0) ATTRIB(CheckBox, checked, float, 0) ATTRIB(CheckBox, onClick, void(entity, entity), CheckBox_Click) diff --git a/qcsrc/menu/item/container.qc b/qcsrc/menu/item/container.qc index ac0655cfa6..cacb0124a2 100644 --- a/qcsrc/menu/item/container.qc +++ b/qcsrc/menu/item/container.qc @@ -2,28 +2,28 @@ #define ITEM_CONTAINER_H #include "../item.qc" CLASS(Container, Item) - METHOD(Container, draw, void(entity)) - METHOD(Container, keyUp, float(entity, float, float, float)) - METHOD(Container, keyDown, float(entity, float, float, float)) - METHOD(Container, mouseMove, float(entity, vector)) - METHOD(Container, mousePress, float(entity, vector)) - METHOD(Container, mouseDrag, float(entity, vector)) - METHOD(Container, mouseRelease, float(entity, vector)) - METHOD(Container, focusLeave, void(entity)) - METHOD(Container, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(Container, resizeNotifyLie, void(entity, vector, vector, vector, vector, .vector, .vector, .vector)) - METHOD(Container, addItem, void(entity, entity, vector, vector, float)) - METHOD(Container, addItemCentered, void(entity, entity, vector, float)) - METHOD(Container, addItemRightCentered, void(entity, entity, vector, float)) - METHOD(Container, moveItemAfter, void(entity, entity, entity)) - METHOD(Container, removeItem, void(entity, entity)) - METHOD(Container, setFocus, void(entity, entity)) - METHOD(Container, saveFocus, void(entity)) - METHOD(Container, setAlphaOf, void(entity, entity, float)) - METHOD(Container, itemFromPoint, entity(entity, vector)) - METHOD(Container, showNotify, void(entity)) - METHOD(Container, hideNotify, void(entity)) - METHOD(Container, preferredFocusedGrandChild, entity(entity)) + METHOD(Container, draw, void(entity)); + METHOD(Container, keyUp, float(entity, float, float, float)); + METHOD(Container, keyDown, float(entity, float, float, float)); + METHOD(Container, mouseMove, float(entity, vector)); + METHOD(Container, mousePress, float(entity, vector)); + METHOD(Container, mouseDrag, float(entity, vector)); + METHOD(Container, mouseRelease, float(entity, vector)); + METHOD(Container, focusLeave, void(entity)); + METHOD(Container, resizeNotify, void(entity, vector, vector, vector, vector)); + METHOD(Container, resizeNotifyLie, void(entity, vector, vector, vector, vector, .vector, .vector, .vector)); + METHOD(Container, addItem, void(entity, entity, vector, vector, float)); + METHOD(Container, addItemCentered, void(entity, entity, vector, float)); + METHOD(Container, addItemRightCentered, void(entity, entity, vector, float)); + METHOD(Container, moveItemAfter, void(entity, entity, entity)); + METHOD(Container, removeItem, void(entity, entity)); + METHOD(Container, setFocus, void(entity, entity)); + METHOD(Container, saveFocus, void(entity)); + METHOD(Container, setAlphaOf, void(entity, entity, float)); + METHOD(Container, itemFromPoint, entity(entity, vector)); + METHOD(Container, showNotify, void(entity)); + METHOD(Container, hideNotify, void(entity)); + METHOD(Container, preferredFocusedGrandChild, entity(entity)); ATTRIB(Container, focusable, float, 0) ATTRIB(Container, firstChild, entity, NULL) ATTRIB(Container, lastChild, entity, NULL) @@ -31,9 +31,9 @@ CLASS(Container, Item) ATTRIB(Container, savedFocus, entity, NULL) ATTRIB(Container, shown, float, 0) - METHOD(Container, enterSubitem, void(entity, entity)) - METHOD(Container, enterLieSubitem, void(entity, vector, vector, vector, float)) - METHOD(Container, leaveSubitem, void(entity)) + METHOD(Container, enterSubitem, void(entity, entity)); + METHOD(Container, enterLieSubitem, void(entity, vector, vector, vector, float)); + METHOD(Container, leaveSubitem, void(entity)); ENDCLASS(Container) .entity nextSibling; .entity prevSibling; diff --git a/qcsrc/menu/item/dialog.qc b/qcsrc/menu/item/dialog.qc index 77037ace61..f02be5b53f 100644 --- a/qcsrc/menu/item/dialog.qc +++ b/qcsrc/menu/item/dialog.qc @@ -17,18 +17,18 @@ #define ITEM_DIALOG_H #include "inputcontainer.qc" CLASS(Dialog, InputContainer) - METHOD(Dialog, configureDialog, void(entity)) // no runtime configuration, all parameters are given in the code! - METHOD(Dialog, fill, void(entity)) // to be overridden by user to fill the dialog with controls - METHOD(Dialog, keyDown, float(entity, float, float, float)) - METHOD(Dialog, close, void(entity)) - METHOD(Dialog, addItemSimple, void(entity, float, float, float, float, entity, vector)) - - METHOD(Dialog, TD, void(entity, float, float, entity)) - METHOD(Dialog, TDNoMargin, void(entity, float, float, entity, vector)) - METHOD(Dialog, TDempty, void(entity, float)) - METHOD(Dialog, setFirstColumn, void(entity, float)) - METHOD(Dialog, TR, void(entity)) - METHOD(Dialog, gotoRC, void(entity, float, float)) + METHOD(Dialog, configureDialog, void(entity)); // no runtime configuration, all parameters are given in the code! + METHOD(Dialog, fill, void(entity)); // to be overridden by user to fill the dialog with controls + METHOD(Dialog, keyDown, float(entity, float, float, float)); + METHOD(Dialog, close, void(entity)); + METHOD(Dialog, addItemSimple, void(entity, float, float, float, float, entity, vector)); + + METHOD(Dialog, TD, void(entity, float, float, entity)); + METHOD(Dialog, TDNoMargin, void(entity, float, float, entity, vector)); + METHOD(Dialog, TDempty, void(entity, float)); + METHOD(Dialog, setFirstColumn, void(entity, float)); + METHOD(Dialog, TR, void(entity)); + METHOD(Dialog, gotoRC, void(entity, float, float)); ATTRIB(Dialog, isTabRoot, float, 1) ATTRIB(Dialog, closeButton, entity, NULL) diff --git a/qcsrc/menu/item/image.qc b/qcsrc/menu/item/image.qc index 7756b49913..baa5d61573 100644 --- a/qcsrc/menu/item/image.qc +++ b/qcsrc/menu/item/image.qc @@ -2,15 +2,15 @@ #define ITEM_IMAGE_H #include "../item.qc" CLASS(Image, Item) - METHOD(Image, configureImage, void(entity, string)) - METHOD(Image, draw, void(entity)) - METHOD(Image, toString, string(entity)) - METHOD(Image, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(Image, updateAspect, void(entity)) - METHOD(Image, initZoom, void(entity)) - METHOD(Image, setZoom, void(entity, float, float)) - METHOD(Image, drag_setStartPos, float(entity, vector)) - METHOD(Image, drag, float(entity, vector)) + METHOD(Image, configureImage, void(entity, string)); + METHOD(Image, draw, void(entity)); + METHOD(Image, toString, string(entity)); + METHOD(Image, resizeNotify, void(entity, vector, vector, vector, vector)); + METHOD(Image, updateAspect, void(entity)); + METHOD(Image, initZoom, void(entity)); + METHOD(Image, setZoom, void(entity, float, float)); + METHOD(Image, drag_setStartPos, float(entity, vector)); + METHOD(Image, drag, float(entity, vector)); ATTRIB(Image, src, string, string_null) ATTRIB(Image, color, vector, '1 1 1') ATTRIB(Image, forcedAspect, float, 0) // special values: -1 keep image aspect ratio, -2 keep image size but bound to the containing box, -3 always keep image size diff --git a/qcsrc/menu/item/inputbox.qc b/qcsrc/menu/item/inputbox.qc index 5bcfd5f9c0..35ffe44d8b 100644 --- a/qcsrc/menu/item/inputbox.qc +++ b/qcsrc/menu/item/inputbox.qc @@ -2,17 +2,17 @@ #define ITEM_INPUTBOX_H #include "label.qc" CLASS(InputBox, Label) - METHOD(InputBox, configureInputBox, void(entity, string, float, float, string)) - METHOD(InputBox, draw, void(entity)) - METHOD(InputBox, setText, void(entity, string)) - METHOD(InputBox, enterText, void(entity, string)) - METHOD(InputBox, keyDown, float(entity, float, float, float)) - METHOD(InputBox, mouseMove, float(entity, vector)) - METHOD(InputBox, mouseRelease, float(entity, vector)) - METHOD(InputBox, mousePress, float(entity, vector)) - METHOD(InputBox, mouseDrag, float(entity, vector)) - METHOD(InputBox, showNotify, void(entity)) - METHOD(InputBox, resizeNotify, void(entity, vector, vector, vector, vector)) + METHOD(InputBox, configureInputBox, void(entity, string, float, float, string)); + METHOD(InputBox, draw, void(entity)); + METHOD(InputBox, setText, void(entity, string)); + METHOD(InputBox, enterText, void(entity, string)); + METHOD(InputBox, keyDown, float(entity, float, float, float)); + METHOD(InputBox, mouseMove, float(entity, vector)); + METHOD(InputBox, mouseRelease, float(entity, vector)); + METHOD(InputBox, mousePress, float(entity, vector)); + METHOD(InputBox, mouseDrag, float(entity, vector)); + METHOD(InputBox, showNotify, void(entity)); + METHOD(InputBox, resizeNotify, void(entity, vector, vector, vector, vector)); ATTRIB(InputBox, src, string, string_null) diff --git a/qcsrc/menu/item/inputcontainer.qc b/qcsrc/menu/item/inputcontainer.qc index 90ca719dce..660bc2d1b9 100644 --- a/qcsrc/menu/item/inputcontainer.qc +++ b/qcsrc/menu/item/inputcontainer.qc @@ -2,15 +2,15 @@ #define ITEM_INPUTCONTAINER_H #include "container.qc" CLASS(InputContainer, Container) - METHOD(InputContainer, keyDown, float(entity, float, float, float)) - METHOD(InputContainer, mouseMove, float(entity, vector)) - METHOD(InputContainer, mousePress, float(entity, vector)) - METHOD(InputContainer, mouseRelease, float(entity, vector)) - METHOD(InputContainer, mouseDrag, float(entity, vector)) - METHOD(InputContainer, focusLeave, void(entity)) - METHOD(InputContainer, resizeNotify, void(entity, vector, vector, vector, vector)) + METHOD(InputContainer, keyDown, float(entity, float, float, float)); + METHOD(InputContainer, mouseMove, float(entity, vector)); + METHOD(InputContainer, mousePress, float(entity, vector)); + METHOD(InputContainer, mouseRelease, float(entity, vector)); + METHOD(InputContainer, mouseDrag, float(entity, vector)); + METHOD(InputContainer, focusLeave, void(entity)); + METHOD(InputContainer, resizeNotify, void(entity, vector, vector, vector, vector)); - METHOD(InputContainer, _changeFocusXY, float(entity, vector)) + METHOD(InputContainer, _changeFocusXY, float(entity, vector)); ATTRIB(InputContainer, mouseFocusedChild, entity, NULL) ATTRIB(InputContainer, isTabRoot, float, 0) ENDCLASS(InputContainer) diff --git a/qcsrc/menu/item/label.qc b/qcsrc/menu/item/label.qc index 75e79f0b22..45a5a7fac4 100644 --- a/qcsrc/menu/item/label.qc +++ b/qcsrc/menu/item/label.qc @@ -2,12 +2,12 @@ #define ITEM_LABEL_H #include "../item.qc" CLASS(Label, Item) - METHOD(Label, configureLabel, void(entity, string, float, float)) - METHOD(Label, draw, void(entity)) - METHOD(Label, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(Label, setText, void(entity, string)) - METHOD(Label, toString, string(entity)) - METHOD(Label, recalcPositionWithText, void(entity, string)) + METHOD(Label, configureLabel, void(entity, string, float, float)); + METHOD(Label, draw, void(entity)); + METHOD(Label, resizeNotify, void(entity, vector, vector, vector, vector)); + METHOD(Label, setText, void(entity, string)); + METHOD(Label, toString, string(entity)); + METHOD(Label, recalcPositionWithText, void(entity, string)); ATTRIB(Label, isBold, float, 0) ATTRIB(Label, text, string, string_null) ATTRIB(Label, currentText, string, string_null) diff --git a/qcsrc/menu/item/listbox.qc b/qcsrc/menu/item/listbox.qc index e2bc5324bd..9cd76fe983 100644 --- a/qcsrc/menu/item/listbox.qc +++ b/qcsrc/menu/item/listbox.qc @@ -2,15 +2,15 @@ #define ITEM_LISTBOX_H #include "../item.qc" CLASS(ListBox, Item) - METHOD(ListBox, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(ListBox, configureListBox, void(entity, float, float)) - METHOD(ListBox, draw, void(entity)) - METHOD(ListBox, keyDown, float(entity, float, float, float)) - METHOD(ListBox, mouseMove, float(entity, vector)) - METHOD(ListBox, mousePress, float(entity, vector)) - METHOD(ListBox, mouseDrag, float(entity, vector)) - METHOD(ListBox, mouseRelease, float(entity, vector)) - METHOD(ListBox, focusLeave, void(entity)) + METHOD(ListBox, resizeNotify, void(entity, vector, vector, vector, vector)); + METHOD(ListBox, configureListBox, void(entity, float, float)); + METHOD(ListBox, draw, void(entity)); + METHOD(ListBox, keyDown, float(entity, float, float, float)); + METHOD(ListBox, mouseMove, float(entity, vector)); + METHOD(ListBox, mousePress, float(entity, vector)); + METHOD(ListBox, mouseDrag, float(entity, vector)); + METHOD(ListBox, mouseRelease, float(entity, vector)); + METHOD(ListBox, focusLeave, void(entity)); ATTRIB(ListBox, focusable, float, 1) ATTRIB(ListBox, focusedItem, int, -1) ATTRIB(ListBox, focusedItemAlpha, float, 0.3) @@ -22,12 +22,12 @@ CLASS(ListBox, Item) ATTRIB(ListBox, scrollPos, float, 0) // measured in window heights, fixed when needed ATTRIB(ListBox, scrollPosTarget, float, 0) ATTRIB(ListBox, needScrollToItem, float, -1) - METHOD(ListBox, scrollToItem, void(entity, int)) + METHOD(ListBox, scrollToItem, void(entity, int)); ATTRIB(ListBox, previousValue, float, 0) ATTRIB(ListBox, pressed, float, 0) // 0 = normal, 1 = scrollbar dragging, 2 = item dragging, 3 = released ATTRIB(ListBox, pressOffset, float, 0) - METHOD(ListBox, updateControlTopBottom, void(entity)) + METHOD(ListBox, updateControlTopBottom, void(entity)); ATTRIB(ListBox, controlTop, float, 0) ATTRIB(ListBox, controlBottom, float, 0) ATTRIB(ListBox, controlWidth, float, 0) @@ -49,19 +49,19 @@ CLASS(ListBox, Item) ATTRIB(ListBox, lastClickedItem, float, -1) ATTRIB(ListBox, lastClickedTime, float, 0) - METHOD(ListBox, drawListBoxItem, void(entity, int, vector, bool, bool)) // item number, width/height, isSelected, isFocused - METHOD(ListBox, clickListBoxItem, void(entity, float, vector)) // item number, relative clickpos - METHOD(ListBox, doubleClickListBoxItem, void(entity, float, vector)) // item number, relative clickpos - METHOD(ListBox, setSelected, void(entity, float)) + METHOD(ListBox, drawListBoxItem, void(entity, int, vector, bool, bool)); // item number, width/height, isSelected, isFocused + METHOD(ListBox, clickListBoxItem, void(entity, float, vector)); // item number, relative clickpos + METHOD(ListBox, doubleClickListBoxItem, void(entity, float, vector)); // item number, relative clickpos + METHOD(ListBox, setSelected, void(entity, float)); - METHOD(ListBox, getLastFullyVisibleItemAtScrollPos, float(entity, float)) - METHOD(ListBox, getFirstFullyVisibleItemAtScrollPos, float(entity, float)) + METHOD(ListBox, getLastFullyVisibleItemAtScrollPos, float(entity, float)); + METHOD(ListBox, getFirstFullyVisibleItemAtScrollPos, float(entity, float)); // NOTE: override these four methods if you want variable sized list items - METHOD(ListBox, getTotalHeight, float(entity)) - METHOD(ListBox, getItemAtPos, float(entity, float)) - METHOD(ListBox, getItemStart, float(entity, float)) - METHOD(ListBox, getItemHeight, float(entity, float)) + METHOD(ListBox, getTotalHeight, float(entity)); + METHOD(ListBox, getItemAtPos, float(entity, float)); + METHOD(ListBox, getItemStart, float(entity, float)); + METHOD(ListBox, getItemHeight, float(entity, float)); // NOTE: if getItemAt* are overridden, it may make sense to cache the // start and height of the last item returned by getItemAtPos and fast // track returning their properties for getItemStart and getItemHeight. diff --git a/qcsrc/menu/item/modalcontroller.qc b/qcsrc/menu/item/modalcontroller.qc index a13fcdd69f..8232125f75 100644 --- a/qcsrc/menu/item/modalcontroller.qc +++ b/qcsrc/menu/item/modalcontroller.qc @@ -2,17 +2,17 @@ #define ITEM_MODALCONTROLLER_H #include "container.qc" CLASS(ModalController, Container) - METHOD(ModalController, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(ModalController, draw, void(entity)) - METHOD(ModalController, showChild, void(entity, entity, vector, vector, float)) - METHOD(ModalController, hideChild, void(entity, entity, float)) - METHOD(ModalController, hideAll, void(entity, float)) - METHOD(ModalController, addItem, void(entity, entity, vector, vector, float)) - METHOD(ModalController, addTab, void(entity, entity, entity)) + METHOD(ModalController, resizeNotify, void(entity, vector, vector, vector, vector)); + METHOD(ModalController, draw, void(entity)); + METHOD(ModalController, showChild, void(entity, entity, vector, vector, float)); + METHOD(ModalController, hideChild, void(entity, entity, float)); + METHOD(ModalController, hideAll, void(entity, float)); + METHOD(ModalController, addItem, void(entity, entity, vector, vector, float)); + METHOD(ModalController, addTab, void(entity, entity, entity)); - METHOD(ModalController, initializeDialog, void(entity, entity)) + METHOD(ModalController, initializeDialog, void(entity, entity)); - METHOD(ModalController, switchState, void(entity, entity, float, float)) + METHOD(ModalController, switchState, void(entity, entity, float, float)); ATTRIB(ModalController, origin, vector, '0 0 0') ATTRIB(ModalController, size, vector, '0 0 0') ATTRIB(ModalController, previousButton, entity, NULL) diff --git a/qcsrc/menu/item/nexposee.qc b/qcsrc/menu/item/nexposee.qc index 69d54b7a07..06616e68f5 100644 --- a/qcsrc/menu/item/nexposee.qc +++ b/qcsrc/menu/item/nexposee.qc @@ -2,26 +2,26 @@ #define ITEM_NEXPOSEE_H #include "container.qc" CLASS(Nexposee, Container) - METHOD(Nexposee, draw, void(entity)) - METHOD(Nexposee, keyDown, float(entity, float, float, float)) - METHOD(Nexposee, keyUp, float(entity, float, float, float)) - METHOD(Nexposee, mousePress, float(entity, vector)) - METHOD(Nexposee, mouseMove, float(entity, vector)) - METHOD(Nexposee, mouseRelease, float(entity, vector)) - METHOD(Nexposee, mouseDrag, float(entity, vector)) - METHOD(Nexposee, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(Nexposee, focusEnter, void(entity)) - METHOD(Nexposee, close, void(entity)) + METHOD(Nexposee, draw, void(entity)); + METHOD(Nexposee, keyDown, float(entity, float, float, float)); + METHOD(Nexposee, keyUp, float(entity, float, float, float)); + METHOD(Nexposee, mousePress, float(entity, vector)); + METHOD(Nexposee, mouseMove, float(entity, vector)); + METHOD(Nexposee, mouseRelease, float(entity, vector)); + METHOD(Nexposee, mouseDrag, float(entity, vector)); + METHOD(Nexposee, resizeNotify, void(entity, vector, vector, vector, vector)); + METHOD(Nexposee, focusEnter, void(entity)); + METHOD(Nexposee, close, void(entity)); ATTRIB(Nexposee, animationState, float, -1) ATTRIB(Nexposee, animationFactor, float, 0) ATTRIB(Nexposee, selectedChild, entity, NULL) ATTRIB(Nexposee, mouseFocusedChild, entity, NULL) - METHOD(Nexposee, addItem, void(entity, entity, vector, vector, float)) - METHOD(Nexposee, calc, void(entity)) - METHOD(Nexposee, setNexposee, void(entity, entity, vector, float, float)) + METHOD(Nexposee, addItem, void(entity, entity, vector, vector, float)); + METHOD(Nexposee, calc, void(entity)); + METHOD(Nexposee, setNexposee, void(entity, entity, vector, float, float)); ATTRIB(Nexposee, mousePosition, vector, '0 0 0') - METHOD(Nexposee, pullNexposee, void(entity, entity, vector)) + METHOD(Nexposee, pullNexposee, void(entity, entity, vector)); ENDCLASS(Nexposee) void ExposeeCloseButton_Click(entity button, entity other); // un-exposees the current state diff --git a/qcsrc/menu/item/radiobutton.qc b/qcsrc/menu/item/radiobutton.qc index c1e034855a..4dfadd2d56 100644 --- a/qcsrc/menu/item/radiobutton.qc +++ b/qcsrc/menu/item/radiobutton.qc @@ -3,7 +3,7 @@ #include "checkbox.qc" void RadioButton_Click(entity me, entity other); CLASS(RadioButton, CheckBox) - METHOD(RadioButton, configureRadioButton, void(entity, string, float, string, float, float)) + METHOD(RadioButton, configureRadioButton, void(entity, string, float, string, float, float)); ATTRIB(RadioButton, checked, float, 0) ATTRIB(RadioButton, group, float, 0) ATTRIB(RadioButton, allowDeselect, float, 0) diff --git a/qcsrc/menu/item/slider.qc b/qcsrc/menu/item/slider.qc index e944a96aea..4654425431 100644 --- a/qcsrc/menu/item/slider.qc +++ b/qcsrc/menu/item/slider.qc @@ -4,20 +4,20 @@ #define ITEM_SLIDER_H #include "label.qc" CLASS(Slider, Label) - METHOD(Slider, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(Slider, configureSliderVisuals, void(entity, float, float, float, string)) - METHOD(Slider, configureSliderValues, void(entity, float, float, float, float, float, float)) - METHOD(Slider, draw, void(entity)) - METHOD(Slider, keyDown, float(entity, float, float, float)) - METHOD(Slider, keyUp, float(entity, float, float, float)) - METHOD(Slider, mousePress, float(entity, vector)) - METHOD(Slider, mouseDrag, float(entity, vector)) - METHOD(Slider, mouseRelease, float(entity, vector)) - METHOD(Slider, valueToText, string(entity, float)) - METHOD(Slider, toString, string(entity)) - METHOD(Slider, setValue, void(entity, float)) - METHOD(Slider, setSliderValue, void(entity, float)) - METHOD(Slider, showNotify, void(entity)) + METHOD(Slider, resizeNotify, void(entity, vector, vector, vector, vector)); + METHOD(Slider, configureSliderVisuals, void(entity, float, float, float, string)); + METHOD(Slider, configureSliderValues, void(entity, float, float, float, float, float, float)); + METHOD(Slider, draw, void(entity)); + METHOD(Slider, keyDown, float(entity, float, float, float)); + METHOD(Slider, keyUp, float(entity, float, float, float)); + METHOD(Slider, mousePress, float(entity, vector)); + METHOD(Slider, mouseDrag, float(entity, vector)); + METHOD(Slider, mouseRelease, float(entity, vector)); + METHOD(Slider, valueToText, string(entity, float)); + METHOD(Slider, toString, string(entity)); + METHOD(Slider, setValue, void(entity, float)); + METHOD(Slider, setSliderValue, void(entity, float)); + METHOD(Slider, showNotify, void(entity)); ATTRIB(Slider, src, string, string_null) ATTRIB(Slider, focusable, float, 1) ATTRIB(Slider, allowFocusSound, float, 1) diff --git a/qcsrc/menu/item/textslider.qc b/qcsrc/menu/item/textslider.qc index f22e632d6f..733b1d6125 100644 --- a/qcsrc/menu/item/textslider.qc +++ b/qcsrc/menu/item/textslider.qc @@ -4,14 +4,14 @@ #define ITEM_TEXTSLIDER_H #include "slider.qc" CLASS(TextSlider, Slider) - METHOD(TextSlider, valueToText, string(entity, float)) - METHOD(TextSlider, valueToIdentifier, string(entity, float)) - METHOD(TextSlider, setValueFromIdentifier, void(entity, string)) - METHOD(TextSlider, getIdentifier, string(entity)) - METHOD(TextSlider, clearValues, void(entity)) - METHOD(TextSlider, addValue, void(entity, string, string)) - METHOD(TextSlider, insertValue, void(entity, float, string, string)) - METHOD(TextSlider, configureTextSliderValues, void(entity, string)) + METHOD(TextSlider, valueToText, string(entity, float)); + METHOD(TextSlider, valueToIdentifier, string(entity, float)); + METHOD(TextSlider, setValueFromIdentifier, void(entity, string)); + METHOD(TextSlider, getIdentifier, string(entity)); + METHOD(TextSlider, clearValues, void(entity)); + METHOD(TextSlider, addValue, void(entity, string, string)); + METHOD(TextSlider, insertValue, void(entity, float, string, string)); + METHOD(TextSlider, configureTextSliderValues, void(entity, string)); ATTRIBARRAY(TextSlider, valueStrings, string, 256) ATTRIBARRAY(TextSlider, valueIdentifiers, string, 256) ATTRIB(TextSlider, nValues, int, 0) diff --git a/qcsrc/menu/progs.src b/qcsrc/menu/progs.src index 64f12478dd..2bde451f8d 100644 --- a/qcsrc/menu/progs.src +++ b/qcsrc/menu/progs.src @@ -23,10 +23,9 @@ xonotic/util.qc ../common/util.qc ../common/items/all.qc - ../common/monsters/all.qc - -../common/weapons/all.qc // TODO +../common/vehicles/all.qc +../common/weapons/all.qc ../warpzonelib/mathlib.qc diff --git a/qcsrc/menu/xonotic/bigbutton.qc b/qcsrc/menu/xonotic/bigbutton.qc index 07b6a074ce..4f0acc6814 100644 --- a/qcsrc/menu/xonotic/bigbutton.qc +++ b/qcsrc/menu/xonotic/bigbutton.qc @@ -2,7 +2,7 @@ #define BIGBUTTON_H #include "button.qc" CLASS(XonoticBigButton, XonoticButton) - METHOD(XonoticBigButton, configureXonoticBigButton, void(entity, string, vector)) + METHOD(XonoticBigButton, configureXonoticBigButton, void(entity, string, vector)); ATTRIB(XonoticBigButton, image, string, SKINGFX_BUTTON_BIG) ATTRIB(XonoticBigButton, grayImage, string, SKINGFX_BUTTON_BIG_GRAY) ENDCLASS(XonoticBigButton) diff --git a/qcsrc/menu/xonotic/bigcommandbutton.qc b/qcsrc/menu/xonotic/bigcommandbutton.qc index 6798d9b01b..53067dde8b 100644 --- a/qcsrc/menu/xonotic/bigcommandbutton.qc +++ b/qcsrc/menu/xonotic/bigcommandbutton.qc @@ -2,7 +2,7 @@ #define BIGCOMMANDBUTTON_H #include "commandbutton.qc" CLASS(XonoticBigCommandButton, XonoticCommandButton) - METHOD(XonoticBigCommandButton, configureXonoticBigCommandButton, void(entity, string, vector, string, float)) + METHOD(XonoticBigCommandButton, configureXonoticBigCommandButton, void(entity, string, vector, string, float)); ATTRIB(XonoticBigCommandButton, image, string, SKINGFX_BUTTON_BIG) ATTRIB(XonoticBigCommandButton, grayImage, string, SKINGFX_BUTTON_BIG_GRAY) ENDCLASS(XonoticBigCommandButton) diff --git a/qcsrc/menu/xonotic/button.qc b/qcsrc/menu/xonotic/button.qc index 73518ef96a..fb0f416e96 100644 --- a/qcsrc/menu/xonotic/button.qc +++ b/qcsrc/menu/xonotic/button.qc @@ -2,7 +2,7 @@ #define BUTTON_H #include "../item/button.qc" CLASS(XonoticButton, Button) - METHOD(XonoticButton, configureXonoticButton, void(entity, string, vector)) + METHOD(XonoticButton, configureXonoticButton, void(entity, string, vector)); ATTRIB(XonoticButton, fontSize, float, SKINFONTSIZE_NORMAL) ATTRIB(XonoticButton, image, string, SKINGFX_BUTTON) ATTRIB(XonoticButton, grayImage, string, SKINGFX_BUTTON_GRAY) diff --git a/qcsrc/menu/xonotic/campaign.qc b/qcsrc/menu/xonotic/campaign.qc index 2387735165..a539d0f6fa 100644 --- a/qcsrc/menu/xonotic/campaign.qc +++ b/qcsrc/menu/xonotic/campaign.qc @@ -4,16 +4,16 @@ #define CAMPAIGN_H #include "listbox.qc" CLASS(XonoticCampaignList, XonoticListBox) - METHOD(XonoticCampaignList, configureXonoticCampaignList, void(entity)) + METHOD(XonoticCampaignList, configureXonoticCampaignList, void(entity)); ATTRIB(XonoticCampaignList, rowsPerItem, float, 10) - METHOD(XonoticCampaignList, draw, void(entity)) - METHOD(XonoticCampaignList, drawListBoxItem, void(entity, int, vector, bool, bool)) - METHOD(XonoticCampaignList, doubleClickListBoxItem, void(entity, float, vector)) - METHOD(XonoticCampaignList, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(XonoticCampaignList, setSelected, void(entity, float)) - METHOD(XonoticCampaignList, keyDown, float(entity, float, float, float)) - METHOD(XonoticCampaignList, campaignGo, void(entity, float)) - METHOD(XonoticCampaignList, destroy, void(entity)) + METHOD(XonoticCampaignList, draw, void(entity)); + METHOD(XonoticCampaignList, drawListBoxItem, void(entity, int, vector, bool, bool)); + METHOD(XonoticCampaignList, doubleClickListBoxItem, void(entity, float, vector)); + METHOD(XonoticCampaignList, resizeNotify, void(entity, vector, vector, vector, vector)); + METHOD(XonoticCampaignList, setSelected, void(entity, float)); + METHOD(XonoticCampaignList, keyDown, float(entity, float, float, float)); + METHOD(XonoticCampaignList, campaignGo, void(entity, float)); + METHOD(XonoticCampaignList, destroy, void(entity)); ATTRIB(XonoticCampaignList, campaignGlob, float, 0) ATTRIB(XonoticCampaignList, realFontSize, vector, '0 0 0') @@ -34,8 +34,8 @@ CLASS(XonoticCampaignList, XonoticListBox) ATTRIB(XonoticCampaignList, campaignIndex, float, 0) ATTRIB(XonoticCampaignList, cvarName, string, string_null) - METHOD(XonoticCampaignList, loadCvars, void(entity)) - METHOD(XonoticCampaignList, saveCvars, void(entity)) + METHOD(XonoticCampaignList, loadCvars, void(entity)); + METHOD(XonoticCampaignList, saveCvars, void(entity)); ATTRIB(XonoticCampaignList, buttonNext, entity, NULL) ATTRIB(XonoticCampaignList, buttonPrev, entity, NULL) diff --git a/qcsrc/menu/xonotic/charmap.qc b/qcsrc/menu/xonotic/charmap.qc index 747d1f03b4..1b0881dc56 100644 --- a/qcsrc/menu/xonotic/charmap.qc +++ b/qcsrc/menu/xonotic/charmap.qc @@ -2,20 +2,20 @@ #define CHARMAP_H #include "picker.qc" CLASS(XonoticCharmap, XonoticPicker) - METHOD(XonoticCharmap, configureXonoticCharmap, void(entity, entity)) - METHOD(XonoticCharmap, focusLeave, void(entity)) - METHOD(XonoticCharmap, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(XonoticCharmap, keyDown, float(entity, float, float, float)) + METHOD(XonoticCharmap, configureXonoticCharmap, void(entity, entity)); + METHOD(XonoticCharmap, focusLeave, void(entity)); + METHOD(XonoticCharmap, resizeNotify, void(entity, vector, vector, vector, vector)); + METHOD(XonoticCharmap, keyDown, float(entity, float, float, float)); ATTRIB(XonoticCharmap, inputBox, entity, NULL) ATTRIB(XonoticCharmap, realFontSize, vector, '0 0 0') ATTRIB(XonoticCharmap, rows, float, 10) ATTRIB(XonoticCharmap, columns, float, 14) - METHOD(XonoticCharmap, cellSelect, void(entity, vector)) - METHOD(XonoticCharmap, cellIsValid, bool(entity, vector)) - METHOD(XonoticCharmap, cellDraw, void(entity, vector, vector)) - METHOD(XonoticCharmap, charOffset, vector) + METHOD(XonoticCharmap, cellSelect, void(entity, vector)); + METHOD(XonoticCharmap, cellIsValid, bool(entity, vector)); + METHOD(XonoticCharmap, cellDraw, void(entity, vector, vector)); + ATTRIB(XonoticCharmap, charOffset, vector, '0 0 0') ENDCLASS(XonoticCharmap) entity makeXonoticCharmap(entity controlledInputBox); #endif diff --git a/qcsrc/menu/xonotic/checkbox.qc b/qcsrc/menu/xonotic/checkbox.qc index 65db0f5a73..18ac036ae5 100644 --- a/qcsrc/menu/xonotic/checkbox.qc +++ b/qcsrc/menu/xonotic/checkbox.qc @@ -2,8 +2,8 @@ #define CHECKBOX_H #include "../item/checkbox.qc" CLASS(XonoticCheckBox, CheckBox) - METHOD(XonoticCheckBox, configureXonoticCheckBox, void(entity, float, float, string, string)) - METHOD(XonoticCheckBox, setChecked, void(entity, float)) + METHOD(XonoticCheckBox, configureXonoticCheckBox, void(entity, float, float, string, string)); + METHOD(XonoticCheckBox, setChecked, void(entity, float)); ATTRIB(XonoticCheckBox, fontSize, float, SKINFONTSIZE_NORMAL) ATTRIB(XonoticCheckBox, image, string, SKINGFX_CHECKBOX) ATTRIB(XonoticCheckBox, yesValue, float, 1) @@ -15,8 +15,8 @@ CLASS(XonoticCheckBox, CheckBox) ATTRIB(XonoticCheckBox, colorD, vector, SKINCOLOR_CHECKBOX_D) ATTRIB(XonoticCheckBox, cvarName, string, string_null) - METHOD(XonoticCheckBox, loadCvars, void(entity)) - METHOD(XonoticCheckBox, saveCvars, void(entity)) + METHOD(XonoticCheckBox, loadCvars, void(entity)); + METHOD(XonoticCheckBox, saveCvars, void(entity)); ATTRIB(XonoticCheckBox, sendCvars, float, 0) ATTRIB(XonoticCheckBox, alpha, float, SKINALPHA_TEXT) diff --git a/qcsrc/menu/xonotic/checkbox_slider_invalid.qc b/qcsrc/menu/xonotic/checkbox_slider_invalid.qc index 9cce51d828..e3ade5b26d 100644 --- a/qcsrc/menu/xonotic/checkbox_slider_invalid.qc +++ b/qcsrc/menu/xonotic/checkbox_slider_invalid.qc @@ -2,9 +2,9 @@ #define CHECKBOX_SLIDER_INVALID_H #include "../item/checkbox.qc" CLASS(XonoticSliderCheckBox, CheckBox) - METHOD(XonoticSliderCheckBox, configureXonoticSliderCheckBox, void(entity, float, float, entity, string)) - METHOD(XonoticSliderCheckBox, setChecked, void(entity, float)) - METHOD(XonoticSliderCheckBox, draw, void(entity)) + METHOD(XonoticSliderCheckBox, configureXonoticSliderCheckBox, void(entity, float, float, entity, string)); + METHOD(XonoticSliderCheckBox, setChecked, void(entity, float)); + METHOD(XonoticSliderCheckBox, draw, void(entity)); ATTRIB(XonoticSliderCheckBox, fontSize, float, SKINFONTSIZE_NORMAL) ATTRIB(XonoticSliderCheckBox, image, string, SKINGFX_CHECKBOX) diff --git a/qcsrc/menu/xonotic/checkbox_string.qc b/qcsrc/menu/xonotic/checkbox_string.qc index 2efa1a102b..4b5b17f0e1 100644 --- a/qcsrc/menu/xonotic/checkbox_string.qc +++ b/qcsrc/menu/xonotic/checkbox_string.qc @@ -2,8 +2,8 @@ #define CHECKBOX_STRING_H #include "../item/checkbox.qc" CLASS(XonoticCheckBoxString, CheckBox) - METHOD(XonoticCheckBoxString, configureXonoticCheckBoxString, void(entity, string, string, string, string)) - METHOD(XonoticCheckBoxString, setChecked, void(entity, float)) + METHOD(XonoticCheckBoxString, configureXonoticCheckBoxString, void(entity, string, string, string, string)); + METHOD(XonoticCheckBoxString, setChecked, void(entity, float)); ATTRIB(XonoticCheckBoxString, fontSize, float, SKINFONTSIZE_NORMAL) ATTRIB(XonoticCheckBoxString, image, string, SKINGFX_CHECKBOX) ATTRIB(XonoticCheckBoxString, yesString, string, string_null) @@ -15,8 +15,8 @@ CLASS(XonoticCheckBoxString, CheckBox) ATTRIB(XonoticCheckBoxString, colorD, vector, SKINCOLOR_CHECKBOX_D) ATTRIB(XonoticCheckBoxString, cvarName, string, string_null) - METHOD(XonoticCheckBoxString, loadCvars, void(entity)) - METHOD(XonoticCheckBoxString, saveCvars, void(entity)) + METHOD(XonoticCheckBoxString, loadCvars, void(entity)); + METHOD(XonoticCheckBoxString, saveCvars, void(entity)); ATTRIB(XonoticCheckBoxString, sendCvars, float, 0) ATTRIB(XonoticCheckBoxString, alpha, float, SKINALPHA_TEXT) diff --git a/qcsrc/menu/xonotic/colorbutton.qc b/qcsrc/menu/xonotic/colorbutton.qc index 950661d73d..4efa4a2bda 100644 --- a/qcsrc/menu/xonotic/colorbutton.qc +++ b/qcsrc/menu/xonotic/colorbutton.qc @@ -2,9 +2,9 @@ #define COLORBUTTON_H #include "../item/radiobutton.qc" CLASS(XonoticColorButton, RadioButton) - METHOD(XonoticColorButton, configureXonoticColorButton, void(entity, float, float, float)) - METHOD(XonoticColorButton, setChecked, void(entity, float)) - METHOD(XonoticColorButton, draw, void(entity)) + METHOD(XonoticColorButton, configureXonoticColorButton, void(entity, float, float, float)); + METHOD(XonoticColorButton, setChecked, void(entity, float)); + METHOD(XonoticColorButton, draw, void(entity)); ATTRIB(XonoticColorButton, fontSize, float, 0) ATTRIB(XonoticColorButton, image, string, SKINGFX_COLORBUTTON) @@ -13,8 +13,8 @@ CLASS(XonoticColorButton, RadioButton) ATTRIB(XonoticColorButton, cvarPart, float, 0) ATTRIB(XonoticColorButton, cvarName, string, string_null) ATTRIB(XonoticColorButton, cvarValueFloat, float, 0) - METHOD(XonoticColorButton, loadCvars, void(entity)) - METHOD(XonoticColorButton, saveCvars, void(entity)) + METHOD(XonoticColorButton, loadCvars, void(entity)); + METHOD(XonoticColorButton, saveCvars, void(entity)); ENDCLASS(XonoticColorButton) entity makeXonoticColorButton(float, float, float); #endif diff --git a/qcsrc/menu/xonotic/colorpicker.qc b/qcsrc/menu/xonotic/colorpicker.qc index 450c5fb29e..f7d72439db 100644 --- a/qcsrc/menu/xonotic/colorpicker.qc +++ b/qcsrc/menu/xonotic/colorpicker.qc @@ -2,17 +2,17 @@ #define COLORPICKER_H #include "../item/image.qc" CLASS(XonoticColorpicker, Image) - METHOD(XonoticColorpicker, configureXonoticColorpicker, void(entity, entity)) - METHOD(XonoticColorpicker, mousePress, float(entity, vector)) - METHOD(XonoticColorpicker, mouseRelease, float(entity, vector)) - METHOD(XonoticColorpicker, mouseDrag, float(entity, vector)) + METHOD(XonoticColorpicker, configureXonoticColorpicker, void(entity, entity)); + METHOD(XonoticColorpicker, mousePress, float(entity, vector)); + METHOD(XonoticColorpicker, mouseRelease, float(entity, vector)); + METHOD(XonoticColorpicker, mouseDrag, float(entity, vector)); ATTRIB(XonoticColorpicker, controlledTextbox, entity, NULL) ATTRIB(XonoticColorpicker, image, string, SKINGFX_COLORPICKER) ATTRIB(XonoticColorpicker, imagemargin, vector, SKINMARGIN_COLORPICKER) ATTRIB(XonoticColorpicker, focusable, float, 1) - METHOD(XonoticColorpicker, focusLeave, void(entity)) - METHOD(XonoticColorpicker, keyDown, float(entity, float, float, float)) - METHOD(XonoticColorpicker, draw, void(entity)) + METHOD(XonoticColorpicker, focusLeave, void(entity)); + METHOD(XonoticColorpicker, keyDown, float(entity, float, float, float)); + METHOD(XonoticColorpicker, draw, void(entity)); ENDCLASS(XonoticColorpicker) entity makeXonoticColorpicker(entity theTextbox); #endif diff --git a/qcsrc/menu/xonotic/colorpicker_string.qc b/qcsrc/menu/xonotic/colorpicker_string.qc index 0695f057ea..6a126dc9fd 100644 --- a/qcsrc/menu/xonotic/colorpicker_string.qc +++ b/qcsrc/menu/xonotic/colorpicker_string.qc @@ -2,18 +2,18 @@ #define COLORPICKER_STRING_H #include "../item/image.qc" CLASS(XonoticColorpickerString, Image) - METHOD(XonoticColorpickerString, configureXonoticColorpickerString, void(entity, string, string)) - METHOD(XonoticColorpickerString, mousePress, float(entity, vector)) - METHOD(XonoticColorpickerString, mouseRelease, float(entity, vector)) - METHOD(XonoticColorpickerString, mouseDrag, float(entity, vector)) + METHOD(XonoticColorpickerString, configureXonoticColorpickerString, void(entity, string, string)); + METHOD(XonoticColorpickerString, mousePress, float(entity, vector)); + METHOD(XonoticColorpickerString, mouseRelease, float(entity, vector)); + METHOD(XonoticColorpickerString, mouseDrag, float(entity, vector)); ATTRIB(XonoticColorpickerString, cvarName, string, string_null) - METHOD(XonoticColorpickerString, loadCvars, void(entity)) - METHOD(XonoticColorpickerString, saveCvars, void(entity)) + METHOD(XonoticColorpickerString, loadCvars, void(entity)); + METHOD(XonoticColorpickerString, saveCvars, void(entity)); ATTRIB(XonoticColorpickerString, prevcoords, vector, '0 0 0') ATTRIB(XonoticColorpickerString, image, string, SKINGFX_COLORPICKER) ATTRIB(XonoticColorpickerString, imagemargin, vector, SKINMARGIN_COLORPICKER) ATTRIB(XonoticColorpickerString, focusable, float, 1) - METHOD(XonoticColorpickerString, draw, void(entity)) + METHOD(XonoticColorpickerString, draw, void(entity)); ATTRIB(XonoticColorpickerString, disabledAlpha, float, 0.3) ENDCLASS(XonoticColorpickerString) entity makeXonoticColorpickerString(string theCvar, string theDefaultCvar); diff --git a/qcsrc/menu/xonotic/commandbutton.qc b/qcsrc/menu/xonotic/commandbutton.qc index afea74cb47..db1ec61ef2 100644 --- a/qcsrc/menu/xonotic/commandbutton.qc +++ b/qcsrc/menu/xonotic/commandbutton.qc @@ -8,7 +8,7 @@ #define COMMANDBUTTON_H #include "button.qc" CLASS(XonoticCommandButton, XonoticButton) - METHOD(XonoticCommandButton, configureXonoticCommandButton, void(entity, string, vector, string, float)) + METHOD(XonoticCommandButton, configureXonoticCommandButton, void(entity, string, vector, string, float)); ATTRIB(XonoticCommandButton, onClickCommand, string, string_null) ATTRIB(XonoticCommandButton, flags, float, 0) ENDCLASS(XonoticCommandButton) diff --git a/qcsrc/menu/xonotic/credits.qc b/qcsrc/menu/xonotic/credits.qc index e3bc1c3399..64fac23d27 100644 --- a/qcsrc/menu/xonotic/credits.qc +++ b/qcsrc/menu/xonotic/credits.qc @@ -2,13 +2,13 @@ #define CREDITS_H #include "listbox.qc" CLASS(XonoticCreditsList, XonoticListBox) - METHOD(XonoticCreditsList, configureXonoticCreditsList, void(entity)) + METHOD(XonoticCreditsList, configureXonoticCreditsList, void(entity)); ATTRIB(XonoticCreditsList, rowsPerItem, float, 1) - METHOD(XonoticCreditsList, draw, void(entity)) - METHOD(XonoticCreditsList, drawListBoxItem, void(entity, int, vector, bool, bool)) - METHOD(XonoticCreditsList, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(XonoticCreditsList, keyDown, float(entity, float, float, float)) - METHOD(XonoticCreditsList, destroy, void(entity)) + METHOD(XonoticCreditsList, draw, void(entity)); + METHOD(XonoticCreditsList, drawListBoxItem, void(entity, int, vector, bool, bool)); + METHOD(XonoticCreditsList, resizeNotify, void(entity, vector, vector, vector, vector)); + METHOD(XonoticCreditsList, keyDown, float(entity, float, float, float)); + METHOD(XonoticCreditsList, destroy, void(entity)); ATTRIB(XonoticCreditsList, selectionDoesntMatter, bool, true) ATTRIB(XonoticCreditsList, realFontSize, vector, '0 0 0') diff --git a/qcsrc/menu/xonotic/crosshairpicker.qc b/qcsrc/menu/xonotic/crosshairpicker.qc index 8922e7fbf4..0ac826a440 100644 --- a/qcsrc/menu/xonotic/crosshairpicker.qc +++ b/qcsrc/menu/xonotic/crosshairpicker.qc @@ -2,14 +2,14 @@ #define CROSSHAIRPICKER_H #include "picker.qc" CLASS(XonoticCrosshairPicker, XonoticPicker) - METHOD(XonoticCrosshairPicker, configureXonoticCrosshairPicker, void(entity)) + METHOD(XonoticCrosshairPicker, configureXonoticCrosshairPicker, void(entity)); ATTRIB(XonoticCrosshairPicker, rows, float, 3) ATTRIB(XonoticCrosshairPicker, columns, float, 12) - METHOD(XonoticCrosshairPicker, cellSelect, void(entity, vector)) - METHOD(XonoticCrosshairPicker, cellIsValid, bool(entity, vector)) - METHOD(XonoticCrosshairPicker, cellDraw, void(entity, vector, vector)) + METHOD(XonoticCrosshairPicker, cellSelect, void(entity, vector)); + METHOD(XonoticCrosshairPicker, cellIsValid, bool(entity, vector)); + METHOD(XonoticCrosshairPicker, cellDraw, void(entity, vector, vector)); ENDCLASS(XonoticCrosshairPicker) entity makeXonoticCrosshairPicker(); #endif diff --git a/qcsrc/menu/xonotic/crosshairpreview.qc b/qcsrc/menu/xonotic/crosshairpreview.qc index f8de857982..90694ca8c3 100644 --- a/qcsrc/menu/xonotic/crosshairpreview.qc +++ b/qcsrc/menu/xonotic/crosshairpreview.qc @@ -2,8 +2,8 @@ #define CROSSHAIRPREVIEW_H #include "../item.qc" CLASS(XonoticCrosshairPreview, Item) - METHOD(XonoticCrosshairPreview, configureXonoticCrosshairPreview, void(entity)) - METHOD(XonoticCrosshairPreview, draw, void(entity)) + METHOD(XonoticCrosshairPreview, configureXonoticCrosshairPreview, void(entity)); + METHOD(XonoticCrosshairPreview, draw, void(entity)); ATTRIB(XonoticCrosshairPreview, src, string, string_null) ATTRIB(XonoticCrosshairPreview, src2, string, string_null) ATTRIB(XonoticCrosshairPreview, disabled, float, 0) diff --git a/qcsrc/menu/xonotic/cvarlist.qc b/qcsrc/menu/xonotic/cvarlist.qc index 9a95ed1639..9943731f7b 100644 --- a/qcsrc/menu/xonotic/cvarlist.qc +++ b/qcsrc/menu/xonotic/cvarlist.qc @@ -2,13 +2,13 @@ #define CVARLIST_H #include "listbox.qc" CLASS(XonoticCvarList, XonoticListBox) - METHOD(XonoticCvarList, configureXonoticCvarList, void(entity)) + METHOD(XonoticCvarList, configureXonoticCvarList, void(entity)); ATTRIB(XonoticCvarList, rowsPerItem, float, 1) - METHOD(XonoticCvarList, drawListBoxItem, void(entity, int, vector, bool, bool)) - METHOD(XonoticCvarList, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(XonoticCvarList, keyDown, float(entity, float, float, float)) + METHOD(XonoticCvarList, drawListBoxItem, void(entity, int, vector, bool, bool)); + METHOD(XonoticCvarList, resizeNotify, void(entity, vector, vector, vector, vector)); + METHOD(XonoticCvarList, keyDown, float(entity, float, float, float)); - METHOD(XonoticCvarList, destroy, void(entity)) + METHOD(XonoticCvarList, destroy, void(entity)); ATTRIB(XonoticCvarList, realFontSize, vector, '0 0 0') ATTRIB(XonoticCvarList, realUpperMargin, float, 0) @@ -17,9 +17,9 @@ CLASS(XonoticCvarList, XonoticListBox) ATTRIB(XonoticCvarList, columnValueOrigin, float, 0) ATTRIB(XonoticCvarList, columnValueSize, float, 0) - METHOD(XonoticCvarList, mouseRelease, float(entity, vector)) - METHOD(XonoticCvarList, setSelected, void(entity, float)) - METHOD(XonoticCvarList, updateCvarType, float(entity)) + METHOD(XonoticCvarList, mouseRelease, float(entity, vector)); + METHOD(XonoticCvarList, setSelected, void(entity, float)); + METHOD(XonoticCvarList, updateCvarType, float(entity)); ATTRIB(XonoticCvarList, controlledTextbox, entity, NULL) ATTRIB(XonoticCvarList, cvarNameBox, entity, NULL) diff --git a/qcsrc/menu/xonotic/demolist.qc b/qcsrc/menu/xonotic/demolist.qc index f46ee407b6..2459d7ca1e 100644 --- a/qcsrc/menu/xonotic/demolist.qc +++ b/qcsrc/menu/xonotic/demolist.qc @@ -2,18 +2,18 @@ #define DEMOLIST_H #include "listbox.qc" CLASS(XonoticDemoList, XonoticListBox) - METHOD(XonoticDemoList, configureXonoticDemoList, void(entity)) + METHOD(XonoticDemoList, configureXonoticDemoList, void(entity)); ATTRIB(XonoticDemoList, rowsPerItem, float, 1) - METHOD(XonoticDemoList, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(XonoticDemoList, drawListBoxItem, void(entity, int, vector, bool, bool)) - METHOD(XonoticDemoList, getDemos, void(entity)) - METHOD(XonoticDemoList, startDemo, void(entity)) - METHOD(XonoticDemoList, timeDemo, void(entity)) - METHOD(XonoticDemoList, demoName, string(entity, float)) - METHOD(XonoticDemoList, doubleClickListBoxItem, void(entity, float, vector)) - METHOD(XonoticDemoList, keyDown, float(entity, float, float, float)) - METHOD(XonoticDemoList, destroy, void(entity)) - METHOD(XonoticDemoList, showNotify, void(entity)) + METHOD(XonoticDemoList, resizeNotify, void(entity, vector, vector, vector, vector)); + METHOD(XonoticDemoList, drawListBoxItem, void(entity, int, vector, bool, bool)); + METHOD(XonoticDemoList, getDemos, void(entity)); + METHOD(XonoticDemoList, startDemo, void(entity)); + METHOD(XonoticDemoList, timeDemo, void(entity)); + METHOD(XonoticDemoList, demoName, string(entity, float)); + METHOD(XonoticDemoList, doubleClickListBoxItem, void(entity, float, vector)); + METHOD(XonoticDemoList, keyDown, float(entity, float, float, float)); + METHOD(XonoticDemoList, destroy, void(entity)); + METHOD(XonoticDemoList, showNotify, void(entity)); ATTRIB(XonoticDemoList, listDemo, float, -1) ATTRIB(XonoticDemoList, realFontSize, vector, '0 0 0') diff --git a/qcsrc/menu/xonotic/dialog.qc b/qcsrc/menu/xonotic/dialog.qc index c1ea16c6b7..7c23b4c97b 100644 --- a/qcsrc/menu/xonotic/dialog.qc +++ b/qcsrc/menu/xonotic/dialog.qc @@ -29,7 +29,7 @@ CLASS(XonoticDialog, Dialog) ATTRIB(XonoticDialog, alpha, float, SKINALPHA_TEXT) - METHOD(XonoticDialog, configureDialog, void(entity)) + METHOD(XonoticDialog, configureDialog, void(entity)); ENDCLASS(XonoticDialog) #ifndef IMPLEMENTATION entity currentDialog; diff --git a/qcsrc/menu/xonotic/dialog_credits.qc b/qcsrc/menu/xonotic/dialog_credits.qc index a996626630..6cf608fd4d 100644 --- a/qcsrc/menu/xonotic/dialog_credits.qc +++ b/qcsrc/menu/xonotic/dialog_credits.qc @@ -2,8 +2,8 @@ #define DIALOG_CREDITS_H #include "dialog.qc" CLASS(XonoticCreditsDialog, XonoticDialog) - METHOD(XonoticCreditsDialog, fill, void(entity)) - METHOD(XonoticCreditsDialog, focusEnter, void(entity)) + METHOD(XonoticCreditsDialog, fill, void(entity)); + METHOD(XonoticCreditsDialog, focusEnter, void(entity)); ATTRIB(XonoticCreditsDialog, title, string, _("Credits")) ATTRIB(XonoticCreditsDialog, color, vector, SKINCOLOR_DIALOG_CREDITS) ATTRIB(XonoticCreditsDialog, intendedWidth, float, SKINWIDTH_CREDITS) diff --git a/qcsrc/menu/xonotic/dialog_firstrun.qc b/qcsrc/menu/xonotic/dialog_firstrun.qc index 894a702d8a..19e243844b 100644 --- a/qcsrc/menu/xonotic/dialog_firstrun.qc +++ b/qcsrc/menu/xonotic/dialog_firstrun.qc @@ -2,7 +2,7 @@ #define DIALOG_FIRSTRUN_H #include "rootdialog.qc" CLASS(XonoticFirstRunDialog, XonoticRootDialog) - METHOD(XonoticFirstRunDialog, fill, void(entity)) // to be overridden by user to fill the dialog with controls + METHOD(XonoticFirstRunDialog, fill, void(entity)); // to be overridden by user to fill the dialog with controls ATTRIB(XonoticFirstRunDialog, title, string, _("Welcome")) ATTRIB(XonoticFirstRunDialog, color, vector, SKINCOLOR_DIALOG_FIRSTRUN) ATTRIB(XonoticFirstRunDialog, intendedWidth, float, 0.7) diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_ammo.qc b/qcsrc/menu/xonotic/dialog_hudpanel_ammo.qc index 9f14754bd3..dd54f14efc 100644 --- a/qcsrc/menu/xonotic/dialog_hudpanel_ammo.qc +++ b/qcsrc/menu/xonotic/dialog_hudpanel_ammo.qc @@ -2,7 +2,7 @@ #define DIALOG_HUDPANEL_AMMO_H #include "rootdialog.qc" CLASS(XonoticHUDAmmoDialog, XonoticRootDialog) - METHOD(XonoticHUDAmmoDialog, fill, void(entity)) + METHOD(XonoticHUDAmmoDialog, fill, void(entity)); ATTRIB(XonoticHUDAmmoDialog, title, string, _("Ammo Panel")) ATTRIB(XonoticHUDAmmoDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) ATTRIB(XonoticHUDAmmoDialog, intendedWidth, float, 0.4) diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qc b/qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qc index 7e74cdf5e8..c888fa7336 100644 --- a/qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qc +++ b/qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qc @@ -2,7 +2,7 @@ #define DIALOG_HUDPANEL_CENTERPRINT_H #include "rootdialog.qc" CLASS(XonoticHUDCenterprintDialog, XonoticRootDialog) - METHOD(XonoticHUDCenterprintDialog, fill, void(entity)) + METHOD(XonoticHUDCenterprintDialog, fill, void(entity)); ATTRIB(XonoticHUDCenterprintDialog, title, string, _("Centerprint Panel")) ATTRIB(XonoticHUDCenterprintDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) ATTRIB(XonoticHUDCenterprintDialog, intendedWidth, float, 0.4) diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_chat.qc b/qcsrc/menu/xonotic/dialog_hudpanel_chat.qc index c56c312efc..4c18f20665 100644 --- a/qcsrc/menu/xonotic/dialog_hudpanel_chat.qc +++ b/qcsrc/menu/xonotic/dialog_hudpanel_chat.qc @@ -2,7 +2,7 @@ #define DIALOG_HUDPANEL_CHAT_H #include "rootdialog.qc" CLASS(XonoticHUDChatDialog, XonoticRootDialog) - METHOD(XonoticHUDChatDialog, fill, void(entity)) + METHOD(XonoticHUDChatDialog, fill, void(entity)); ATTRIB(XonoticHUDChatDialog, title, string, _("Chat Panel")) ATTRIB(XonoticHUDChatDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) ATTRIB(XonoticHUDChatDialog, intendedWidth, float, 0.4) diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_engineinfo.qc b/qcsrc/menu/xonotic/dialog_hudpanel_engineinfo.qc index 0220ea2325..df9165e814 100644 --- a/qcsrc/menu/xonotic/dialog_hudpanel_engineinfo.qc +++ b/qcsrc/menu/xonotic/dialog_hudpanel_engineinfo.qc @@ -2,7 +2,7 @@ #define DIALOG_HUDPANEL_ENGINEINFO_H #include "rootdialog.qc" CLASS(XonoticHUDEngineInfoDialog, XonoticRootDialog) - METHOD(XonoticHUDEngineInfoDialog, fill, void(entity)) + METHOD(XonoticHUDEngineInfoDialog, fill, void(entity)); ATTRIB(XonoticHUDEngineInfoDialog, title, string, _("Engine Info Panel")) ATTRIB(XonoticHUDEngineInfoDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) ATTRIB(XonoticHUDEngineInfoDialog, intendedWidth, float, 0.4) diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc b/qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc index f0482bd73e..d576e23724 100644 --- a/qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc +++ b/qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc @@ -2,7 +2,7 @@ #define DIALOG_HUDPANEL_HEALTHARMOR_H #include "rootdialog.qc" CLASS(XonoticHUDHealthArmorDialog, XonoticRootDialog) - METHOD(XonoticHUDHealthArmorDialog, fill, void(entity)) + METHOD(XonoticHUDHealthArmorDialog, fill, void(entity)); ATTRIB(XonoticHUDHealthArmorDialog, title, string, _("Health/Armor Panel")) ATTRIB(XonoticHUDHealthArmorDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) ATTRIB(XonoticHUDHealthArmorDialog, intendedWidth, float, 0.4) diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_infomessages.qc b/qcsrc/menu/xonotic/dialog_hudpanel_infomessages.qc index 84625df73d..33b4ca9b7a 100644 --- a/qcsrc/menu/xonotic/dialog_hudpanel_infomessages.qc +++ b/qcsrc/menu/xonotic/dialog_hudpanel_infomessages.qc @@ -2,7 +2,7 @@ #define DIALOG_HUDPANEL_INFOMESSAGES_H #include "rootdialog.qc" CLASS(XonoticHUDInfoMessagesDialog, XonoticRootDialog) - METHOD(XonoticHUDInfoMessagesDialog, fill, void(entity)) + METHOD(XonoticHUDInfoMessagesDialog, fill, void(entity)); ATTRIB(XonoticHUDInfoMessagesDialog, title, string, _("Info Messages Panel")) ATTRIB(XonoticHUDInfoMessagesDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) ATTRIB(XonoticHUDInfoMessagesDialog, intendedWidth, float, 0.4) diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc b/qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc index 77f99dcc59..be5eef529d 100644 --- a/qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc +++ b/qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc @@ -2,7 +2,7 @@ #define DIALOG_HUDPANEL_ITEMSTIME_H #include "rootdialog.qc" CLASS(XonoticHUDItemsTimeDialog, XonoticRootDialog) - METHOD(XonoticHUDItemsTimeDialog, fill, void(entity)) + METHOD(XonoticHUDItemsTimeDialog, fill, void(entity)); ATTRIB(XonoticHUDItemsTimeDialog, title, string, _("Items Time Panel")) ATTRIB(XonoticHUDItemsTimeDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) ATTRIB(XonoticHUDItemsTimeDialog, intendedWidth, float, 0.4) diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_modicons.qc b/qcsrc/menu/xonotic/dialog_hudpanel_modicons.qc index 9737c54805..1fcefb72ff 100644 --- a/qcsrc/menu/xonotic/dialog_hudpanel_modicons.qc +++ b/qcsrc/menu/xonotic/dialog_hudpanel_modicons.qc @@ -2,7 +2,7 @@ #define DIALOG_HUDPANEL_MODICONS_H #include "rootdialog.qc" CLASS(XonoticHUDModIconsDialog, XonoticRootDialog) - METHOD(XonoticHUDModIconsDialog, fill, void(entity)) + METHOD(XonoticHUDModIconsDialog, fill, void(entity)); ATTRIB(XonoticHUDModIconsDialog, title, string, _("Mod Icons Panel")) ATTRIB(XonoticHUDModIconsDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) ATTRIB(XonoticHUDModIconsDialog, intendedWidth, float, 0.4) diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_notification.qc b/qcsrc/menu/xonotic/dialog_hudpanel_notification.qc index d0586710cf..93d58d0bbc 100644 --- a/qcsrc/menu/xonotic/dialog_hudpanel_notification.qc +++ b/qcsrc/menu/xonotic/dialog_hudpanel_notification.qc @@ -2,7 +2,7 @@ #define DIALOG_HUDPANEL_NOTIFICATION_H #include "rootdialog.qc" CLASS(XonoticHUDNotificationDialog, XonoticRootDialog) - METHOD(XonoticHUDNotificationDialog, fill, void(entity)) + METHOD(XonoticHUDNotificationDialog, fill, void(entity)); ATTRIB(XonoticHUDNotificationDialog, title, string, _("Notification Panel")) ATTRIB(XonoticHUDNotificationDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) ATTRIB(XonoticHUDNotificationDialog, intendedWidth, float, 0.4) diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_physics.qc b/qcsrc/menu/xonotic/dialog_hudpanel_physics.qc index 606f01aaab..394ab14bc9 100644 --- a/qcsrc/menu/xonotic/dialog_hudpanel_physics.qc +++ b/qcsrc/menu/xonotic/dialog_hudpanel_physics.qc @@ -2,7 +2,7 @@ #define DIALOG_HUDPANEL_PHYSICS_H #include "rootdialog.qc" CLASS(XonoticHUDPhysicsDialog, XonoticRootDialog) - METHOD(XonoticHUDPhysicsDialog, fill, void(entity)) + METHOD(XonoticHUDPhysicsDialog, fill, void(entity)); ATTRIB(XonoticHUDPhysicsDialog, title, string, _("Physics Panel")) ATTRIB(XonoticHUDPhysicsDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) ATTRIB(XonoticHUDPhysicsDialog, intendedWidth, float, 0.4) diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_powerups.qc b/qcsrc/menu/xonotic/dialog_hudpanel_powerups.qc index 0fdb35f49d..85abb0f02c 100644 --- a/qcsrc/menu/xonotic/dialog_hudpanel_powerups.qc +++ b/qcsrc/menu/xonotic/dialog_hudpanel_powerups.qc @@ -2,7 +2,7 @@ #define DIALOG_HUDPANEL_POWERUPS_H #include "rootdialog.qc" CLASS(XonoticHUDPowerupsDialog, XonoticRootDialog) - METHOD(XonoticHUDPowerupsDialog, fill, void(entity)) + METHOD(XonoticHUDPowerupsDialog, fill, void(entity)); ATTRIB(XonoticHUDPowerupsDialog, title, string, _("Powerups Panel")) ATTRIB(XonoticHUDPowerupsDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) ATTRIB(XonoticHUDPowerupsDialog, intendedWidth, float, 0.4) diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_pressedkeys.qc b/qcsrc/menu/xonotic/dialog_hudpanel_pressedkeys.qc index 4499d7c0f6..1de8e51c33 100644 --- a/qcsrc/menu/xonotic/dialog_hudpanel_pressedkeys.qc +++ b/qcsrc/menu/xonotic/dialog_hudpanel_pressedkeys.qc @@ -2,7 +2,7 @@ #define DIALOG_HUDPANEL_PRESSEDKEYS_H #include "rootdialog.qc" CLASS(XonoticHUDPressedKeysDialog, XonoticRootDialog) - METHOD(XonoticHUDPressedKeysDialog, fill, void(entity)) + METHOD(XonoticHUDPressedKeysDialog, fill, void(entity)); ATTRIB(XonoticHUDPressedKeysDialog, title, string, _("Pressed Keys Panel")) ATTRIB(XonoticHUDPressedKeysDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) ATTRIB(XonoticHUDPressedKeysDialog, intendedWidth, float, 0.4) diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_racetimer.qc b/qcsrc/menu/xonotic/dialog_hudpanel_racetimer.qc index 3333a0e641..79a56230df 100644 --- a/qcsrc/menu/xonotic/dialog_hudpanel_racetimer.qc +++ b/qcsrc/menu/xonotic/dialog_hudpanel_racetimer.qc @@ -2,7 +2,7 @@ #define DIALOG_HUDPANEL_RACETIMER_H #include "rootdialog.qc" CLASS(XonoticHUDRaceTimerDialog, XonoticRootDialog) - METHOD(XonoticHUDRaceTimerDialog, fill, void(entity)) + METHOD(XonoticHUDRaceTimerDialog, fill, void(entity)); ATTRIB(XonoticHUDRaceTimerDialog, title, string, _("Race Timer Panel")) ATTRIB(XonoticHUDRaceTimerDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) ATTRIB(XonoticHUDRaceTimerDialog, intendedWidth, float, 0.4) diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_radar.qc b/qcsrc/menu/xonotic/dialog_hudpanel_radar.qc index 0d159b2766..b7efc4a39b 100644 --- a/qcsrc/menu/xonotic/dialog_hudpanel_radar.qc +++ b/qcsrc/menu/xonotic/dialog_hudpanel_radar.qc @@ -2,7 +2,7 @@ #define DIALOG_HUDPANEL_RADAR_H #include "rootdialog.qc" CLASS(XonoticHUDRadarDialog, XonoticRootDialog) - METHOD(XonoticHUDRadarDialog, fill, void(entity)) + METHOD(XonoticHUDRadarDialog, fill, void(entity)); ATTRIB(XonoticHUDRadarDialog, title, string, _("Radar Panel")) ATTRIB(XonoticHUDRadarDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) ATTRIB(XonoticHUDRadarDialog, intendedWidth, float, 0.4) diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_score.qc b/qcsrc/menu/xonotic/dialog_hudpanel_score.qc index 690fc3b109..6cbbe46183 100644 --- a/qcsrc/menu/xonotic/dialog_hudpanel_score.qc +++ b/qcsrc/menu/xonotic/dialog_hudpanel_score.qc @@ -2,7 +2,7 @@ #define DIALOG_HUDPANEL_SCORE_H #include "rootdialog.qc" CLASS(XonoticHUDScoreDialog, XonoticRootDialog) - METHOD(XonoticHUDScoreDialog, fill, void(entity)) + METHOD(XonoticHUDScoreDialog, fill, void(entity)); ATTRIB(XonoticHUDScoreDialog, title, string, _("Score Panel")) ATTRIB(XonoticHUDScoreDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) ATTRIB(XonoticHUDScoreDialog, intendedWidth, float, 0.4) diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_timer.qc b/qcsrc/menu/xonotic/dialog_hudpanel_timer.qc index d140dea222..ae071e02e1 100644 --- a/qcsrc/menu/xonotic/dialog_hudpanel_timer.qc +++ b/qcsrc/menu/xonotic/dialog_hudpanel_timer.qc @@ -2,7 +2,7 @@ #define DIALOG_HUDPANEL_TIMER_H #include "rootdialog.qc" CLASS(XonoticHUDTimerDialog, XonoticRootDialog) - METHOD(XonoticHUDTimerDialog, fill, void(entity)) + METHOD(XonoticHUDTimerDialog, fill, void(entity)); ATTRIB(XonoticHUDTimerDialog, title, string, _("Timer Panel")) ATTRIB(XonoticHUDTimerDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) ATTRIB(XonoticHUDTimerDialog, intendedWidth, float, 0.4) diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_vote.qc b/qcsrc/menu/xonotic/dialog_hudpanel_vote.qc index 62d439e33b..67eed0c8fa 100644 --- a/qcsrc/menu/xonotic/dialog_hudpanel_vote.qc +++ b/qcsrc/menu/xonotic/dialog_hudpanel_vote.qc @@ -2,7 +2,7 @@ #define DIALOG_HUDPANEL_VOTE_H #include "rootdialog.qc" CLASS(XonoticHUDVoteDialog, XonoticRootDialog) - METHOD(XonoticHUDVoteDialog, fill, void(entity)) + METHOD(XonoticHUDVoteDialog, fill, void(entity)); ATTRIB(XonoticHUDVoteDialog, title, string, _("Vote Panel")) ATTRIB(XonoticHUDVoteDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) ATTRIB(XonoticHUDVoteDialog, intendedWidth, float, 0.4) diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc b/qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc index a78effc6ed..a5fedbd3fd 100644 --- a/qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc +++ b/qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc @@ -2,7 +2,7 @@ #define DIALOG_HUDPANEL_WEAPONS_H #include "rootdialog.qc" CLASS(XonoticHUDWeaponsDialog, XonoticRootDialog) - METHOD(XonoticHUDWeaponsDialog, fill, void(entity)) + METHOD(XonoticHUDWeaponsDialog, fill, void(entity)); ATTRIB(XonoticHUDWeaponsDialog, title, string, _("Weapons Panel")) ATTRIB(XonoticHUDWeaponsDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) ATTRIB(XonoticHUDWeaponsDialog, intendedWidth, float, 0.4) diff --git a/qcsrc/menu/xonotic/dialog_hudsetup_exit.qc b/qcsrc/menu/xonotic/dialog_hudsetup_exit.qc index f8f6b9e6e4..b9d4c34b7e 100644 --- a/qcsrc/menu/xonotic/dialog_hudsetup_exit.qc +++ b/qcsrc/menu/xonotic/dialog_hudsetup_exit.qc @@ -2,7 +2,7 @@ #define DIALOG_HUDSETUP_EXIT_H #include "rootdialog.qc" CLASS(XonoticHUDExitDialog, XonoticRootDialog) - METHOD(XonoticHUDExitDialog, fill, void(entity)) + METHOD(XonoticHUDExitDialog, fill, void(entity)); ATTRIB(XonoticHUDExitDialog, title, string, _("Panel HUD Setup")) ATTRIB(XonoticHUDExitDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) ATTRIB(XonoticHUDExitDialog, intendedWidth, float, 0.4) diff --git a/qcsrc/menu/xonotic/dialog_monstertools.qc b/qcsrc/menu/xonotic/dialog_monstertools.qc index 14587e2a9f..6b95565074 100644 --- a/qcsrc/menu/xonotic/dialog_monstertools.qc +++ b/qcsrc/menu/xonotic/dialog_monstertools.qc @@ -2,7 +2,7 @@ #define DIALOG_MONSTERTOOLS_H #include "rootdialog.qc" CLASS(XonoticMonsterToolsDialog, XonoticRootDialog) - METHOD(XonoticMonsterToolsDialog, fill, void(entity)) // to be overridden by user to fill the dialog with controls + METHOD(XonoticMonsterToolsDialog, fill, void(entity)); // to be overridden by user to fill the dialog with controls ATTRIB(XonoticMonsterToolsDialog, title, string, _("Monster Tools")) ATTRIB(XonoticMonsterToolsDialog, color, vector, SKINCOLOR_DIALOG_SANDBOXTOOLS) ATTRIB(XonoticMonsterToolsDialog, intendedWidth, float, 0.8) diff --git a/qcsrc/menu/xonotic/dialog_multiplayer.qc b/qcsrc/menu/xonotic/dialog_multiplayer.qc index 64cfbd91dd..fb0b00fda0 100644 --- a/qcsrc/menu/xonotic/dialog_multiplayer.qc +++ b/qcsrc/menu/xonotic/dialog_multiplayer.qc @@ -2,7 +2,7 @@ #define DIALOG_MULTIPLAYER_H #include "dialog.qc" CLASS(XonoticMultiplayerDialog, XonoticDialog) - METHOD(XonoticMultiplayerDialog, fill, void(entity)) + METHOD(XonoticMultiplayerDialog, fill, void(entity)); ATTRIB(XonoticMultiplayerDialog, title, string, _("Multiplayer")) ATTRIB(XonoticMultiplayerDialog, color, vector, SKINCOLOR_DIALOG_MULTIPLAYER) ATTRIB(XonoticMultiplayerDialog, intendedWidth, float, 0.96) diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_create.qc b/qcsrc/menu/xonotic/dialog_multiplayer_create.qc index 5759bf0aea..5b7b5ef7ac 100644 --- a/qcsrc/menu/xonotic/dialog_multiplayer_create.qc +++ b/qcsrc/menu/xonotic/dialog_multiplayer_create.qc @@ -2,9 +2,9 @@ #define DIALOG_MULTIPLAYER_CREATE_H #include "tab.qc" CLASS(XonoticServerCreateTab, XonoticTab) - METHOD(XonoticServerCreateTab, fill, void(entity)) - METHOD(XonoticServerCreateTab, gameTypeChangeNotify, void(entity)) - METHOD(XonoticServerCreateTab, gameTypeSelectNotify, void(entity)) + METHOD(XonoticServerCreateTab, fill, void(entity)); + METHOD(XonoticServerCreateTab, gameTypeChangeNotify, void(entity)); + METHOD(XonoticServerCreateTab, gameTypeSelectNotify, void(entity)); ATTRIB(XonoticServerCreateTab, intendedWidth, float, 0.9) ATTRIB(XonoticServerCreateTab, rows, float, 23) ATTRIB(XonoticServerCreateTab, columns, float, 6.2) // added extra .2 for center space diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qc b/qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qc index 5254f5aa37..2a5c8245a9 100644 --- a/qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qc +++ b/qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qc @@ -2,8 +2,8 @@ #define DIALOG_MULTIPLAYER_CREATE_MAPINFO_H #include "dialog.qc" CLASS(XonoticMapInfoDialog, XonoticDialog) - METHOD(XonoticMapInfoDialog, fill, void(entity)) - METHOD(XonoticMapInfoDialog, loadMapInfo, void(entity, float, entity)) + METHOD(XonoticMapInfoDialog, fill, void(entity)); + METHOD(XonoticMapInfoDialog, loadMapInfo, void(entity, float, entity)); ATTRIB(XonoticMapInfoDialog, title, string, _("Map Information")) ATTRIB(XonoticMapInfoDialog, color, vector, SKINCOLOR_DIALOG_MAPINFO) ATTRIB(XonoticMapInfoDialog, intendedWidth, float, 1.0) diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc b/qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc index 8ab5296383..a1b299d9fc 100644 --- a/qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc +++ b/qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc @@ -4,10 +4,10 @@ #define DIALOG_MULTIPLAYER_CREATE_MUTATORS_H #include "dialog.qc" CLASS(XonoticMutatorsDialog, XonoticDialog) - METHOD(XonoticMutatorsDialog, toString, string(entity)) - METHOD(XonoticMutatorsDialog, fill, void(entity)) - METHOD(XonoticMutatorsDialog, showNotify, void(entity)) - METHOD(XonoticMutatorsDialog, close, void(entity)) + METHOD(XonoticMutatorsDialog, toString, string(entity)); + METHOD(XonoticMutatorsDialog, fill, void(entity)); + METHOD(XonoticMutatorsDialog, showNotify, void(entity)); + METHOD(XonoticMutatorsDialog, close, void(entity)); ATTRIB(XonoticMutatorsDialog, title, string, _("Mutators")) ATTRIB(XonoticMutatorsDialog, color, vector, SKINCOLOR_DIALOG_MUTATORS) ATTRIB(XonoticMutatorsDialog, intendedWidth, float, 0.9) diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_join.qc b/qcsrc/menu/xonotic/dialog_multiplayer_join.qc index a4e480e18a..86829871bd 100644 --- a/qcsrc/menu/xonotic/dialog_multiplayer_join.qc +++ b/qcsrc/menu/xonotic/dialog_multiplayer_join.qc @@ -2,7 +2,7 @@ #define DIALOG_MULTIPLAYER_JOIN_H #include "tab.qc" CLASS(XonoticServerListTab, XonoticTab) - METHOD(XonoticServerListTab, fill, void(entity)) + METHOD(XonoticServerListTab, fill, void(entity)); ATTRIB(XonoticServerListTab, intendedWidth, float, 0.9) ATTRIB(XonoticServerListTab, rows, float, 23) ATTRIB(XonoticServerListTab, columns, float, 6.5) diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc b/qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc index a5ad633205..62b85269d4 100644 --- a/qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc +++ b/qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc @@ -4,8 +4,8 @@ #define DIALOG_MULTIPLAYER_JOIN_SERVERINFO_H #include "dialog.qc" CLASS(XonoticServerInfoDialog, XonoticDialog) - METHOD(XonoticServerInfoDialog, fill, void(entity)) - METHOD(XonoticServerInfoDialog, loadServerInfo, void(entity, float)) + METHOD(XonoticServerInfoDialog, fill, void(entity)); + METHOD(XonoticServerInfoDialog, loadServerInfo, void(entity, float)); ATTRIB(XonoticServerInfoDialog, title, string, _("Server Information")) ATTRIB(XonoticServerInfoDialog, color, vector, SKINCOLOR_DIALOG_SERVERINFO) ATTRIB(XonoticServerInfoDialog, intendedWidth, float, 0.8) diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_media.qc b/qcsrc/menu/xonotic/dialog_multiplayer_media.qc index 03ffd0f36d..abecd1ed5b 100644 --- a/qcsrc/menu/xonotic/dialog_multiplayer_media.qc +++ b/qcsrc/menu/xonotic/dialog_multiplayer_media.qc @@ -2,7 +2,7 @@ #define DIALOG_MULTIPLAYER_MEDIA_H #include "tab.qc" CLASS(XonoticMediaTab, XonoticTab) - METHOD(XonoticMediaTab, fill, void(entity)) + METHOD(XonoticMediaTab, fill, void(entity)); ATTRIB(XonoticMediaTab, intendedWidth, float, 0.9) ATTRIB(XonoticMediaTab, rows, float, 23) ATTRIB(XonoticMediaTab, columns, float, 3) diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc b/qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc index 788aa5381b..6172174d5b 100644 --- a/qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc +++ b/qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc @@ -2,7 +2,7 @@ #define DIALOG_MULTIPLAYER_MEDIA_DEMO_H #include "tab.qc" CLASS(XonoticDemoBrowserTab, XonoticTab) - METHOD(XonoticDemoBrowserTab, fill, void(entity)) + METHOD(XonoticDemoBrowserTab, fill, void(entity)); ATTRIB(XonoticDemoBrowserTab, intendedWidth, float, 0.9) ATTRIB(XonoticDemoBrowserTab, rows, float, 21) ATTRIB(XonoticDemoBrowserTab, columns, float, 6.5) diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_media_demo_startconfirm.qc b/qcsrc/menu/xonotic/dialog_multiplayer_media_demo_startconfirm.qc index 8d410ca7de..dedd34356e 100644 --- a/qcsrc/menu/xonotic/dialog_multiplayer_media_demo_startconfirm.qc +++ b/qcsrc/menu/xonotic/dialog_multiplayer_media_demo_startconfirm.qc @@ -2,7 +2,7 @@ #define DIALOG_MULTIPLAYER_MEDIA_DEMO_STARTCONFIRM_H #include "dialog.qc" CLASS(XonoticDemoStartConfirmDialog, XonoticDialog) - METHOD(XonoticDemoStartConfirmDialog, fill, void(entity)) + METHOD(XonoticDemoStartConfirmDialog, fill, void(entity)); ATTRIB(XonoticDemoStartConfirmDialog, title, string, _("Disconnect")) ATTRIB(XonoticDemoStartConfirmDialog, color, vector, SKINCOLOR_DIALOG_HUDCONFIRM) ATTRIB(XonoticDemoStartConfirmDialog, intendedWidth, float, 0.5) diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_media_demo_timeconfirm.qc b/qcsrc/menu/xonotic/dialog_multiplayer_media_demo_timeconfirm.qc index fc3aa4448d..6e35565ad5 100644 --- a/qcsrc/menu/xonotic/dialog_multiplayer_media_demo_timeconfirm.qc +++ b/qcsrc/menu/xonotic/dialog_multiplayer_media_demo_timeconfirm.qc @@ -2,7 +2,7 @@ #define DIALOG_MULTIPLAYER_MEDIA_DEMO_TIMECONFIRM_H #include "dialog.qc" CLASS(XonoticDemoTimeConfirmDialog, XonoticDialog) - METHOD(XonoticDemoTimeConfirmDialog, fill, void(entity)) + METHOD(XonoticDemoTimeConfirmDialog, fill, void(entity)); ATTRIB(XonoticDemoTimeConfirmDialog, title, string, _("Disconnect")) ATTRIB(XonoticDemoTimeConfirmDialog, color, vector, SKINCOLOR_DIALOG_HUDCONFIRM) ATTRIB(XonoticDemoTimeConfirmDialog, intendedWidth, float, 0.5) diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc b/qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc index 6c0791ff7c..d78b5b6575 100644 --- a/qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc +++ b/qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc @@ -2,7 +2,7 @@ #define DIALOG_MULTIPLAYER_MEDIA_MUSICPLAYER_H #include "tab.qc" CLASS(XonoticMusicPlayerTab, XonoticTab) - METHOD(XonoticMusicPlayerTab, fill, void(entity)) + METHOD(XonoticMusicPlayerTab, fill, void(entity)); ATTRIB(XonoticMusicPlayerTab, intendedWidth, float, 0.9) ATTRIB(XonoticMusicPlayerTab, rows, float, 21) ATTRIB(XonoticMusicPlayerTab, columns, float, 6.5) diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot.qc b/qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot.qc index c6526f2ec8..58230253f4 100644 --- a/qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot.qc +++ b/qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot.qc @@ -2,13 +2,13 @@ #define DIALOG_MULTIPLAYER_MEDIA_SCREENSHOT_H #include "tab.qc" CLASS(XonoticScreenshotBrowserTab, XonoticTab) - METHOD(XonoticScreenshotBrowserTab, fill, void(entity)) + METHOD(XonoticScreenshotBrowserTab, fill, void(entity)); ATTRIB(XonoticScreenshotBrowserTab, intendedWidth, float, 1) ATTRIB(XonoticScreenshotBrowserTab, rows, float, 21) ATTRIB(XonoticScreenshotBrowserTab, columns, float, 6.5) ATTRIB(XonoticScreenshotBrowserTab, name, string, "ScreenshotBrowser") - METHOD(XonoticScreenshotBrowserTab, loadPreviewScreenshot, void(entity, string)) + METHOD(XonoticScreenshotBrowserTab, loadPreviewScreenshot, void(entity, string)); ATTRIB(XonoticScreenshotBrowserTab, screenshotImage, entity, NULL) ATTRIB(XonoticScreenshotBrowserTab, currentScrPath, string, string_null) ENDCLASS(XonoticScreenshotBrowserTab) diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.qc b/qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.qc index fa63a17b01..3cf20b7b5c 100644 --- a/qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.qc +++ b/qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.qc @@ -2,10 +2,10 @@ #define DIALOG_MULTIPLAYER_MEDIA_SCREENSHOT_VIEWER_H #include "dialog.qc" CLASS(XonoticScreenshotViewerDialog, XonoticDialog) - METHOD(XonoticScreenshotViewerDialog, fill, void(entity)) - METHOD(XonoticScreenshotViewerDialog, keyDown, float(entity, float, float, float)) - METHOD(XonoticScreenshotViewerDialog, loadScreenshot, void(entity, string)) - METHOD(XonoticScreenshotViewerDialog, close, void(entity)) + METHOD(XonoticScreenshotViewerDialog, fill, void(entity)); + METHOD(XonoticScreenshotViewerDialog, keyDown, float(entity, float, float, float)); + METHOD(XonoticScreenshotViewerDialog, loadScreenshot, void(entity, string)); + METHOD(XonoticScreenshotViewerDialog, close, void(entity)); ATTRIB(XonoticScreenshotViewerDialog, title, string, "Screenshot Viewer") ATTRIB(XonoticScreenshotViewerDialog, name, string, "ScreenshotViewer") ATTRIB(XonoticScreenshotViewerDialog, intendedWidth, float, 1) diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_profile.qc b/qcsrc/menu/xonotic/dialog_multiplayer_profile.qc index 9faf42888e..80d1ffe995 100644 --- a/qcsrc/menu/xonotic/dialog_multiplayer_profile.qc +++ b/qcsrc/menu/xonotic/dialog_multiplayer_profile.qc @@ -2,8 +2,8 @@ #define DIALOG_MULTIPLAYER_PROFILE_H #include "tab.qc" CLASS(XonoticProfileTab, XonoticTab) - METHOD(XonoticProfileTab, fill, void(entity)) - METHOD(XonoticProfileTab, draw, void(entity)) + METHOD(XonoticProfileTab, fill, void(entity)); + METHOD(XonoticProfileTab, draw, void(entity)); ATTRIB(XonoticProfileTab, intendedWidth, float, 0.9) ATTRIB(XonoticProfileTab, rows, float, 23) ATTRIB(XonoticProfileTab, columns, float, 6.1) // added extra .2 for center space diff --git a/qcsrc/menu/xonotic/dialog_quit.qc b/qcsrc/menu/xonotic/dialog_quit.qc index fa4cacecb4..a7591c71c9 100644 --- a/qcsrc/menu/xonotic/dialog_quit.qc +++ b/qcsrc/menu/xonotic/dialog_quit.qc @@ -2,7 +2,7 @@ #define DIALOG_QUIT_H #include "dialog.qc" CLASS(XonoticQuitDialog, XonoticDialog) - METHOD(XonoticQuitDialog, fill, void(entity)) + METHOD(XonoticQuitDialog, fill, void(entity)); ATTRIB(XonoticQuitDialog, title, string, _("Quit")) ATTRIB(XonoticQuitDialog, color, vector, SKINCOLOR_DIALOG_QUIT) ATTRIB(XonoticQuitDialog, intendedWidth, float, 0.5) diff --git a/qcsrc/menu/xonotic/dialog_sandboxtools.qc b/qcsrc/menu/xonotic/dialog_sandboxtools.qc index bcc1ea1f0c..e76be39558 100644 --- a/qcsrc/menu/xonotic/dialog_sandboxtools.qc +++ b/qcsrc/menu/xonotic/dialog_sandboxtools.qc @@ -2,7 +2,7 @@ #define DIALOG_SANDBOXTOOLS_H #include "rootdialog.qc" CLASS(XonoticSandboxToolsDialog, XonoticRootDialog) - METHOD(XonoticSandboxToolsDialog, fill, void(entity)) // to be overridden by user to fill the dialog with controls + METHOD(XonoticSandboxToolsDialog, fill, void(entity)); // to be overridden by user to fill the dialog with controls ATTRIB(XonoticSandboxToolsDialog, title, string, _("Sandbox Tools")) // ;) ATTRIB(XonoticSandboxToolsDialog, color, vector, SKINCOLOR_DIALOG_SANDBOXTOOLS) ATTRIB(XonoticSandboxToolsDialog, intendedWidth, float, 0.8) diff --git a/qcsrc/menu/xonotic/dialog_settings.qc b/qcsrc/menu/xonotic/dialog_settings.qc index e17ab14e6c..eb57476afa 100644 --- a/qcsrc/menu/xonotic/dialog_settings.qc +++ b/qcsrc/menu/xonotic/dialog_settings.qc @@ -2,7 +2,7 @@ #define DIALOG_SETTINGS_H #include "dialog.qc" CLASS(XonoticSettingsDialog, XonoticDialog) - METHOD(XonoticSettingsDialog, fill, void(entity)) + METHOD(XonoticSettingsDialog, fill, void(entity)); ATTRIB(XonoticSettingsDialog, title, string, _("Settings")) ATTRIB(XonoticSettingsDialog, color, vector, SKINCOLOR_DIALOG_SETTINGS) ATTRIB(XonoticSettingsDialog, intendedWidth, float, 0.96) diff --git a/qcsrc/menu/xonotic/dialog_settings_audio.qc b/qcsrc/menu/xonotic/dialog_settings_audio.qc index af8faddace..13f5264c17 100644 --- a/qcsrc/menu/xonotic/dialog_settings_audio.qc +++ b/qcsrc/menu/xonotic/dialog_settings_audio.qc @@ -2,7 +2,7 @@ #define DIALOG_SETTINGS_AUDIO_H #include "tab.qc" CLASS(XonoticAudioSettingsTab, XonoticTab) - METHOD(XonoticAudioSettingsTab, fill, void(entity)) + METHOD(XonoticAudioSettingsTab, fill, void(entity)); ATTRIB(XonoticAudioSettingsTab, intendedWidth, float, 0.9) ATTRIB(XonoticAudioSettingsTab, rows, float, 15.5) ATTRIB(XonoticAudioSettingsTab, columns, float, 6.2) // added extra .2 for center space diff --git a/qcsrc/menu/xonotic/dialog_settings_effects.qc b/qcsrc/menu/xonotic/dialog_settings_effects.qc index d06465082b..c071529971 100644 --- a/qcsrc/menu/xonotic/dialog_settings_effects.qc +++ b/qcsrc/menu/xonotic/dialog_settings_effects.qc @@ -2,7 +2,7 @@ #define DIALOG_SETTINGS_EFFECTS_H #include "tab.qc" CLASS(XonoticEffectsSettingsTab, XonoticTab) - METHOD(XonoticEffectsSettingsTab, fill, void(entity)) + METHOD(XonoticEffectsSettingsTab, fill, void(entity)); ATTRIB(XonoticEffectsSettingsTab, intendedWidth, float, 0.9) ATTRIB(XonoticEffectsSettingsTab, rows, float, 15.5) ATTRIB(XonoticEffectsSettingsTab, columns, float, 6.2) // added extra .2 for center space diff --git a/qcsrc/menu/xonotic/dialog_settings_game.qc b/qcsrc/menu/xonotic/dialog_settings_game.qc index 5b14b7bdb6..2dcdebca9a 100644 --- a/qcsrc/menu/xonotic/dialog_settings_game.qc +++ b/qcsrc/menu/xonotic/dialog_settings_game.qc @@ -2,7 +2,7 @@ #define DIALOG_SETTINGS_GAME_H #include "tab.qc" CLASS(XonoticGameSettingsTab, XonoticTab) - METHOD(XonoticGameSettingsTab, fill, void(entity)) + METHOD(XonoticGameSettingsTab, fill, void(entity)); ATTRIB(XonoticGameSettingsTab, intendedWidth, float, 0.9) ATTRIB(XonoticGameSettingsTab, rows, float, 15.5) ATTRIB(XonoticGameSettingsTab, columns, float, 6.5) diff --git a/qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc b/qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc index cee4bd5c72..db197d6044 100644 --- a/qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc +++ b/qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc @@ -2,8 +2,8 @@ #define DIALOG_SETTINGS_GAME_CROSSHAIR_H #include "tab.qc" CLASS(XonoticGameCrosshairSettingsTab, XonoticTab) - METHOD(XonoticGameCrosshairSettingsTab, fill, void(entity)) - METHOD(XonoticGameCrosshairSettingsTab, showNotify, void(entity)) + METHOD(XonoticGameCrosshairSettingsTab, fill, void(entity)); + METHOD(XonoticGameCrosshairSettingsTab, showNotify, void(entity)); ATTRIB(XonoticGameCrosshairSettingsTab, intendedWidth, float, 0.9) ATTRIB(XonoticGameCrosshairSettingsTab, rows, float, 13) ATTRIB(XonoticGameCrosshairSettingsTab, columns, float, 6.2) diff --git a/qcsrc/menu/xonotic/dialog_settings_game_hud.qc b/qcsrc/menu/xonotic/dialog_settings_game_hud.qc index 941daa7922..c9fc6d8211 100644 --- a/qcsrc/menu/xonotic/dialog_settings_game_hud.qc +++ b/qcsrc/menu/xonotic/dialog_settings_game_hud.qc @@ -2,8 +2,8 @@ #define DIALOG_SETTINGS_GAME_HUD_H #include "tab.qc" CLASS(XonoticGameHUDSettingsTab, XonoticTab) - METHOD(XonoticGameHUDSettingsTab, fill, void(entity)) - METHOD(XonoticGameHUDSettingsTab, showNotify, void(entity)) + METHOD(XonoticGameHUDSettingsTab, fill, void(entity)); + METHOD(XonoticGameHUDSettingsTab, showNotify, void(entity)); ATTRIB(XonoticGameHUDSettingsTab, intendedWidth, float, 0.9) ATTRIB(XonoticGameHUDSettingsTab, rows, float, 13) ATTRIB(XonoticGameHUDSettingsTab, columns, float, 6.2) diff --git a/qcsrc/menu/xonotic/dialog_settings_game_hudconfirm.qc b/qcsrc/menu/xonotic/dialog_settings_game_hudconfirm.qc index d0b460b916..6d3fa1f02c 100644 --- a/qcsrc/menu/xonotic/dialog_settings_game_hudconfirm.qc +++ b/qcsrc/menu/xonotic/dialog_settings_game_hudconfirm.qc @@ -2,7 +2,7 @@ #define DIALOG_SETTINGS_GAME_HUDCONFIRM_H #include "dialog.qc" CLASS(XonoticHUDConfirmDialog, XonoticDialog) - METHOD(XonoticHUDConfirmDialog, fill, void(entity)) + METHOD(XonoticHUDConfirmDialog, fill, void(entity)); ATTRIB(XonoticHUDConfirmDialog, title, string, _("Enter HUD editor")) ATTRIB(XonoticHUDConfirmDialog, color, vector, SKINCOLOR_DIALOG_HUDCONFIRM) ATTRIB(XonoticHUDConfirmDialog, intendedWidth, float, 0.5) diff --git a/qcsrc/menu/xonotic/dialog_settings_game_messages.qc b/qcsrc/menu/xonotic/dialog_settings_game_messages.qc index d52a102d42..764d7ef509 100644 --- a/qcsrc/menu/xonotic/dialog_settings_game_messages.qc +++ b/qcsrc/menu/xonotic/dialog_settings_game_messages.qc @@ -2,8 +2,8 @@ #define DIALOG_SETTINGS_GAME_MESSAGES_H #include "tab.qc" CLASS(XonoticGameMessageSettingsTab, XonoticTab) - METHOD(XonoticGameMessageSettingsTab, fill, void(entity)) - METHOD(XonoticGameMessageSettingsTab, showNotify, void(entity)) + METHOD(XonoticGameMessageSettingsTab, fill, void(entity)); + METHOD(XonoticGameMessageSettingsTab, showNotify, void(entity)); ATTRIB(XonoticGameMessageSettingsTab, intendedWidth, float, 0.9) ATTRIB(XonoticGameMessageSettingsTab, rows, float, 13) ATTRIB(XonoticGameMessageSettingsTab, columns, float, 6) diff --git a/qcsrc/menu/xonotic/dialog_settings_game_model.qc b/qcsrc/menu/xonotic/dialog_settings_game_model.qc index db3e4082c9..f91f7f0396 100644 --- a/qcsrc/menu/xonotic/dialog_settings_game_model.qc +++ b/qcsrc/menu/xonotic/dialog_settings_game_model.qc @@ -2,8 +2,8 @@ #define DIALOG_SETTINGS_GAME_MODEL_H #include "tab.qc" CLASS(XonoticGameModelSettingsTab, XonoticTab) - METHOD(XonoticGameModelSettingsTab, fill, void(entity)) - METHOD(XonoticGameModelSettingsTab, showNotify, void(entity)) + METHOD(XonoticGameModelSettingsTab, fill, void(entity)); + METHOD(XonoticGameModelSettingsTab, showNotify, void(entity)); ATTRIB(XonoticGameModelSettingsTab, intendedWidth, float, 0.9) ATTRIB(XonoticGameModelSettingsTab, rows, float, 13) ATTRIB(XonoticGameModelSettingsTab, columns, float, 5) diff --git a/qcsrc/menu/xonotic/dialog_settings_game_view.qc b/qcsrc/menu/xonotic/dialog_settings_game_view.qc index 8fc56f94c6..939fd0dc9b 100644 --- a/qcsrc/menu/xonotic/dialog_settings_game_view.qc +++ b/qcsrc/menu/xonotic/dialog_settings_game_view.qc @@ -2,8 +2,8 @@ #define DIALOG_SETTINGS_GAME_VIEW_H #include "tab.qc" CLASS(XonoticGameViewSettingsTab, XonoticTab) - METHOD(XonoticGameViewSettingsTab, fill, void(entity)) - METHOD(XonoticGameViewSettingsTab, showNotify, void(entity)) + METHOD(XonoticGameViewSettingsTab, fill, void(entity)); + METHOD(XonoticGameViewSettingsTab, showNotify, void(entity)); ATTRIB(XonoticGameViewSettingsTab, intendedWidth, float, 0.9) ATTRIB(XonoticGameViewSettingsTab, rows, float, 13) ATTRIB(XonoticGameViewSettingsTab, columns, float, 6.2) diff --git a/qcsrc/menu/xonotic/dialog_settings_game_weapons.qc b/qcsrc/menu/xonotic/dialog_settings_game_weapons.qc index c59a9620d4..aab91c7484 100644 --- a/qcsrc/menu/xonotic/dialog_settings_game_weapons.qc +++ b/qcsrc/menu/xonotic/dialog_settings_game_weapons.qc @@ -2,8 +2,8 @@ #define DIALOG_SETTINGS_GAME_WEAPONS_H #include "tab.qc" CLASS(XonoticGameWeaponsSettingsTab, XonoticTab) - METHOD(XonoticGameWeaponsSettingsTab, fill, void(entity)) - METHOD(XonoticGameWeaponsSettingsTab, showNotify, void(entity)) + METHOD(XonoticGameWeaponsSettingsTab, fill, void(entity)); + METHOD(XonoticGameWeaponsSettingsTab, showNotify, void(entity)); ATTRIB(XonoticGameWeaponsSettingsTab, intendedWidth, float, 0.9) ATTRIB(XonoticGameWeaponsSettingsTab, rows, float, 13) ATTRIB(XonoticGameWeaponsSettingsTab, columns, float, 6) diff --git a/qcsrc/menu/xonotic/dialog_settings_input.qc b/qcsrc/menu/xonotic/dialog_settings_input.qc index f8e53c03a9..c36c26e547 100644 --- a/qcsrc/menu/xonotic/dialog_settings_input.qc +++ b/qcsrc/menu/xonotic/dialog_settings_input.qc @@ -2,7 +2,7 @@ #define DIALOG_SETTINGS_INPUT_H #include "tab.qc" CLASS(XonoticInputSettingsTab, XonoticTab) - METHOD(XonoticInputSettingsTab, fill, void(entity)) + METHOD(XonoticInputSettingsTab, fill, void(entity)); ATTRIB(XonoticInputSettingsTab, intendedWidth, float, 0.9) ATTRIB(XonoticInputSettingsTab, rows, float, 15.5) ATTRIB(XonoticInputSettingsTab, columns, float, 6.2) // added extra .2 for center space diff --git a/qcsrc/menu/xonotic/dialog_settings_input_userbind.qc b/qcsrc/menu/xonotic/dialog_settings_input_userbind.qc index d6ad2e7090..d88be1d59e 100644 --- a/qcsrc/menu/xonotic/dialog_settings_input_userbind.qc +++ b/qcsrc/menu/xonotic/dialog_settings_input_userbind.qc @@ -2,8 +2,8 @@ #define DIALOG_SETTINGS_INPUT_USERBIND_H #include "dialog.qc" CLASS(XonoticUserbindEditDialog, XonoticDialog) - METHOD(XonoticUserbindEditDialog, loadUserBind, void(entity, string, string, string)) - METHOD(XonoticUserbindEditDialog, fill, void(entity)) + METHOD(XonoticUserbindEditDialog, loadUserBind, void(entity, string, string, string)); + METHOD(XonoticUserbindEditDialog, fill, void(entity)); ATTRIB(XonoticUserbindEditDialog, title, string, _("User defined key bind")) ATTRIB(XonoticUserbindEditDialog, color, vector, SKINCOLOR_DIALOG_USERBIND) ATTRIB(XonoticUserbindEditDialog, intendedWidth, float, 0.7) diff --git a/qcsrc/menu/xonotic/dialog_settings_misc.qc b/qcsrc/menu/xonotic/dialog_settings_misc.qc index 79e1961706..877b070ffa 100644 --- a/qcsrc/menu/xonotic/dialog_settings_misc.qc +++ b/qcsrc/menu/xonotic/dialog_settings_misc.qc @@ -2,7 +2,7 @@ #define DIALOG_SETTINGS_MISC_H #include "tab.qc" CLASS(XonoticMiscSettingsTab, XonoticTab) - METHOD(XonoticMiscSettingsTab, fill, void(entity)) + METHOD(XonoticMiscSettingsTab, fill, void(entity)); ATTRIB(XonoticMiscSettingsTab, intendedWidth, float, 0.9) ATTRIB(XonoticMiscSettingsTab, rows, float, 15.5) ATTRIB(XonoticMiscSettingsTab, columns, float, 6.2) diff --git a/qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc b/qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc index af75e64b92..6ace10c124 100644 --- a/qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc +++ b/qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc @@ -2,8 +2,8 @@ #define DIALOG_SETTINGS_MISC_CVARS_H #include "dialog.qc" CLASS(XonoticCvarsDialog, XonoticDialog) - METHOD(XonoticCvarsDialog, fill, void(entity)) - METHOD(XonoticCvarsDialog, showNotify, void(entity)) + METHOD(XonoticCvarsDialog, fill, void(entity)); + METHOD(XonoticCvarsDialog, showNotify, void(entity)); ATTRIB(XonoticCvarsDialog, title, string, _("Advanced settings")) ATTRIB(XonoticCvarsDialog, color, vector, SKINCOLOR_DIALOG_CVARS) ATTRIB(XonoticCvarsDialog, intendedWidth, float, 0.8) diff --git a/qcsrc/menu/xonotic/dialog_settings_misc_reset.qc b/qcsrc/menu/xonotic/dialog_settings_misc_reset.qc index 2f99321598..f989f88593 100644 --- a/qcsrc/menu/xonotic/dialog_settings_misc_reset.qc +++ b/qcsrc/menu/xonotic/dialog_settings_misc_reset.qc @@ -2,7 +2,7 @@ #define DIALOG_SETTINGS_MISC_RESET_H #include "dialog.qc" CLASS(XonoticResetDialog, XonoticDialog) - METHOD(XonoticResetDialog, fill, void(entity)) + METHOD(XonoticResetDialog, fill, void(entity)); ATTRIB(XonoticResetDialog, title, string, _("Factory reset")) ATTRIB(XonoticResetDialog, color, vector, SKINCOLOR_DIALOG_QUIT) ATTRIB(XonoticResetDialog, intendedWidth, float, 0.5) diff --git a/qcsrc/menu/xonotic/dialog_settings_user.qc b/qcsrc/menu/xonotic/dialog_settings_user.qc index 35246ae170..4a8712c260 100644 --- a/qcsrc/menu/xonotic/dialog_settings_user.qc +++ b/qcsrc/menu/xonotic/dialog_settings_user.qc @@ -2,7 +2,7 @@ #define DIALOG_SETTINGS_USER_H #include "tab.qc" CLASS(XonoticUserSettingsTab, XonoticTab) - METHOD(XonoticUserSettingsTab, fill, void(entity)) + METHOD(XonoticUserSettingsTab, fill, void(entity)); ATTRIB(XonoticUserSettingsTab, intendedWidth, float, 0.9) ATTRIB(XonoticUserSettingsTab, rows, float, 15.5) ATTRIB(XonoticUserSettingsTab, columns, float, 6) diff --git a/qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qc b/qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qc index 0a340eaff4..73a339411c 100644 --- a/qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qc +++ b/qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qc @@ -2,7 +2,7 @@ #define DIALOG_SETTINGS_USER_LANGUAGEWARNING_H #include "dialog.qc" CLASS(XonoticLanguageWarningDialog, XonoticDialog) - METHOD(XonoticLanguageWarningDialog, fill, void(entity)) // to be overridden by user to fill the dialog with controls + METHOD(XonoticLanguageWarningDialog, fill, void(entity)); // to be overridden by user to fill the dialog with controls ATTRIB(XonoticLanguageWarningDialog, title, string, _("Warning")) ATTRIB(XonoticLanguageWarningDialog, color, vector, SKINCOLOR_DIALOG_HUDCONFIRM) ATTRIB(XonoticLanguageWarningDialog, intendedWidth, float, 0.6) diff --git a/qcsrc/menu/xonotic/dialog_settings_video.qc b/qcsrc/menu/xonotic/dialog_settings_video.qc index 61a93f62e2..c4981bb1ae 100644 --- a/qcsrc/menu/xonotic/dialog_settings_video.qc +++ b/qcsrc/menu/xonotic/dialog_settings_video.qc @@ -2,7 +2,7 @@ #define DIALOG_SETTINGS_VIDEO_H #include "tab.qc" CLASS(XonoticVideoSettingsTab, XonoticTab) - METHOD(XonoticVideoSettingsTab, fill, void(entity)) + METHOD(XonoticVideoSettingsTab, fill, void(entity)); ATTRIB(XonoticVideoSettingsTab, intendedWidth, float, 0.9) ATTRIB(XonoticVideoSettingsTab, rows, float, 15.5) ATTRIB(XonoticVideoSettingsTab, columns, float, 6.2) // added extra .2 for center space diff --git a/qcsrc/menu/xonotic/dialog_singleplayer.qc b/qcsrc/menu/xonotic/dialog_singleplayer.qc index aa00d8fe8e..8dab35f997 100644 --- a/qcsrc/menu/xonotic/dialog_singleplayer.qc +++ b/qcsrc/menu/xonotic/dialog_singleplayer.qc @@ -2,7 +2,7 @@ #define DIALOG_SINGLEPLAYER_H #include "dialog.qc" CLASS(XonoticSingleplayerDialog, XonoticDialog) - METHOD(XonoticSingleplayerDialog, fill, void(entity)) + METHOD(XonoticSingleplayerDialog, fill, void(entity)); ATTRIB(XonoticSingleplayerDialog, title, string, _("Singleplayer")) ATTRIB(XonoticSingleplayerDialog, color, vector, SKINCOLOR_DIALOG_SINGLEPLAYER) ATTRIB(XonoticSingleplayerDialog, intendedWidth, float, 0.80) diff --git a/qcsrc/menu/xonotic/dialog_singleplayer_winner.qc b/qcsrc/menu/xonotic/dialog_singleplayer_winner.qc index bc9d1c4eae..b7b97c9733 100644 --- a/qcsrc/menu/xonotic/dialog_singleplayer_winner.qc +++ b/qcsrc/menu/xonotic/dialog_singleplayer_winner.qc @@ -2,8 +2,8 @@ #define DIALOG_SINGLEPLAYER_WINNER_H #include "dialog.qc" CLASS(XonoticWinnerDialog, XonoticDialog) - METHOD(XonoticWinnerDialog, fill, void(entity)) - METHOD(XonoticWinnerDialog, focusEnter, void(entity)) + METHOD(XonoticWinnerDialog, fill, void(entity)); + METHOD(XonoticWinnerDialog, focusEnter, void(entity)); ATTRIB(XonoticWinnerDialog, title, string, _("Winner")) ATTRIB(XonoticWinnerDialog, color, vector, SKINCOLOR_DIALOG_SINGLEPLAYER) ATTRIB(XonoticWinnerDialog, intendedWidth, float, 0.32) diff --git a/qcsrc/menu/xonotic/dialog_teamselect.qc b/qcsrc/menu/xonotic/dialog_teamselect.qc index 8ed9d7ef23..2c09e8613d 100644 --- a/qcsrc/menu/xonotic/dialog_teamselect.qc +++ b/qcsrc/menu/xonotic/dialog_teamselect.qc @@ -2,8 +2,8 @@ #define DIALOG_TEAMSELECT_H #include "rootdialog.qc" CLASS(XonoticTeamSelectDialog, XonoticRootDialog) - METHOD(XonoticTeamSelectDialog, fill, void(entity)) // to be overridden by user to fill the dialog with controls - METHOD(XonoticTeamSelectDialog, showNotify, void(entity)) + METHOD(XonoticTeamSelectDialog, fill, void(entity)); // to be overridden by user to fill the dialog with controls + METHOD(XonoticTeamSelectDialog, showNotify, void(entity)); ATTRIB(XonoticTeamSelectDialog, title, string, _("Team Selection")) // ;) ATTRIB(XonoticTeamSelectDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) ATTRIB(XonoticTeamSelectDialog, intendedWidth, float, 0.4) diff --git a/qcsrc/menu/xonotic/gametypebutton.qc b/qcsrc/menu/xonotic/gametypebutton.qc index ae202560c4..f27a626782 100644 --- a/qcsrc/menu/xonotic/gametypebutton.qc +++ b/qcsrc/menu/xonotic/gametypebutton.qc @@ -2,8 +2,8 @@ #define GAMETYPEBUTTON_H #include "../item/radiobutton.qc" CLASS(XonoticGametypeButton, RadioButton) - METHOD(XonoticGametypeButton, configureXonoticGametypeButton, void(entity, float, string, string)) - METHOD(XonoticGametypeButton, setChecked, void(entity, float)) + METHOD(XonoticGametypeButton, configureXonoticGametypeButton, void(entity, float, string, string)); + METHOD(XonoticGametypeButton, setChecked, void(entity, float)); ATTRIB(XonoticGametypeButton, fontSize, float, SKINFONTSIZE_NORMAL) ATTRIB(XonoticGametypeButton, image, string, SKINGFX_BUTTON_BIG) ATTRIB(XonoticGametypeButton, color, vector, SKINCOLOR_BUTTON_N) @@ -14,8 +14,8 @@ CLASS(XonoticGametypeButton, RadioButton) ATTRIB(XonoticGametypeButton, useDownAsChecked, float, 1) ATTRIB(XonoticGametypeButton, cvarName, string, string_null) - METHOD(XonoticGametypeButton, loadCvars, void(entity)) - METHOD(XonoticGametypeButton, saveCvars, void(entity)) + METHOD(XonoticGametypeButton, loadCvars, void(entity)); + METHOD(XonoticGametypeButton, saveCvars, void(entity)); ATTRIB(XonoticGametypeButton, alpha, float, SKINALPHA_TEXT) ATTRIB(XonoticGametypeButton, disabledAlpha, float, SKINALPHA_DISABLED) diff --git a/qcsrc/menu/xonotic/gametypelist.qc b/qcsrc/menu/xonotic/gametypelist.qc index 030af67153..e2fdfa8e72 100644 --- a/qcsrc/menu/xonotic/gametypelist.qc +++ b/qcsrc/menu/xonotic/gametypelist.qc @@ -2,15 +2,15 @@ #define GAMETYPELIST_H #include "listbox.qc" CLASS(XonoticGametypeList, XonoticListBox) - METHOD(XonoticGametypeList, configureXonoticGametypeList, void(entity)) + METHOD(XonoticGametypeList, configureXonoticGametypeList, void(entity)); ATTRIB(XonoticGametypeList, rowsPerItem, float, 2) - METHOD(XonoticGametypeList, drawListBoxItem, void(entity, int, vector, bool, bool)) - METHOD(XonoticGametypeList, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(XonoticGametypeList, setSelected, void(entity, float)) - METHOD(XonoticGametypeList, loadCvars, void(entity)) - METHOD(XonoticGametypeList, saveCvars, void(entity)) - METHOD(XonoticGametypeList, keyDown, float(entity, float, float, float)) - METHOD(XonoticGametypeList, clickListBoxItem, void(entity, float, vector)) + METHOD(XonoticGametypeList, drawListBoxItem, void(entity, int, vector, bool, bool)); + METHOD(XonoticGametypeList, resizeNotify, void(entity, vector, vector, vector, vector)); + METHOD(XonoticGametypeList, setSelected, void(entity, float)); + METHOD(XonoticGametypeList, loadCvars, void(entity)); + METHOD(XonoticGametypeList, saveCvars, void(entity)); + METHOD(XonoticGametypeList, keyDown, float(entity, float, float, float)); + METHOD(XonoticGametypeList, clickListBoxItem, void(entity, float, vector)); ATTRIB(XonoticGametypeList, realFontSize, vector, '0 0 0') ATTRIB(XonoticGametypeList, realUpperMargin, float, 0) diff --git a/qcsrc/menu/xonotic/image.qc b/qcsrc/menu/xonotic/image.qc index e8f5a82693..1f25899c14 100644 --- a/qcsrc/menu/xonotic/image.qc +++ b/qcsrc/menu/xonotic/image.qc @@ -2,7 +2,7 @@ #define IMAGE_H #include "../item/image.qc" CLASS(XonoticImage, Image) - METHOD(XonoticImage, configureXonoticImage, void(entity, string, float)) + METHOD(XonoticImage, configureXonoticImage, void(entity, string, float)); ENDCLASS(XonoticImage) entity makeXonoticImage(string theImage, float theAspect); #endif diff --git a/qcsrc/menu/xonotic/inputbox.qc b/qcsrc/menu/xonotic/inputbox.qc index de1580160e..0ff3aaee36 100644 --- a/qcsrc/menu/xonotic/inputbox.qc +++ b/qcsrc/menu/xonotic/inputbox.qc @@ -2,9 +2,9 @@ #define INPUTBOX_H #include "../item/inputbox.qc" CLASS(XonoticInputBox, InputBox) - METHOD(XonoticInputBox, configureXonoticInputBox, void(entity, float, string)) - METHOD(XonoticInputBox, focusLeave, void(entity)) - METHOD(XonoticInputBox, setText, void(entity, string)) + METHOD(XonoticInputBox, configureXonoticInputBox, void(entity, float, string)); + METHOD(XonoticInputBox, focusLeave, void(entity)); + METHOD(XonoticInputBox, setText, void(entity, string)); ATTRIB(XonoticInputBox, fontSize, float, SKINFONTSIZE_NORMAL) ATTRIB(XonoticInputBox, image, string, SKINGFX_INPUTBOX) ATTRIB(XonoticInputBox, onChange, void(entity, entity), func_null) @@ -26,10 +26,10 @@ CLASS(XonoticInputBox, InputBox) ATTRIB(XonoticInputBox, cb_colorC, vector, SKINCOLOR_CLEARBUTTON_C) ATTRIB(XonoticInputBox, cvarName, string, string_null) - METHOD(XonoticInputBox, loadCvars, void(entity)) - METHOD(XonoticInputBox, saveCvars, void(entity)) + METHOD(XonoticInputBox, loadCvars, void(entity)); + METHOD(XonoticInputBox, saveCvars, void(entity)); ATTRIB(XonoticInputBox, sendCvars, float, 0) - METHOD(XonoticInputBox, keyDown, float(entity, float, float, float)) + METHOD(XonoticInputBox, keyDown, float(entity, float, float, float)); ATTRIB(XonoticInputBox, saveImmediately, float, 0) ENDCLASS(XonoticInputBox) diff --git a/qcsrc/menu/xonotic/keybinder.qc b/qcsrc/menu/xonotic/keybinder.qc index 8953b1db9b..a510a757c9 100644 --- a/qcsrc/menu/xonotic/keybinder.qc +++ b/qcsrc/menu/xonotic/keybinder.qc @@ -2,14 +2,14 @@ #define KEYBINDER_H #include "listbox.qc" CLASS(XonoticKeyBinder, XonoticListBox) - METHOD(XonoticKeyBinder, configureXonoticKeyBinder, void(entity)) + METHOD(XonoticKeyBinder, configureXonoticKeyBinder, void(entity)); ATTRIB(XonoticKeyBinder, rowsPerItem, int, 1) - METHOD(XonoticKeyBinder, drawListBoxItem, void(entity, int, vector, bool, bool)) - METHOD(XonoticKeyBinder, doubleClickListBoxItem, void(entity, float, vector)) - METHOD(XonoticKeyBinder, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(XonoticKeyBinder, setSelected, void(entity, float)) - METHOD(XonoticKeyBinder, keyDown, float(entity, float, float, float)) - METHOD(XonoticKeyBinder, keyGrabbed, void(entity, float, float)) + METHOD(XonoticKeyBinder, drawListBoxItem, void(entity, int, vector, bool, bool)); + METHOD(XonoticKeyBinder, doubleClickListBoxItem, void(entity, float, vector)); + METHOD(XonoticKeyBinder, resizeNotify, void(entity, vector, vector, vector, vector)); + METHOD(XonoticKeyBinder, setSelected, void(entity, float)); + METHOD(XonoticKeyBinder, keyDown, float(entity, float, float, float)); + METHOD(XonoticKeyBinder, keyGrabbed, void(entity, float, float)); ATTRIB(XonoticKeyBinder, realFontSize, vector, '0 0 0') ATTRIB(XonoticKeyBinder, realUpperMargin, float, 0) @@ -24,7 +24,7 @@ CLASS(XonoticKeyBinder, XonoticListBox) ATTRIB(XonoticKeyBinder, keyGrabButton, entity, NULL) ATTRIB(XonoticKeyBinder, clearButton, entity, NULL) ATTRIB(XonoticKeyBinder, userbindEditDialog, entity, NULL) - METHOD(XonoticKeyBinder, editUserbind, void(entity, string, string, string)) + METHOD(XonoticKeyBinder, editUserbind, void(entity, string, string, string)); ENDCLASS(XonoticKeyBinder) entity makeXonoticKeyBinder(); void KeyBinder_Bind_Change(entity btn, entity me); diff --git a/qcsrc/menu/xonotic/languagelist.qc b/qcsrc/menu/xonotic/languagelist.qc index 4ff1775567..0b7281dbff 100644 --- a/qcsrc/menu/xonotic/languagelist.qc +++ b/qcsrc/menu/xonotic/languagelist.qc @@ -2,13 +2,13 @@ #define LANGUAGELIST_H #include "listbox.qc" CLASS(XonoticLanguageList, XonoticListBox) - METHOD(XonoticLanguageList, configureXonoticLanguageList, void(entity)) + METHOD(XonoticLanguageList, configureXonoticLanguageList, void(entity)); ATTRIB(XonoticLanguageList, rowsPerItem, float, 1) - METHOD(XonoticLanguageList, drawListBoxItem, void(entity, int, vector, bool, bool)) - METHOD(XonoticLanguageList, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(XonoticLanguageList, setSelected, void(entity, float)) - METHOD(XonoticLanguageList, loadCvars, void(entity)) - METHOD(XonoticLanguageList, saveCvars, void(entity)) + METHOD(XonoticLanguageList, drawListBoxItem, void(entity, int, vector, bool, bool)); + METHOD(XonoticLanguageList, resizeNotify, void(entity, vector, vector, vector, vector)); + METHOD(XonoticLanguageList, setSelected, void(entity, float)); + METHOD(XonoticLanguageList, loadCvars, void(entity)); + METHOD(XonoticLanguageList, saveCvars, void(entity)); ATTRIB(XonoticLanguageList, realFontSize, vector, '0 0 0') ATTRIB(XonoticLanguageList, realUpperMargin, float, 0) @@ -17,15 +17,15 @@ CLASS(XonoticLanguageList, XonoticListBox) ATTRIB(XonoticLanguageList, columnPercentageOrigin, float, 0) ATTRIB(XonoticLanguageList, columnPercentageSize, float, 0) - METHOD(XonoticLanguageList, doubleClickListBoxItem, void(entity, float, vector)) - METHOD(XonoticLanguageList, keyDown, float(entity, float, float, float)) // enter handling + METHOD(XonoticLanguageList, doubleClickListBoxItem, void(entity, float, vector)); + METHOD(XonoticLanguageList, keyDown, float(entity, float, float, float)); // enter handling - METHOD(XonoticLanguageList, destroy, void(entity)) + METHOD(XonoticLanguageList, destroy, void(entity)); ATTRIB(XonoticLanguageList, languagelist, float, -1) - METHOD(XonoticLanguageList, getLanguages, void(entity)) - METHOD(XonoticLanguageList, setLanguage, void(entity)) - METHOD(XonoticLanguageList, languageParameter, string(entity, float, float)) + METHOD(XonoticLanguageList, getLanguages, void(entity)); + METHOD(XonoticLanguageList, setLanguage, void(entity)); + METHOD(XonoticLanguageList, languageParameter, string(entity, float, float)); ATTRIB(XonoticLanguageList, name, string, "languageselector") // change this to make it noninteractive (for first run dialog) ENDCLASS(XonoticLanguageList) diff --git a/qcsrc/menu/xonotic/listbox.qc b/qcsrc/menu/xonotic/listbox.qc index c4a0923858..3ce6ed7cc7 100644 --- a/qcsrc/menu/xonotic/listbox.qc +++ b/qcsrc/menu/xonotic/listbox.qc @@ -2,13 +2,13 @@ #define LISTBOX_H #include "../item/listbox.qc" CLASS(XonoticListBox, ListBox) - METHOD(XonoticListBox, configureXonoticListBox, void(entity)) + METHOD(XonoticListBox, configureXonoticListBox, void(entity)); ATTRIB(XonoticListBox, fontSize, float, SKINFONTSIZE_NORMAL) ATTRIB(XonoticListBox, scrollbarWidth, float, SKINWIDTH_SCROLLBAR) ATTRIB(XonoticListBox, src, string, SKINGFX_SCROLLBAR) ATTRIB(XonoticListBox, tolerance, vector, SKINTOLERANCE_SLIDER) ATTRIB(XonoticListBox, rowsPerItem, float, 1) - METHOD(XonoticListBox, resizeNotify, void(entity, vector, vector, vector, vector)) + METHOD(XonoticListBox, resizeNotify, void(entity, vector, vector, vector, vector)); ATTRIB(XonoticListBox, color, vector, SKINCOLOR_SCROLLBAR_N) ATTRIB(XonoticListBox, colorF, vector, SKINCOLOR_SCROLLBAR_F) ATTRIB(XonoticListBox, color2, vector, SKINCOLOR_SCROLLBAR_S) diff --git a/qcsrc/menu/xonotic/mainwindow.qc b/qcsrc/menu/xonotic/mainwindow.qc index 4ca94c9b02..eafa1842fd 100644 --- a/qcsrc/menu/xonotic/mainwindow.qc +++ b/qcsrc/menu/xonotic/mainwindow.qc @@ -2,8 +2,8 @@ #define MAINWINDOW_H #include "../item/modalcontroller.qc" CLASS(MainWindow, ModalController) - METHOD(MainWindow, configureMainWindow, void(entity)) - METHOD(MainWindow, draw, void(entity)) + METHOD(MainWindow, configureMainWindow, void(entity)); + METHOD(MainWindow, draw, void(entity)); ATTRIB(MainWindow, firstRunDialog, entity, NULL) ATTRIB(MainWindow, advancedDialog, entity, NULL) ATTRIB(MainWindow, mutatorsDialog, entity, NULL) diff --git a/qcsrc/menu/xonotic/maplist.qc b/qcsrc/menu/xonotic/maplist.qc index a4cc0565c3..a9379e7e83 100644 --- a/qcsrc/menu/xonotic/maplist.qc +++ b/qcsrc/menu/xonotic/maplist.qc @@ -2,16 +2,16 @@ #define MAPLIST_H #include "listbox.qc" CLASS(XonoticMapList, XonoticListBox) - METHOD(XonoticMapList, configureXonoticMapList, void(entity)) + METHOD(XonoticMapList, configureXonoticMapList, void(entity)); ATTRIB(XonoticMapList, rowsPerItem, float, 4) - METHOD(XonoticMapList, draw, void(entity)) - METHOD(XonoticMapList, drawListBoxItem, void(entity, int, vector, bool, bool)) - METHOD(XonoticMapList, clickListBoxItem, void(entity, float, vector)) - METHOD(XonoticMapList, doubleClickListBoxItem, void(entity, float, vector)) - METHOD(XonoticMapList, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(XonoticMapList, refilter, void(entity)) - METHOD(XonoticMapList, refilterCallback, void(entity, entity)) - METHOD(XonoticMapList, keyDown, float(entity, float, float, float)) + METHOD(XonoticMapList, draw, void(entity)); + METHOD(XonoticMapList, drawListBoxItem, void(entity, int, vector, bool, bool)); + METHOD(XonoticMapList, clickListBoxItem, void(entity, float, vector)); + METHOD(XonoticMapList, doubleClickListBoxItem, void(entity, float, vector)); + METHOD(XonoticMapList, resizeNotify, void(entity, vector, vector, vector, vector)); + METHOD(XonoticMapList, refilter, void(entity)); + METHOD(XonoticMapList, refilterCallback, void(entity, entity)); + METHOD(XonoticMapList, keyDown, float(entity, float, float, float)); ATTRIB(XonoticMapList, realFontSize, vector, '0 0 0') ATTRIB(XonoticMapList, columnPreviewOrigin, float, 0) @@ -30,20 +30,20 @@ CLASS(XonoticMapList, XonoticListBox) ATTRIB(XonoticMapList, itemAbsSize, vector, '0 0 0') ATTRIB(XonoticMapList, g_maplistCache, string, string_null) - METHOD(XonoticMapList, g_maplistCacheToggle, void(entity, float)) - METHOD(XonoticMapList, g_maplistCacheQuery, float(entity, float)) + METHOD(XonoticMapList, g_maplistCacheToggle, void(entity, float)); + METHOD(XonoticMapList, g_maplistCacheQuery, float(entity, float)); ATTRIB(XonoticMapList, stringFilter, string, string_null) ATTRIB(XonoticMapList, stringFilterBox, entity, NULL) ATTRIB(XonoticMapList, startButton, entity, NULL) - METHOD(XonoticMapList, loadCvars, void(entity)) + METHOD(XonoticMapList, loadCvars, void(entity)); ATTRIB(XonoticMapList, typeToSearchString, string, string_null) ATTRIB(XonoticMapList, typeToSearchTime, float, 0) - METHOD(XonoticMapList, destroy, void(entity)) + METHOD(XonoticMapList, destroy, void(entity)); ATTRIB(XonoticMapList, alphaBG, float, 0) ENDCLASS(XonoticMapList) @@ -280,7 +280,7 @@ void MapList_StringFilterBox_Change(entity box, entity me) me.stringFilter = strzone(box.text); else me.stringFilter = string_null; - + me.refilter(me); } diff --git a/qcsrc/menu/xonotic/nexposee.qc b/qcsrc/menu/xonotic/nexposee.qc index 966b11a988..0d302eba86 100644 --- a/qcsrc/menu/xonotic/nexposee.qc +++ b/qcsrc/menu/xonotic/nexposee.qc @@ -2,8 +2,8 @@ #define NEXPOSEE_H #include "../item/nexposee.qc" CLASS(XonoticNexposee, Nexposee) - METHOD(XonoticNexposee, configureXonoticNexposee, void(entity)) - METHOD(XonoticNexposee, close, void(entity)) + METHOD(XonoticNexposee, configureXonoticNexposee, void(entity)); + METHOD(XonoticNexposee, close, void(entity)); ENDCLASS(XonoticNexposee) entity makeXonoticNexposee(); #endif diff --git a/qcsrc/menu/xonotic/picker.qc b/qcsrc/menu/xonotic/picker.qc index dd574676e0..24e5b2f5cd 100644 --- a/qcsrc/menu/xonotic/picker.qc +++ b/qcsrc/menu/xonotic/picker.qc @@ -2,13 +2,13 @@ #define PICKER_H #include "../item.qc" CLASS(XonoticPicker, Item) - METHOD(XonoticPicker, configureXonoticPicker, void(entity)) - METHOD(XonoticPicker, mousePress, float(entity, vector)) - METHOD(XonoticPicker, mouseRelease, float(entity, vector)) - METHOD(XonoticPicker, mouseMove, float(entity, vector)) - METHOD(XonoticPicker, mouseDrag, float(entity, vector)) - METHOD(XonoticPicker, keyDown, float(entity, float, float, float)) - METHOD(XonoticPicker, draw, void(entity)) + METHOD(XonoticPicker, configureXonoticPicker, void(entity)); + METHOD(XonoticPicker, mousePress, float(entity, vector)); + METHOD(XonoticPicker, mouseRelease, float(entity, vector)); + METHOD(XonoticPicker, mouseMove, float(entity, vector)); + METHOD(XonoticPicker, mouseDrag, float(entity, vector)); + METHOD(XonoticPicker, keyDown, float(entity, float, float, float)); + METHOD(XonoticPicker, draw, void(entity)); ATTRIB(XonoticPicker, focusable, float, 1) ATTRIB(XonoticPicker, disabled, float, 0) ATTRIB(XonoticPicker, alpha, float, 1) @@ -17,10 +17,10 @@ CLASS(XonoticPicker, Item) ATTRIB(XonoticPicker, rows, float, 3) ATTRIB(XonoticPicker, columns, float, 2) - METHOD(XonoticPicker, moveFocus, void(entity, vector, vector)) - METHOD(XonoticPicker, cellSelect, void(entity, vector)) - METHOD(XonoticPicker, cellDraw, void(entity, vector, vector)) - METHOD(XonoticPicker, cellIsValid, bool(entity, vector)) + METHOD(XonoticPicker, moveFocus, void(entity, vector, vector)); + METHOD(XonoticPicker, cellSelect, void(entity, vector)); + METHOD(XonoticPicker, cellDraw, void(entity, vector, vector)); + METHOD(XonoticPicker, cellIsValid, bool(entity, vector)); ATTRIB(XonoticPicker, realCellSize, vector, '0 0 0') ATTRIB(XonoticPicker, selectedCell, vector, '-1 -1 0') ATTRIB(XonoticPicker, focusedCell, vector, '-1 -1 0') diff --git a/qcsrc/menu/xonotic/playerlist.qc b/qcsrc/menu/xonotic/playerlist.qc index 72fe69e116..9ba5d8738d 100644 --- a/qcsrc/menu/xonotic/playerlist.qc +++ b/qcsrc/menu/xonotic/playerlist.qc @@ -3,8 +3,8 @@ #include "listbox.qc" CLASS(XonoticPlayerList, XonoticListBox) ATTRIB(XonoticPlayerList, rowsPerItem, float, 1) - METHOD(XonoticPlayerList, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(XonoticPlayerList, drawListBoxItem, void(entity, int, vector, bool, bool)) + METHOD(XonoticPlayerList, resizeNotify, void(entity, vector, vector, vector, vector)); + METHOD(XonoticPlayerList, drawListBoxItem, void(entity, int, vector, bool, bool)); ATTRIB(XonoticPlayerList, allowFocusSound, float, 0) ATTRIB(XonoticPlayerList, realFontSize, vector, '0 0 0') ATTRIB(XonoticPlayerList, columnNameOrigin, float, 0) @@ -14,8 +14,8 @@ CLASS(XonoticPlayerList, XonoticListBox) ATTRIB(XonoticPlayerList, realUpperMargin, float, 0) ATTRIB(XonoticPlayerList, origin, vector, '0 0 0') ATTRIB(XonoticPlayerList, itemAbsSize, vector, '0 0 0') - METHOD(XonoticPlayerList, setPlayerList, void(entity, string)) - METHOD(XonoticPlayerList, getPlayerList, string(entity, float, float)) + METHOD(XonoticPlayerList, setPlayerList, void(entity, string)); + METHOD(XonoticPlayerList, getPlayerList, string(entity, float, float)); ATTRIB(XonoticPlayerList, playerList, float, -1) ATTRIB(XonoticPlayerList, selectionDoesntMatter, bool, true) ENDCLASS(XonoticPlayerList) diff --git a/qcsrc/menu/xonotic/playermodel.qc b/qcsrc/menu/xonotic/playermodel.qc index 760e8f93d9..c5ad21ec19 100644 --- a/qcsrc/menu/xonotic/playermodel.qc +++ b/qcsrc/menu/xonotic/playermodel.qc @@ -2,19 +2,19 @@ #define PLAYERMODEL_H #include "image.qc" CLASS(XonoticPlayerModelSelector, XonoticImage) - METHOD(XonoticPlayerModelSelector, configureXonoticPlayerModelSelector, void(entity)) - METHOD(XonoticPlayerModelSelector, loadCvars, void(entity)) - METHOD(XonoticPlayerModelSelector, saveCvars, void(entity)) - METHOD(XonoticPlayerModelSelector, draw, void(entity)) - METHOD(XonoticPlayerModelSelector, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(XonoticPlayerModelSelector, showNotify, void(entity)) + METHOD(XonoticPlayerModelSelector, configureXonoticPlayerModelSelector, void(entity)); + METHOD(XonoticPlayerModelSelector, loadCvars, void(entity)); + METHOD(XonoticPlayerModelSelector, saveCvars, void(entity)); + METHOD(XonoticPlayerModelSelector, draw, void(entity)); + METHOD(XonoticPlayerModelSelector, resizeNotify, void(entity, vector, vector, vector, vector)); + METHOD(XonoticPlayerModelSelector, showNotify, void(entity)); ATTRIB(XonoticPlayerModelSelector, currentModel, string, string_null) ATTRIB(XonoticPlayerModelSelector, currentSkin, float, 0) ATTRIB(XonoticPlayerModelSelector, currentModelImage, string, string_null) ATTRIB(XonoticPlayerModelSelector, currentModelTitle, string, string_null) ATTRIB(XonoticPlayerModelSelector, currentModelDescription, string, string_null) - METHOD(XonoticPlayerModelSelector, go, void(entity, float)) - METHOD(XonoticPlayerModelSelector, destroy, void(entity)) + METHOD(XonoticPlayerModelSelector, go, void(entity, float)); + METHOD(XonoticPlayerModelSelector, destroy, void(entity)); ATTRIB(XonoticPlayerModelSelector, origin, vector, '0 0 0') ATTRIB(XonoticPlayerModelSelector, size, vector, '0 0 0') ATTRIB(XonoticPlayerModelSelector, realFontSize, vector, '0 0 0') diff --git a/qcsrc/menu/xonotic/playlist.qc b/qcsrc/menu/xonotic/playlist.qc index 5dd7b6b926..0393215f8a 100644 --- a/qcsrc/menu/xonotic/playlist.qc +++ b/qcsrc/menu/xonotic/playlist.qc @@ -2,21 +2,21 @@ #define PLAYLIST_H #include "listbox.qc" CLASS(XonoticPlayList, XonoticListBox) - METHOD(XonoticPlayList, configureXonoticPlayList, void(entity)) + METHOD(XonoticPlayList, configureXonoticPlayList, void(entity)); ATTRIB(XonoticPlayList, rowsPerItem, float, 1) - METHOD(XonoticPlayList, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(XonoticPlayList, draw, void(entity)) - METHOD(XonoticPlayList, drawListBoxItem, void(entity, int, vector, bool, bool)) - METHOD(XonoticPlayList, stopSound, void(entity)) - METHOD(XonoticPlayList, startSound, void(entity, float)) - METHOD(XonoticPlayList, resumeSound, void(entity)) - METHOD(XonoticPlayList, pauseSound, void(entity)) - METHOD(XonoticPlayList, doubleClickListBoxItem, void(entity, float, vector)) - METHOD(XonoticPlayList, keyDown, float(entity, float, float, float)) - METHOD(XonoticPlayList, mouseDrag, float(entity, vector)) - - METHOD(XonoticPlayList, addToPlayList, void(entity, string)) - METHOD(XonoticPlayList, removeSelectedFromPlayList, void(entity)) + METHOD(XonoticPlayList, resizeNotify, void(entity, vector, vector, vector, vector)); + METHOD(XonoticPlayList, draw, void(entity)); + METHOD(XonoticPlayList, drawListBoxItem, void(entity, int, vector, bool, bool)); + METHOD(XonoticPlayList, stopSound, void(entity)); + METHOD(XonoticPlayList, startSound, void(entity, float)); + METHOD(XonoticPlayList, resumeSound, void(entity)); + METHOD(XonoticPlayList, pauseSound, void(entity)); + METHOD(XonoticPlayList, doubleClickListBoxItem, void(entity, float, vector)); + METHOD(XonoticPlayList, keyDown, float(entity, float, float, float)); + METHOD(XonoticPlayList, mouseDrag, float(entity, vector)); + + METHOD(XonoticPlayList, addToPlayList, void(entity, string)); + METHOD(XonoticPlayList, removeSelectedFromPlayList, void(entity)); ATTRIB(XonoticPlayList, playingTrack, float, -1) ATTRIB(XonoticPlayList, realFontSize, vector, '0 0 0') diff --git a/qcsrc/menu/xonotic/radiobutton.qc b/qcsrc/menu/xonotic/radiobutton.qc index 05c8238d48..1d2676f1f4 100644 --- a/qcsrc/menu/xonotic/radiobutton.qc +++ b/qcsrc/menu/xonotic/radiobutton.qc @@ -2,9 +2,9 @@ #define RADIOBUTTON_H #include "../item/radiobutton.qc" CLASS(XonoticRadioButton, RadioButton) - METHOD(XonoticRadioButton, configureXonoticRadioButton, void(entity, float, string, string, string)) - METHOD(XonoticRadioButton, draw, void(entity)) - METHOD(XonoticRadioButton, setChecked, void(entity, float)) + METHOD(XonoticRadioButton, configureXonoticRadioButton, void(entity, float, string, string, string)); + METHOD(XonoticRadioButton, draw, void(entity)); + METHOD(XonoticRadioButton, setChecked, void(entity, float)); ATTRIB(XonoticRadioButton, fontSize, float, SKINFONTSIZE_NORMAL) ATTRIB(XonoticRadioButton, image, string, SKINGFX_RADIOBUTTON) ATTRIB(XonoticRadioButton, color, vector, SKINCOLOR_RADIOBUTTON_N) @@ -16,8 +16,8 @@ CLASS(XonoticRadioButton, RadioButton) ATTRIB(XonoticRadioButton, cvarValue, string, string_null) ATTRIB(XonoticRadioButton, cvarOffValue, string, string_null) ATTRIB(XonoticRadioButton, getCvarValueFromCvar, float, 0) - METHOD(XonoticRadioButton, loadCvars, void(entity)) - METHOD(XonoticRadioButton, saveCvars, void(entity)) + METHOD(XonoticRadioButton, loadCvars, void(entity)); + METHOD(XonoticRadioButton, saveCvars, void(entity)); ATTRIB(XonoticRadioButton, alpha, float, SKINALPHA_TEXT) ATTRIB(XonoticRadioButton, disabledAlpha, float, SKINALPHA_DISABLED) diff --git a/qcsrc/menu/xonotic/rootdialog.qc b/qcsrc/menu/xonotic/rootdialog.qc index 209fcade83..f074a6286f 100644 --- a/qcsrc/menu/xonotic/rootdialog.qc +++ b/qcsrc/menu/xonotic/rootdialog.qc @@ -11,7 +11,7 @@ CLASS(XonoticRootDialog, XonoticDialog) ATTRIB(XonoticDialog, rows, float, 3) ATTRIB(XonoticDialog, columns, float, 2) */ - METHOD(XonoticRootDialog, close, void(entity)) + METHOD(XonoticRootDialog, close, void(entity)); ENDCLASS(XonoticRootDialog) #endif diff --git a/qcsrc/menu/xonotic/screenshotimage.qc b/qcsrc/menu/xonotic/screenshotimage.qc index f2eb0b00d7..f7a5c9b303 100644 --- a/qcsrc/menu/xonotic/screenshotimage.qc +++ b/qcsrc/menu/xonotic/screenshotimage.qc @@ -2,14 +2,14 @@ #define SCREENSHOTIMAGE_H #include "image.qc" CLASS(XonoticScreenshotImage, XonoticImage) - METHOD(XonoticScreenshotImage, configureXonoticScreenshotImage, void(entity)) - METHOD(XonoticScreenshotImage, load, void(entity, string)) - METHOD(XonoticScreenshotImage, draw, void(entity)) + METHOD(XonoticScreenshotImage, configureXonoticScreenshotImage, void(entity)); + METHOD(XonoticScreenshotImage, load, void(entity, string)); + METHOD(XonoticScreenshotImage, draw, void(entity)); ATTRIB(XonoticScreenshotImage, focusable, float, 1) // mousePress and mouseDrag work only if focusable is set - METHOD(XonoticScreenshotImage, mousePress, float(entity, vector)) - METHOD(XonoticScreenshotImage, mouseDrag, float(entity, vector)) - METHOD(XonoticScreenshotImage, mouseMove, float(entity, vector)) - METHOD(XonoticScreenshotImage, resizeNotify, void(entity, vector, vector, vector, vector)) + METHOD(XonoticScreenshotImage, mousePress, float(entity, vector)); + METHOD(XonoticScreenshotImage, mouseDrag, float(entity, vector)); + METHOD(XonoticScreenshotImage, mouseMove, float(entity, vector)); + METHOD(XonoticScreenshotImage, resizeNotify, void(entity, vector, vector, vector, vector)); ATTRIB(XonoticScreenshotImage, realFontSize, vector, '0 0 0') ATTRIB(XonoticScreenshotImage, fontSize, float, SKINFONTSIZE_NORMAL) ATTRIB(XonoticScreenshotImage, showTitle, float, 1) diff --git a/qcsrc/menu/xonotic/screenshotlist.qc b/qcsrc/menu/xonotic/screenshotlist.qc index 99780ed832..e7693a2e35 100644 --- a/qcsrc/menu/xonotic/screenshotlist.qc +++ b/qcsrc/menu/xonotic/screenshotlist.qc @@ -2,20 +2,20 @@ #define SCREENSHOTLIST_H #include "listbox.qc" CLASS(XonoticScreenshotList, XonoticListBox) - METHOD(XonoticScreenshotList, configureXonoticScreenshotList, void(entity)) + METHOD(XonoticScreenshotList, configureXonoticScreenshotList, void(entity)); ATTRIB(XonoticScreenshotList, rowsPerItem, float, 1) - METHOD(XonoticScreenshotList, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(XonoticScreenshotList, setSelected, void(entity, float)) - METHOD(XonoticScreenshotList, draw, void(entity)) - METHOD(XonoticScreenshotList, drawListBoxItem, void(entity, int, vector, bool, bool)) - METHOD(XonoticScreenshotList, getScreenshots, void(entity)) - METHOD(XonoticScreenshotList, previewScreenshot, void(entity)) - METHOD(XonoticScreenshotList, startScreenshot, void(entity)) - METHOD(XonoticScreenshotList, screenshotName, string(entity, float)) - METHOD(XonoticScreenshotList, doubleClickListBoxItem, void(entity, float, vector)) - METHOD(XonoticScreenshotList, keyDown, float(entity, float, float, float)) - METHOD(XonoticScreenshotList, destroy, void(entity)) - METHOD(XonoticScreenshotList, showNotify, void(entity)) + METHOD(XonoticScreenshotList, resizeNotify, void(entity, vector, vector, vector, vector)); + METHOD(XonoticScreenshotList, setSelected, void(entity, float)); + METHOD(XonoticScreenshotList, draw, void(entity)); + METHOD(XonoticScreenshotList, drawListBoxItem, void(entity, int, vector, bool, bool)); + METHOD(XonoticScreenshotList, getScreenshots, void(entity)); + METHOD(XonoticScreenshotList, previewScreenshot, void(entity)); + METHOD(XonoticScreenshotList, startScreenshot, void(entity)); + METHOD(XonoticScreenshotList, screenshotName, string(entity, float)); + METHOD(XonoticScreenshotList, doubleClickListBoxItem, void(entity, float, vector)); + METHOD(XonoticScreenshotList, keyDown, float(entity, float, float, float)); + METHOD(XonoticScreenshotList, destroy, void(entity)); + METHOD(XonoticScreenshotList, showNotify, void(entity)); ATTRIB(XonoticScreenshotList, listScreenshot, float, -1) ATTRIB(XonoticScreenshotList, realFontSize, vector, '0 0 0') ATTRIB(XonoticScreenshotList, columnNameOrigin, float, 0) @@ -33,9 +33,9 @@ CLASS(XonoticScreenshotList, XonoticListBox) ATTRIB(XonoticScreenshotList, screenshotBrowserDialog, entity, NULL) ATTRIB(XonoticScreenshotList, screenshotPreview, entity, NULL) ATTRIB(XonoticScreenshotList, screenshotViewerDialog, entity, NULL) - METHOD(XonoticScreenshotList, goScreenshot, void(entity, float)) - METHOD(XonoticScreenshotList, startSlideShow, void(entity)) - METHOD(XonoticScreenshotList, stopSlideShow, void(entity)) + METHOD(XonoticScreenshotList, goScreenshot, void(entity, float)); + METHOD(XonoticScreenshotList, startSlideShow, void(entity)); + METHOD(XonoticScreenshotList, stopSlideShow, void(entity)); ENDCLASS(XonoticScreenshotList) entity makeXonoticScreenshotList(); diff --git a/qcsrc/menu/xonotic/serverlist.qc b/qcsrc/menu/xonotic/serverlist.qc index 8d53be8fb5..c72db26bba 100644 --- a/qcsrc/menu/xonotic/serverlist.qc +++ b/qcsrc/menu/xonotic/serverlist.qc @@ -2,14 +2,14 @@ #define SERVERLIST_H #include "listbox.qc" CLASS(XonoticServerList, XonoticListBox) - METHOD(XonoticServerList, configureXonoticServerList, void(entity)) + METHOD(XonoticServerList, configureXonoticServerList, void(entity)); ATTRIB(XonoticServerList, rowsPerItem, float, 1) - METHOD(XonoticServerList, draw, void(entity)) - METHOD(XonoticServerList, drawListBoxItem, void(entity, int, vector, bool, bool)) - METHOD(XonoticServerList, doubleClickListBoxItem, void(entity, float, vector)) - METHOD(XonoticServerList, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(XonoticServerList, keyDown, float(entity, float, float, float)) - METHOD(XonoticServerList, toggleFavorite, void(entity, string)) + METHOD(XonoticServerList, draw, void(entity)); + METHOD(XonoticServerList, drawListBoxItem, void(entity, int, vector, bool, bool)); + METHOD(XonoticServerList, doubleClickListBoxItem, void(entity, float, vector)); + METHOD(XonoticServerList, resizeNotify, void(entity, vector, vector, vector, vector)); + METHOD(XonoticServerList, keyDown, float(entity, float, float, float)); + METHOD(XonoticServerList, toggleFavorite, void(entity, string)); ATTRIB(XonoticServerList, iconsSizeFactor, float, 0.85) @@ -30,8 +30,8 @@ CLASS(XonoticServerList, XonoticListBox) ATTRIB(XonoticServerList, lockedSelectedItem, bool, true) // initially keep selected the first item of the list, avoiding an unwanted scrolling ATTRIB(XonoticServerList, selectedServer, string, string_null) // to restore selected server when needed - METHOD(XonoticServerList, setSelected, void(entity, float)) - METHOD(XonoticServerList, setSortOrder, void(entity, float, float)) + METHOD(XonoticServerList, setSelected, void(entity, float)); + METHOD(XonoticServerList, setSortOrder, void(entity, float, float)); ATTRIB(XonoticServerList, filterShowEmpty, float, 1) ATTRIB(XonoticServerList, filterShowFull, float, 1) ATTRIB(XonoticServerList, filterString, string, string_null) @@ -39,10 +39,10 @@ CLASS(XonoticServerList, XonoticListBox) ATTRIB(XonoticServerList, ipAddressBox, entity, NULL) ATTRIB(XonoticServerList, favoriteButton, entity, NULL) ATTRIB(XonoticServerList, nextRefreshTime, float, 0) - METHOD(XonoticServerList, refreshServerList, void(entity, float)) // refresh mode: REFRESHSERVERLIST_* + METHOD(XonoticServerList, refreshServerList, void(entity, float)); // refresh mode: REFRESHSERVERLIST_* ATTRIB(XonoticServerList, needsRefresh, float, 1) - METHOD(XonoticServerList, focusEnter, void(entity)) - METHOD(XonoticServerList, positionSortButton, void(entity, entity, float, float, string, void(entity, entity))) + METHOD(XonoticServerList, focusEnter, void(entity)); + METHOD(XonoticServerList, positionSortButton, void(entity, entity, float, float, string, void(entity, entity))); ATTRIB(XonoticServerList, sortButton1, entity, NULL) ATTRIB(XonoticServerList, sortButton2, entity, NULL) ATTRIB(XonoticServerList, sortButton3, entity, NULL) @@ -59,10 +59,10 @@ CLASS(XonoticServerList, XonoticListBox) ATTRIB(XonoticServerList, seenIPv6, float, 0) ATTRIB(XonoticServerList, categoriesHeight, float, 1.25) - METHOD(XonoticServerList, getTotalHeight, float(entity)) - METHOD(XonoticServerList, getItemAtPos, float(entity, float)) - METHOD(XonoticServerList, getItemStart, float(entity, float)) - METHOD(XonoticServerList, getItemHeight, float(entity, float)) + METHOD(XonoticServerList, getTotalHeight, float(entity)); + METHOD(XonoticServerList, getItemAtPos, float(entity, float)); + METHOD(XonoticServerList, getItemStart, float(entity, float)); + METHOD(XonoticServerList, getItemHeight, float(entity, float)); ENDCLASS(XonoticServerList) entity makeXonoticServerList(); diff --git a/qcsrc/menu/xonotic/skinlist.qc b/qcsrc/menu/xonotic/skinlist.qc index d505a2894e..1a5f754db8 100644 --- a/qcsrc/menu/xonotic/skinlist.qc +++ b/qcsrc/menu/xonotic/skinlist.qc @@ -2,18 +2,18 @@ #define SKINLIST_H #include "listbox.qc" CLASS(XonoticSkinList, XonoticListBox) - METHOD(XonoticSkinList, configureXonoticSkinList, void(entity)) + METHOD(XonoticSkinList, configureXonoticSkinList, void(entity)); ATTRIB(XonoticSkinList, rowsPerItem, float, 4) - METHOD(XonoticSkinList, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(XonoticSkinList, drawListBoxItem, void(entity, int, vector, bool, bool)) - METHOD(XonoticSkinList, getSkins, void(entity)) - METHOD(XonoticSkinList, setSkin, void(entity)) - METHOD(XonoticSkinList, loadCvars, void(entity)) - METHOD(XonoticSkinList, saveCvars, void(entity)) - METHOD(XonoticSkinList, skinParameter, string(entity, float, float)) - METHOD(XonoticSkinList, doubleClickListBoxItem, void(entity, float, vector)) - METHOD(XonoticSkinList, keyDown, float(entity, float, float, float)) - METHOD(XonoticSkinList, destroy, void(entity)) + METHOD(XonoticSkinList, resizeNotify, void(entity, vector, vector, vector, vector)); + METHOD(XonoticSkinList, drawListBoxItem, void(entity, int, vector, bool, bool)); + METHOD(XonoticSkinList, getSkins, void(entity)); + METHOD(XonoticSkinList, setSkin, void(entity)); + METHOD(XonoticSkinList, loadCvars, void(entity)); + METHOD(XonoticSkinList, saveCvars, void(entity)); + METHOD(XonoticSkinList, skinParameter, string(entity, float, float)); + METHOD(XonoticSkinList, doubleClickListBoxItem, void(entity, float, vector)); + METHOD(XonoticSkinList, keyDown, float(entity, float, float, float)); + METHOD(XonoticSkinList, destroy, void(entity)); ATTRIB(XonoticSkinList, skinlist, float, -1) ATTRIB(XonoticSkinList, realFontSize, vector, '0 0 0') diff --git a/qcsrc/menu/xonotic/slider.qc b/qcsrc/menu/xonotic/slider.qc index d95cac7e9e..46379d5a35 100644 --- a/qcsrc/menu/xonotic/slider.qc +++ b/qcsrc/menu/xonotic/slider.qc @@ -2,8 +2,8 @@ #define SLIDER_H #include "../item/slider.qc" CLASS(XonoticSlider, Slider) - METHOD(XonoticSlider, configureXonoticSlider, void(entity, float, float, float, string)) - METHOD(XonoticSlider, setValue, void(entity, float)) + METHOD(XonoticSlider, configureXonoticSlider, void(entity, float, float, float, string)); + METHOD(XonoticSlider, setValue, void(entity, float)); ATTRIB(XonoticSlider, fontSize, float, SKINFONTSIZE_NORMAL) ATTRIB(XonoticSlider, valueSpace, float, SKINWIDTH_SLIDERTEXT) ATTRIB(XonoticSlider, image, string, SKINGFX_SLIDER) @@ -16,8 +16,8 @@ CLASS(XonoticSlider, Slider) ATTRIB(XonoticSlider, color2, vector, SKINCOLOR_SLIDER_S) ATTRIB(XonoticSlider, cvarName, string, string_null) - METHOD(XonoticSlider, loadCvars, void(entity)) - METHOD(XonoticSlider, saveCvars, void(entity)) + METHOD(XonoticSlider, loadCvars, void(entity)); + METHOD(XonoticSlider, saveCvars, void(entity)); ATTRIB(XonoticSlider, sendCvars, float, 0) ATTRIB(XonoticSlider, alpha, float, SKINALPHA_TEXT) diff --git a/qcsrc/menu/xonotic/slider_decibels.qc b/qcsrc/menu/xonotic/slider_decibels.qc index 29d2a86ac9..3d8cf1da44 100644 --- a/qcsrc/menu/xonotic/slider_decibels.qc +++ b/qcsrc/menu/xonotic/slider_decibels.qc @@ -4,9 +4,9 @@ #define SLIDER_DECIBELS_H #include "slider.qc" CLASS(XonoticDecibelsSlider, XonoticSlider) - METHOD(XonoticDecibelsSlider, loadCvars, void(entity)) - METHOD(XonoticDecibelsSlider, saveCvars, void(entity)) - METHOD(XonoticDecibelsSlider, valueToText, string(entity, float)) + METHOD(XonoticDecibelsSlider, loadCvars, void(entity)); + METHOD(XonoticDecibelsSlider, saveCvars, void(entity)); + METHOD(XonoticDecibelsSlider, valueToText, string(entity, float)); ENDCLASS(XonoticDecibelsSlider) entity makeXonoticDecibelsSlider(float, float, float, string); #endif diff --git a/qcsrc/menu/xonotic/slider_particles.qc b/qcsrc/menu/xonotic/slider_particles.qc index 9a098165e4..f7acdfeca3 100644 --- a/qcsrc/menu/xonotic/slider_particles.qc +++ b/qcsrc/menu/xonotic/slider_particles.qc @@ -2,9 +2,9 @@ #define SLIDER_PARTICLES_H #include "textslider.qc" CLASS(XonoticParticlesSlider, XonoticTextSlider) - METHOD(XonoticParticlesSlider, configureXonoticParticlesSlider, void(entity)) - METHOD(XonoticParticlesSlider, loadCvars, void(entity)) - METHOD(XonoticParticlesSlider, saveCvars, void(entity)) + METHOD(XonoticParticlesSlider, configureXonoticParticlesSlider, void(entity)); + METHOD(XonoticParticlesSlider, loadCvars, void(entity)); + METHOD(XonoticParticlesSlider, saveCvars, void(entity)); ENDCLASS(XonoticParticlesSlider) entity makeXonoticParticlesSlider(); #endif diff --git a/qcsrc/menu/xonotic/slider_picmip.qc b/qcsrc/menu/xonotic/slider_picmip.qc index f663f7dd6d..7c1dec045e 100644 --- a/qcsrc/menu/xonotic/slider_picmip.qc +++ b/qcsrc/menu/xonotic/slider_picmip.qc @@ -2,9 +2,9 @@ #define SLIDER_PICMIP_H #include "textslider.qc" CLASS(XonoticPicmipSlider, XonoticTextSlider) - METHOD(XonoticPicmipSlider, configureXonoticPicmipSlider, void(entity)) - METHOD(XonoticPicmipSlider, draw, void(entity)) - METHOD(XonoticPicmipSlider, autofix, void(entity)) + METHOD(XonoticPicmipSlider, configureXonoticPicmipSlider, void(entity)); + METHOD(XonoticPicmipSlider, draw, void(entity)); + METHOD(XonoticPicmipSlider, autofix, void(entity)); ATTRIB(XonoticPicmipSlider, have_s3tc, float, 0) ENDCLASS(XonoticPicmipSlider) entity makeXonoticPicmipSlider(); // note: you still need to call addValue and configureXonoticTextSliderValues! diff --git a/qcsrc/menu/xonotic/slider_resolution.qc b/qcsrc/menu/xonotic/slider_resolution.qc index 3d1f8302f1..1857621b49 100644 --- a/qcsrc/menu/xonotic/slider_resolution.qc +++ b/qcsrc/menu/xonotic/slider_resolution.qc @@ -2,12 +2,12 @@ #define SLIDER_RESOLUTION_H #include "textslider.qc" CLASS(XonoticResolutionSlider, XonoticTextSlider) - METHOD(XonoticResolutionSlider, configureXonoticResolutionSlider, void(entity)) - METHOD(XonoticResolutionSlider, loadResolutions, void(entity, float)) - METHOD(XonoticResolutionSlider, addResolution, void(entity, float, float, float)) - METHOD(XonoticResolutionSlider, loadCvars, void(entity)) - METHOD(XonoticResolutionSlider, saveCvars, void(entity)) - METHOD(XonoticResolutionSlider, draw, void(entity)) + METHOD(XonoticResolutionSlider, configureXonoticResolutionSlider, void(entity)); + METHOD(XonoticResolutionSlider, loadResolutions, void(entity, float)); + METHOD(XonoticResolutionSlider, addResolution, void(entity, float, float, float)); + METHOD(XonoticResolutionSlider, loadCvars, void(entity)); + METHOD(XonoticResolutionSlider, saveCvars, void(entity)); + METHOD(XonoticResolutionSlider, draw, void(entity)); ATTRIB(XonoticResolutionSlider, vid_fullscreen, float, -1) ATTRIB(XonoticResolutionSlider, maxAllowedWidth, float, 0) ATTRIB(XonoticResolutionSlider, maxAllowedHeight, float, 0) diff --git a/qcsrc/menu/xonotic/slider_sbfadetime.qc b/qcsrc/menu/xonotic/slider_sbfadetime.qc index 4d30c64f00..d64a990d23 100644 --- a/qcsrc/menu/xonotic/slider_sbfadetime.qc +++ b/qcsrc/menu/xonotic/slider_sbfadetime.qc @@ -2,9 +2,9 @@ #define SLIDER_SBFADETIME_H #include "textslider.qc" CLASS(XonoticScoreboardFadeTimeSlider, XonoticTextSlider) - METHOD(XonoticScoreboardFadeTimeSlider, configureXonoticScoreboardFadeTimeSlider, void(entity)) - METHOD(XonoticScoreboardFadeTimeSlider, loadCvars, void(entity)) - METHOD(XonoticScoreboardFadeTimeSlider, saveCvars, void(entity)) + METHOD(XonoticScoreboardFadeTimeSlider, configureXonoticScoreboardFadeTimeSlider, void(entity)); + METHOD(XonoticScoreboardFadeTimeSlider, loadCvars, void(entity)); + METHOD(XonoticScoreboardFadeTimeSlider, saveCvars, void(entity)); ENDCLASS(XonoticScoreboardFadeTimeSlider) entity makeXonoticScoreboardFadeTimeSlider(); #endif diff --git a/qcsrc/menu/xonotic/soundlist.qc b/qcsrc/menu/xonotic/soundlist.qc index 2b98c5fe52..6d28352680 100644 --- a/qcsrc/menu/xonotic/soundlist.qc +++ b/qcsrc/menu/xonotic/soundlist.qc @@ -2,16 +2,16 @@ #define SOUNDLIST_H #include "listbox.qc" CLASS(XonoticSoundList, XonoticListBox) - METHOD(XonoticSoundList, configureXonoticSoundList, void(entity)) + METHOD(XonoticSoundList, configureXonoticSoundList, void(entity)); ATTRIB(XonoticSoundList, rowsPerItem, float, 1) - METHOD(XonoticSoundList, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(XonoticSoundList, drawListBoxItem, void(entity, int, vector, bool, bool)) - METHOD(XonoticSoundList, getSounds, void(entity)) - METHOD(XonoticSoundList, soundName, string(entity, float)) - METHOD(XonoticSoundList, doubleClickListBoxItem, void(entity, float, vector)) - METHOD(XonoticSoundList, keyDown, float(entity, float, float, float)) - METHOD(XonoticSoundList, destroy, void(entity)) - METHOD(XonoticSoundList, showNotify, void(entity)) + METHOD(XonoticSoundList, resizeNotify, void(entity, vector, vector, vector, vector)); + METHOD(XonoticSoundList, drawListBoxItem, void(entity, int, vector, bool, bool)); + METHOD(XonoticSoundList, getSounds, void(entity)); + METHOD(XonoticSoundList, soundName, string(entity, float)); + METHOD(XonoticSoundList, doubleClickListBoxItem, void(entity, float, vector)); + METHOD(XonoticSoundList, keyDown, float(entity, float, float, float)); + METHOD(XonoticSoundList, destroy, void(entity)); + METHOD(XonoticSoundList, showNotify, void(entity)); ATTRIB(XonoticSoundList, listSound, float, -1) ATTRIB(XonoticSoundList, realFontSize, vector, '0 0 0') diff --git a/qcsrc/menu/xonotic/statslist.qc b/qcsrc/menu/xonotic/statslist.qc index bfa050abdb..db42177fbc 100644 --- a/qcsrc/menu/xonotic/statslist.qc +++ b/qcsrc/menu/xonotic/statslist.qc @@ -5,15 +5,15 @@ #define STATSLIST_H #include "listbox.qc" CLASS(XonoticStatsList, XonoticListBox) - METHOD(XonoticStatsList, configureXonoticStatsList, void(entity)) + METHOD(XonoticStatsList, configureXonoticStatsList, void(entity)); ATTRIB(XonoticStatsList, rowsPerItem, float, 1.4) - METHOD(XonoticStatsList, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(XonoticStatsList, drawListBoxItem, void(entity, int, vector, bool, bool)) - METHOD(XonoticStatsList, getStats, void(entity)) - METHOD(XonoticStatsList, doubleClickListBoxItem, void(entity, float, vector)) - METHOD(XonoticStatsList, keyDown, float(entity, float, float, float)) - METHOD(XonoticStatsList, destroy, void(entity)) - METHOD(XonoticStatsList, showNotify, void(entity)) + METHOD(XonoticStatsList, resizeNotify, void(entity, vector, vector, vector, vector)); + METHOD(XonoticStatsList, drawListBoxItem, void(entity, int, vector, bool, bool)); + METHOD(XonoticStatsList, getStats, void(entity)); + METHOD(XonoticStatsList, doubleClickListBoxItem, void(entity, float, vector)); + METHOD(XonoticStatsList, keyDown, float(entity, float, float, float)); + METHOD(XonoticStatsList, destroy, void(entity)); + METHOD(XonoticStatsList, showNotify, void(entity)); ATTRIB(XonoticStatsList, selectionDoesntMatter, bool, true) ATTRIB(XonoticStatsList, listStats, float, -1) diff --git a/qcsrc/menu/xonotic/tab.qc b/qcsrc/menu/xonotic/tab.qc index 0383c7aae6..03a5bc5fe7 100644 --- a/qcsrc/menu/xonotic/tab.qc +++ b/qcsrc/menu/xonotic/tab.qc @@ -8,7 +8,7 @@ CLASS(XonoticTab, Tab) ATTRIB(XonoticTab, rows, float, 3) ATTRIB(XonoticTab, columns, float, 2) */ - METHOD(XonoticTab, showNotify, void(entity)) + METHOD(XonoticTab, showNotify, void(entity)); ATTRIB(XonoticTab, marginTop, float, 0) // pixels ATTRIB(XonoticTab, marginBottom, float, 0) // pixels diff --git a/qcsrc/menu/xonotic/tabcontroller.qc b/qcsrc/menu/xonotic/tabcontroller.qc index c95424b177..ec30b9c2d4 100644 --- a/qcsrc/menu/xonotic/tabcontroller.qc +++ b/qcsrc/menu/xonotic/tabcontroller.qc @@ -2,8 +2,8 @@ #define TABCONTROLLER_H #include "../item/modalcontroller.qc" CLASS(XonoticTabController, ModalController) - METHOD(XonoticTabController, configureXonoticTabController, void(entity, float)) - METHOD(XonoticTabController, makeTabButton, entity(entity, string, entity)) + METHOD(XonoticTabController, configureXonoticTabController, void(entity, float)); + METHOD(XonoticTabController, makeTabButton, entity(entity, string, entity)); ATTRIB(XonoticTabController, rows, float, 0) ATTRIB(XonoticTabController, fontSize, float, SKINFONTSIZE_NORMAL) ATTRIB(XonoticTabController, image, string, SKINGFX_BUTTON) diff --git a/qcsrc/menu/xonotic/textlabel.qc b/qcsrc/menu/xonotic/textlabel.qc index e33182f2da..13d3077abf 100644 --- a/qcsrc/menu/xonotic/textlabel.qc +++ b/qcsrc/menu/xonotic/textlabel.qc @@ -2,8 +2,8 @@ #define TEXTLABEL_H #include "../item/label.qc" CLASS(XonoticTextLabel, Label) - METHOD(XonoticTextLabel, configureXonoticTextLabel, void(entity, float, string)) - METHOD(XonoticTextLabel, draw, void(entity)) + METHOD(XonoticTextLabel, configureXonoticTextLabel, void(entity, float, string)); + METHOD(XonoticTextLabel, draw, void(entity)); ATTRIB(XonoticTextLabel, fontSize, float, SKINFONTSIZE_NORMAL) ATTRIB(XonoticTextLabel, alpha, float, SKINALPHA_TEXT) ATTRIB(XonoticTextLabel, disabledAlpha, float, SKINALPHA_DISABLED) diff --git a/qcsrc/menu/xonotic/textslider.qc b/qcsrc/menu/xonotic/textslider.qc index 47d9eb44dc..8864654040 100644 --- a/qcsrc/menu/xonotic/textslider.qc +++ b/qcsrc/menu/xonotic/textslider.qc @@ -2,9 +2,9 @@ #define TEXTSLIDER_H #include "../item/textslider.qc" CLASS(XonoticTextSlider, TextSlider) - METHOD(XonoticTextSlider, configureXonoticTextSlider, void(entity, string)) - METHOD(XonoticTextSlider, setValue, void(entity, float)) - METHOD(XonoticTextSlider, configureXonoticTextSliderValues, void(entity)) + METHOD(XonoticTextSlider, configureXonoticTextSlider, void(entity, string)); + METHOD(XonoticTextSlider, setValue, void(entity, float)); + METHOD(XonoticTextSlider, configureXonoticTextSliderValues, void(entity)); ATTRIB(XonoticTextSlider, fontSize, float, SKINFONTSIZE_NORMAL) ATTRIB(XonoticTextSlider, valueSpace, float, SKINWIDTH_SLIDERTEXT) ATTRIB(XonoticTextSlider, image, string, SKINGFX_SLIDER) @@ -17,8 +17,8 @@ CLASS(XonoticTextSlider, TextSlider) ATTRIB(XonoticTextSlider, color2, vector, SKINCOLOR_SLIDER_S) ATTRIB(XonoticTextSlider, cvarName, string, string_null) - METHOD(XonoticTextSlider, loadCvars, void(entity)) - METHOD(XonoticTextSlider, saveCvars, void(entity)) + METHOD(XonoticTextSlider, loadCvars, void(entity)); + METHOD(XonoticTextSlider, saveCvars, void(entity)); ATTRIB(XonoticTextSlider, sendCvars, float, 0) ATTRIB(XonoticTextSlider, alpha, float, SKINALPHA_TEXT) diff --git a/qcsrc/menu/xonotic/weaponarenacheckbox.qc b/qcsrc/menu/xonotic/weaponarenacheckbox.qc index 2a8f3aa033..a0a962de24 100644 --- a/qcsrc/menu/xonotic/weaponarenacheckbox.qc +++ b/qcsrc/menu/xonotic/weaponarenacheckbox.qc @@ -2,14 +2,14 @@ #define WEAPONARENACHECKBOX_H #include "../item/checkbox.qc" CLASS(XonoticWeaponarenaCheckBox, CheckBox) - METHOD(XonoticWeaponarenaCheckBox, configureXonoticWeaponarenaCheckBox, void(entity, string, string)) - METHOD(XonoticWeaponarenaCheckBox, setChecked, void(entity, float)) + METHOD(XonoticWeaponarenaCheckBox, configureXonoticWeaponarenaCheckBox, void(entity, string, string)); + METHOD(XonoticWeaponarenaCheckBox, setChecked, void(entity, float)); ATTRIB(XonoticWeaponarenaCheckBox, fontSize, float, SKINFONTSIZE_NORMAL) ATTRIB(XonoticWeaponarenaCheckBox, image, string, SKINGFX_CHECKBOX) ATTRIB(XonoticWeaponarenaCheckBox, netname, string, string_null) - METHOD(XonoticWeaponarenaCheckBox, loadCvars, void(entity)) - METHOD(XonoticWeaponarenaCheckBox, saveCvars, void(entity)) + METHOD(XonoticWeaponarenaCheckBox, loadCvars, void(entity)); + METHOD(XonoticWeaponarenaCheckBox, saveCvars, void(entity)); ENDCLASS(XonoticWeaponarenaCheckBox) entity makeXonoticWeaponarenaCheckBox(string, string); #endif diff --git a/qcsrc/menu/xonotic/weaponslist.qc b/qcsrc/menu/xonotic/weaponslist.qc index f4bcf4feae..7834153dce 100644 --- a/qcsrc/menu/xonotic/weaponslist.qc +++ b/qcsrc/menu/xonotic/weaponslist.qc @@ -2,16 +2,16 @@ #define WEAPONSLIST_H #include "listbox.qc" CLASS(XonoticWeaponsList, XonoticListBox) - METHOD(XonoticWeaponsList, configureXonoticWeaponsList, void(entity)) - METHOD(XonoticWeaponsList, toString, string(entity)) + METHOD(XonoticWeaponsList, configureXonoticWeaponsList, void(entity)); + METHOD(XonoticWeaponsList, toString, string(entity)); ATTRIB(XonoticWeaponsList, rowsPerItem, float, 1) - METHOD(XonoticWeaponsList, draw, void(entity)) - METHOD(XonoticWeaponsList, drawListBoxItem, void(entity, int, vector, bool, bool)) - METHOD(XonoticWeaponsList, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(XonoticWeaponsList, keyDown, float(entity, float, float, float)) + METHOD(XonoticWeaponsList, draw, void(entity)); + METHOD(XonoticWeaponsList, drawListBoxItem, void(entity, int, vector, bool, bool)); + METHOD(XonoticWeaponsList, resizeNotify, void(entity, vector, vector, vector, vector)); + METHOD(XonoticWeaponsList, keyDown, float(entity, float, float, float)); ATTRIB(XonoticWeaponsList, realFontSize, vector, '0 0 0') ATTRIB(XonoticWeaponsList, realUpperMargin, float, 0) - METHOD(XonoticWeaponsList, mouseDrag, float(entity, vector)) + METHOD(XonoticWeaponsList, mouseDrag, float(entity, vector)); ENDCLASS(XonoticWeaponsList) entity makeXonoticWeaponsList(); void WeaponsList_MoveUp_Click(entity btn, entity me); diff --git a/qcsrc/server/antilag.qc b/qcsrc/server/antilag.qc index 9549501641..c51d3cf5ba 100644 --- a/qcsrc/server/antilag.qc +++ b/qcsrc/server/antilag.qc @@ -3,8 +3,7 @@ #elif defined(SVQC) #include "../dpdefs/progsdefs.qh" #include "../dpdefs/dpextensions.qh" - #include "../common/vehicles/sv_vehicles.qh" - #include "../common/vehicles/vehicles.qh" + #include "../common/vehicles/all.qh" #include "antilag.qh" #endif diff --git a/qcsrc/server/autocvars.qh b/qcsrc/server/autocvars.qh index 0b6d044753..9d6c49d2f0 100644 --- a/qcsrc/server/autocvars.qh +++ b/qcsrc/server/autocvars.qh @@ -433,11 +433,6 @@ bool autocvar_g_nix_with_powerups; bool autocvar_g_nodepthtestitems; bool autocvar_g_nodepthtestplayers; bool autocvar_g_norecoil; -float autocvar_g_onslaught_cp_buildhealth; -float autocvar_g_onslaught_cp_buildtime; -float autocvar_g_onslaught_cp_health; -float autocvar_g_onslaught_cp_regen; -float autocvar_g_onslaught_gen_health; int autocvar_g_pickup_cells_max; int autocvar_g_pickup_plasma_max; int autocvar_g_pickup_fuel_max; @@ -509,45 +504,10 @@ bool autocvar_g_turrets_nofire; bool autocvar_g_turrets_reloadcvars; float autocvar_g_turrets_targetscan_maxdelay; float autocvar_g_turrets_targetscan_mindelay; -float autocvar_g_turrets_unit_ewheel_speed_fast; -float autocvar_g_turrets_unit_ewheel_speed_slow; -float autocvar_g_turrets_unit_ewheel_speed_slower; -float autocvar_g_turrets_unit_ewheel_speed_stop; -float autocvar_g_turrets_unit_ewheel_turnrate; -float autocvar_g_turrets_unit_hellion_std_shot_speed_gain; -float autocvar_g_turrets_unit_hellion_std_shot_speed_max; -float autocvar_g_turrets_unit_hk_std_shot_speed; -float autocvar_g_turrets_unit_hk_std_shot_speed_accel; -float autocvar_g_turrets_unit_hk_std_shot_speed_accel2; -float autocvar_g_turrets_unit_hk_std_shot_speed_decel; -float autocvar_g_turrets_unit_hk_std_shot_speed_max; -float autocvar_g_turrets_unit_hk_std_shot_speed_turnrate; -float autocvar_g_turrets_unit_walker_speed_jump; -float autocvar_g_turrets_unit_walker_speed_roam; -float autocvar_g_turrets_unit_walker_speed_run; -float autocvar_g_turrets_unit_walker_speed_stop; -float autocvar_g_turrets_unit_walker_speed_swim; -float autocvar_g_turrets_unit_walker_speed_walk; -float autocvar_g_turrets_unit_walker_std_meele_dmg; -float autocvar_g_turrets_unit_walker_std_meele_force; -float autocvar_g_turrets_unit_walker_std_meele_range; -float autocvar_g_turrets_unit_walker_std_rocket_dmg; -float autocvar_g_turrets_unit_walker_std_rocket_force; -float autocvar_g_turrets_unit_walker_std_rocket_radius; -float autocvar_g_turrets_unit_walker_std_rocket_refire; -float autocvar_g_turrets_unit_walker_std_rocket_speed; -float autocvar_g_turrets_unit_walker_std_rocket_turnrate; -float autocvar_g_turrets_unit_walker_std_rockets_range; -float autocvar_g_turrets_unit_walker_std_rockets_range_min; -float autocvar_g_turrets_unit_walker_turn; -float autocvar_g_turrets_unit_walker_turn_walk; -float autocvar_g_turrets_unit_walker_turn_run; -float autocvar_g_turrets_unit_walker_turn_strafe; -float autocvar_g_turrets_unit_walker_turn_swim; bool autocvar_g_use_ammunition; bool autocvar_g_waypointeditor; int autocvar_g_waypointeditor_auto; -int autocvar_g_waypoints_for_items; +bool autocvar_g_waypoints_for_items; float autocvar_g_weapon_charge_colormod_blue_full; float autocvar_g_weapon_charge_colormod_blue_half; float autocvar_g_weapon_charge_colormod_green_full; @@ -834,6 +794,30 @@ float autocvar_g_spawn_near_teammate_distance; bool autocvar_g_spawn_near_teammate_ignore_spawnpoint; float autocvar_g_spawn_near_teammate_ignore_spawnpoint_delay; float autocvar_g_spawn_near_teammate_ignore_spawnpoint_delay_death; +float autocvar_g_onslaught_debug; +float autocvar_g_onslaught_teleport_wait; +bool autocvar_g_onslaught_spawn_at_controlpoints; +bool autocvar_g_onslaught_spawn_at_generator; +float autocvar_g_onslaught_cp_proxydecap; +float autocvar_g_onslaught_cp_proxydecap_distance = 512; +float autocvar_g_onslaught_cp_proxydecap_dps = 100; +float autocvar_g_onslaught_spawn_at_controlpoints_chance = 0.5; +float autocvar_g_onslaught_spawn_at_controlpoints_random; +float autocvar_g_onslaught_spawn_at_generator_chance; +float autocvar_g_onslaught_spawn_at_generator_random; +float autocvar_g_onslaught_cp_buildhealth; +float autocvar_g_onslaught_cp_buildtime; +float autocvar_g_onslaught_cp_health; +float autocvar_g_onslaught_cp_regen; +float autocvar_g_onslaught_gen_health; +float autocvar_g_onslaught_shield_force = 100; +float autocvar_g_onslaught_allow_vehicle_touch; +float autocvar_g_onslaught_round_timelimit; +float autocvar_g_onslaught_point_limit; +float autocvar_g_onslaught_warmup; +float autocvar_g_onslaught_teleport_radius; +float autocvar_g_onslaught_spawn_choose; +float autocvar_g_onslaught_click_radius; int autocvar_g_spawn_near_teammate_ignore_spawnpoint_check_health; bool autocvar_g_spawn_near_teammate_ignore_spawnpoint_closetodeath; bool autocvar_g_physics_clientselect; diff --git a/qcsrc/server/bot/havocbot/role_onslaught.qc b/qcsrc/server/bot/havocbot/role_onslaught.qc deleted file mode 100644 index 6924f51229..0000000000 --- a/qcsrc/server/bot/havocbot/role_onslaught.qc +++ /dev/null @@ -1,381 +0,0 @@ -#include "../../_all.qh" - -#include "havocbot.qh" - -#include "../bot.qh" -#include "../navigation.qh" -#include "../waypoints.qh" - -#include "../../mutators/mutators_include.qh" - -#include "../../../common/teams.qh" - -const int HAVOCBOT_ONS_ROLE_NONE = 0; -const int HAVOCBOT_ONS_ROLE_DEFENSE = 2; -const int HAVOCBOT_ONS_ROLE_ASSISTANT = 4; -const int HAVOCBOT_ONS_ROLE_OFFENSE = 8; - -.int havocbot_role_flags; -.float havocbot_attack_time; - -.void() havocbot_role; -.void() havocbot_previous_role; - -void() havocbot_role_ons_defense; -void() havocbot_role_ons_offense; -void() havocbot_role_ons_assistant; - -void(entity bot) havocbot_ons_reset_role; -void(float ratingscale, vector org, float sradius) havocbot_goalrating_items; -void(float ratingscale, vector org, float sradius) havocbot_goalrating_enemyplayers; - -.float isshielded; -.float iscaptured; -.float islinked; -.float isgenneighbor_blue, iscpneighbor_blue; -.float isgenneighbor_red, iscpneighbor_red; - -.entity havocbot_ons_target; - -void havocbot_goalrating_ons_offenseitems(float ratingscale, vector org, float sradius) -{ - entity head; - float t, i, c, needarmor = false, needweapons = false; - - // Needs armor/health? - if(self.health<100) - needarmor = true; - - // Needs weapons? - c = 0; - for(i = WEP_FIRST; i <= WEP_LAST ; ++i) - { - // Find weapon - if(self.weapons & WepSet_FromWeapon(i)) - if(++c>=4) - break; - } - - if(c<4) - needweapons = true; - - if(!needweapons && !needarmor) - return; - -// dprint(self.netname, " needs weapons ", ftos(needweapons) , "\n"); -// dprint(self.netname, " needs armor ", ftos(needarmor) , "\n"); - - // See what is around - head = findchainfloat(bot_pickup, true); - while (head) - { - // gather health and armor only - if (head.solid) - if ( ((head.health || head.armorvalue) && needarmor) || (head.weapons && needweapons ) ) - if (vlen(head.origin - org) < sradius) - { - t = head.bot_pickupevalfunc(self, head); - if (t > 0) - navigation_routerating(head, t * ratingscale, 500); - } - head = head.chain; - } -} - -void havocbot_role_ons_setrole(entity bot, float role) -{ - dprint(strcat(bot.netname," switched to ")); - switch(role) - { - case HAVOCBOT_ONS_ROLE_DEFENSE: - dprint("defense"); - bot.havocbot_role = havocbot_role_ons_defense; - bot.havocbot_role_flags = HAVOCBOT_ONS_ROLE_DEFENSE; - bot.havocbot_role_timeout = 0; - break; - case HAVOCBOT_ONS_ROLE_ASSISTANT: - dprint("assistant"); - bot.havocbot_role = havocbot_role_ons_assistant; - bot.havocbot_role_flags = HAVOCBOT_ONS_ROLE_ASSISTANT; - bot.havocbot_role_timeout = 0; - break; - case HAVOCBOT_ONS_ROLE_OFFENSE: - dprint("offense"); - bot.havocbot_role = havocbot_role_ons_offense; - bot.havocbot_role_flags = HAVOCBOT_ONS_ROLE_OFFENSE; - bot.havocbot_role_timeout = 0; - break; - } - dprint("\n"); -} - -float havocbot_ons_teamcount(entity bot, int role) -{ - float c = 0; - entity head; - - FOR_EACH_PLAYER(head) - if(head.team==self.team) - if(head.havocbot_role_flags & role) - ++c; - - return c; -} - -void havocbot_goalrating_ons_controlpoints_attack(float ratingscale) -{ - entity cp, cp1, cp2, best, pl, wp; - float radius, found, bestvalue, c; - - cp1 = cp2 = findchain(classname, "onslaught_controlpoint"); - - // Filter control points - for (; cp2; cp2 = cp2.chain) - { - cp2.wpcost = c = 0; - cp2.wpconsidered = false; - - if(cp2.isshielded) - continue; - - // Ignore owned controlpoints - if(self.team == NUM_TEAM_1) - { - if( (cp2.isgenneighbor_blue || cp2.iscpneighbor_blue) && !(cp2.isgenneighbor_red || cp2.iscpneighbor_red) ) - continue; - } - else if(self.team == NUM_TEAM_2) - { - if( (cp2.isgenneighbor_red || cp2.iscpneighbor_red) && !(cp2.isgenneighbor_blue || cp2.iscpneighbor_blue) ) - continue; - } - - // Count team mates interested in this control point - // (easier and cleaner than keeping counters per cp and teams) - FOR_EACH_PLAYER(pl) - if(pl.team==self.team) - if(pl.havocbot_role_flags & HAVOCBOT_ONS_ROLE_OFFENSE) - if(pl.havocbot_ons_target==cp2) - ++c; - - // NOTE: probably decrease the cost of attackable control points - cp2.wpcost = c; - cp2.wpconsidered = true; - } - - // We'll consider only the best case - bestvalue = 99999999999; - cp = world; - for (; cp1; cp1 = cp1.chain) - { - if (!cp1.wpconsidered) - continue; - - if(cp1.wpcost self.havocbot_role_timeout) - { - havocbot_ons_reset_role(self); - return; - } - - if(self.havocbot_attack_time>time) - return; - - if (self.bot_strategytime < time) - { - navigation_goalrating_start(); - havocbot_goalrating_enemyplayers(20000, self.origin, 650); - if(!havocbot_goalrating_ons_generator_attack(20000)) - havocbot_goalrating_ons_controlpoints_attack(20000); - havocbot_goalrating_ons_offenseitems(10000, self.origin, 10000); - navigation_goalrating_end(); - - self.bot_strategytime = time + autocvar_bot_ai_strategyinterval; - } -} - -void havocbot_role_ons_assistant() -{ - havocbot_ons_reset_role(self); -} - -void havocbot_role_ons_defense() -{ - havocbot_ons_reset_role(self); -} - -void havocbot_ons_reset_role(entity bot) -{ - entity head; - float c; - - if(self.deadflag != DEAD_NO) - return; - - bot.havocbot_ons_target = world; - - // TODO: Defend control points or generator if necessary - - // if there is only me on the team switch to offense - c = 0; - FOR_EACH_PLAYER(head) - if(head.team==self.team) - ++c; - - if(c==1) - { - havocbot_role_ons_setrole(bot, HAVOCBOT_ONS_ROLE_OFFENSE); - return; - } - - havocbot_role_ons_setrole(bot, HAVOCBOT_ONS_ROLE_OFFENSE); -} - -void havocbot_chooserole_ons() -{ - havocbot_ons_reset_role(self); -} diff --git a/qcsrc/server/bot/havocbot/role_onslaught.qh b/qcsrc/server/bot/havocbot/role_onslaught.qh deleted file mode 100644 index 3fca678fd8..0000000000 --- a/qcsrc/server/bot/havocbot/role_onslaught.qh +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef ROLE_ONSLAUGHT_H -#define ROLE_ONSLAUGHT_H -void havocbot_chooserole_ons(); -#endif diff --git a/qcsrc/server/bot/havocbot/roles.qc b/qcsrc/server/bot/havocbot/roles.qc index df6b8de912..bfa8f8436c 100644 --- a/qcsrc/server/bot/havocbot/roles.qc +++ b/qcsrc/server/bot/havocbot/roles.qc @@ -2,7 +2,6 @@ #include "havocbot.qh" #include "role_keyhunt.qh" -#include "role_onslaught.qh" #include "../bot.qh" #include "../navigation.qh" @@ -246,8 +245,6 @@ void havocbot_chooserole() return; else if (g_keyhunt) havocbot_chooserole_kh(); - else if (g_onslaught) - havocbot_chooserole_ons(); else // assume anything else is deathmatch havocbot_chooserole_dm(); } diff --git a/qcsrc/server/cl_client.qc b/qcsrc/server/cl_client.qc index 154a306043..6034923ca7 100644 --- a/qcsrc/server/cl_client.qc +++ b/qcsrc/server/cl_client.qc @@ -25,7 +25,7 @@ #include "bot/bot.qh" #include "bot/navigation.qh" -#include "../common/vehicles/sv_vehicles.qh" +#include "../common/vehicles/all.qh" #include "weapons/hitplot.qh" #include "weapons/weaponsystem.qh" diff --git a/qcsrc/server/cl_player.qc b/qcsrc/server/cl_player.qc index 9bc36c8df8..e3bb91e395 100644 --- a/qcsrc/server/cl_player.qc +++ b/qcsrc/server/cl_player.qc @@ -492,6 +492,7 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, int deathtyp dh = dh - max(self.health, 0); da = da - max(self.armorvalue, 0); WeaponStats_LogDamage(awep, abot, self.weapon, vbot, dh + da); + MUTATOR_CALLHOOK(PlayerDamaged, attacker, self, dh, da, hitloc); } if (self.health < 1) diff --git a/qcsrc/server/command/cmd.qc b/qcsrc/server/command/cmd.qc index 8672c3a292..c6d122eed3 100644 --- a/qcsrc/server/command/cmd.qc +++ b/qcsrc/server/command/cmd.qc @@ -16,7 +16,7 @@ #include "../mutators/mutators_include.qh" #ifdef SVQC - #include "../../common/vehicles/sv_vehicles.qh" + #include "../../common/vehicles/all.qh" #endif #include "../../common/constants.qh" @@ -384,7 +384,7 @@ void ClientCommand_physics(float request, float argc) case CMD_REQUEST_COMMAND: { string command = strtolower(argv(1)); - + if(!autocvar_g_physics_clientselect) { sprint(self, "Client physics selection is currently disabled.\n"); @@ -396,7 +396,7 @@ void ClientCommand_physics(float request, float argc) sprint(self, strcat("Available physics sets: \n\n", autocvar_g_physics_clientselect_options, " default\n")); return; } - + if(Physics_Valid(command) || command == "default") { stuffcmd(self, strcat("\nseta cl_physics ", command, "\nsendcvar cl_physics\n")); @@ -404,7 +404,7 @@ void ClientCommand_physics(float request, float argc) return; } } - + default: sprint(self, strcat("Current physics set: ^3", self.cvar_cl_physics, "\n")); case CMD_REQUEST_USAGE: diff --git a/qcsrc/server/controlpoint.qc b/qcsrc/server/controlpoint.qc new file mode 100644 index 0000000000..7cf81d762e --- /dev/null +++ b/qcsrc/server/controlpoint.qc @@ -0,0 +1,38 @@ +#include "controlpoint.qh" + +bool cpicon_send(entity to, int sf) +{ + WriteByte(MSG_ENTITY, ENT_CLIENT_CONTROLPOINT_ICON); + WriteByte(MSG_ENTITY, sf); + if(sf & CPSF_SETUP) + { + WriteCoord(MSG_ENTITY, self.origin_x); + WriteCoord(MSG_ENTITY, self.origin_y); + WriteCoord(MSG_ENTITY, self.origin_z); + + WriteByte(MSG_ENTITY, self.health); + WriteByte(MSG_ENTITY, self.max_health); + WriteByte(MSG_ENTITY, self.count); + WriteByte(MSG_ENTITY, self.team); + WriteByte(MSG_ENTITY, self.owner.iscaptured); + } + + if(sf & CPSF_STATUS) + { + WriteByte(MSG_ENTITY, self.team); + + if(self.health <= 0) + WriteByte(MSG_ENTITY, 0); + else + WriteByte(MSG_ENTITY, ceil((self.health / self.max_health) * 255)); + } + + return true; +} + +void onslaught_controlpoint_icon_link(entity e, void() spawnproc) +{ + Net_LinkEntity(e, true, 0, cpicon_send); + e.think = spawnproc; + e.nextthink = time * sys_frametime; +} diff --git a/qcsrc/server/controlpoint.qh b/qcsrc/server/controlpoint.qh new file mode 100644 index 0000000000..d76f0ea069 --- /dev/null +++ b/qcsrc/server/controlpoint.qh @@ -0,0 +1,10 @@ +#ifndef CONTROLPOINT_H +#define CONTROLPOINT_H + +const vector CPICON_MIN = '-32 -32 -9'; +const vector CPICON_MAX = '32 32 25'; + +const int CPSF_STATUS = 4; +const int CPSF_SETUP = 8; + +#endif diff --git a/qcsrc/server/g_damage.qc b/qcsrc/server/g_damage.qc index 61fe6ef87b..45c6ba1254 100644 --- a/qcsrc/server/g_damage.qc +++ b/qcsrc/server/g_damage.qc @@ -6,9 +6,8 @@ #include "scores.qh" #include "waypointsprites.qh" #include "spawnpoints.qh" -#include "tturrets/include/turrets_early.qh" #include "t_items.qh" -#include "../common/vehicles/sv_vehicles.qh" +#include "../common/vehicles/all.qh" #include "weapons/accuracy.qh" #include "weapons/csqcprojectile.qh" #include "weapons/selection.qh" @@ -850,7 +849,7 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, int d else victim = targ; - if(IS_PLAYER(victim) || IS_TURRET(victim) || IS_MONSTER(victim)) + if(IS_PLAYER(victim) || (IS_TURRET(victim) && victim.active == ACTIVE_ACTIVE) || IS_MONSTER(victim) || MUTATOR_CALLHOOK(PlayHitsound, victim)) { if(DIFF_TEAM(victim, attacker) && !victim.frozen) { diff --git a/qcsrc/server/g_damage.qh b/qcsrc/server/g_damage.qh index f291fff7a4..8d7db7f5dc 100644 --- a/qcsrc/server/g_damage.qh +++ b/qcsrc/server/g_damage.qh @@ -21,8 +21,8 @@ #include "../common/notifications.qh" #include "../common/deathtypes.qh" #include "mutators/mutators_include.qh" - #include "tturrets/include/turrets_early.qh" - #include "../common/vehicles/sv_vehicles.qh" + #include "../common/turrets/sv_turrets.qh" + #include "../common/vehicles/all.qh" #include "../csqcmodellib/sv_model.qh" #include "../common/playerstats.qh" #include "g_hook.qh" diff --git a/qcsrc/server/g_hook.qc b/qcsrc/server/g_hook.qc index e28b9b2ae7..71c32df398 100644 --- a/qcsrc/server/g_hook.qc +++ b/qcsrc/server/g_hook.qc @@ -8,7 +8,7 @@ #include "cl_player.qh" #include "command/common.qh" #include "round_handler.qh" -#include "../common/vehicles/sv_vehicles.qh" +#include "../common/vehicles/all.qh" #include "../common/constants.qh" #include "../common/util.qh" #include "../common/weapons/all.qh" diff --git a/qcsrc/server/g_world.qc b/qcsrc/server/g_world.qc index da2983c4a2..98147bfa3d 100644 --- a/qcsrc/server/g_world.qc +++ b/qcsrc/server/g_world.qc @@ -27,7 +27,7 @@ #include "../common/mapinfo.qh" #include "../common/monsters/all.qh" #include "../common/monsters/sv_monsters.qh" -#include "../common/vehicles/vehicles.qh" +#include "../common/vehicles/all.qh" #include "../common/notifications.qh" #include "../common/playerstats.qh" #include "../common/stats.qh" @@ -336,7 +336,6 @@ void cvar_changes_init() BADCVAR("pausable"); BADCVAR("sv_allow_fullbright"); BADCVAR("sv_checkforpacketsduringsleep"); - BADCVAR("sv_fraginfo"); BADCVAR("sv_timeout"); BADPREFIX("sv_timeout_"); BADPREFIX("crypto_"); @@ -347,7 +346,6 @@ void cvar_changes_init() BADPREFIX("prvm_"); BADPREFIX("skill_"); BADPREFIX("sv_cullentities_"); - BADPREFIX("sv_fraginfo_"); BADPREFIX("sv_maxidle_"); BADPREFIX("sv_vote_"); BADPREFIX("timelimit_"); @@ -562,10 +560,10 @@ void spawnfunc___init_dedicated_server(void) // needs to be done so early because of the constants they create static_init(); + CALL_ACCUMULATED_FUNCTION(RegisterTurrets); CALL_ACCUMULATED_FUNCTION(RegisterNotifications); CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes); CALL_ACCUMULATED_FUNCTION(RegisterEffects); - CALL_ACCUMULATED_FUNCTION(RegisterVehicles); MapInfo_Enumerate(); MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0); @@ -611,10 +609,10 @@ void spawnfunc_worldspawn (void) // needs to be done so early because of the constants they create static_init(); + CALL_ACCUMULATED_FUNCTION(RegisterTurrets); CALL_ACCUMULATED_FUNCTION(RegisterNotifications); CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes); CALL_ACCUMULATED_FUNCTION(RegisterEffects); - CALL_ACCUMULATED_FUNCTION(RegisterVehicles); ServerProgsDB = db_load(strcat("server.db", autocvar_sessionid)); @@ -1705,48 +1703,6 @@ void ClearWinners(void) head.winning = 0; } -// Onslaught winning condition: -// game terminates if only one team has a working generator (or none) -float WinningCondition_Onslaught() -{ - entity head; - float t1, t2, t3, t4; - - WinningConditionHelper(); // set worldstatus - - if(warmup_stage) - return WINNING_NO; - - // first check if the game has ended - t1 = t2 = t3 = t4 = 0; - head = find(world, classname, "onslaught_generator"); - while (head) - { - if (head.health > 0) - { - if (head.team == NUM_TEAM_1) t1 = 1; - if (head.team == NUM_TEAM_2) t2 = 1; - if (head.team == NUM_TEAM_3) t3 = 1; - if (head.team == NUM_TEAM_4) t4 = 1; - } - head = find(head, classname, "onslaught_generator"); - } - if (t1 + t2 + t3 + t4 < 2) - { - // game over, only one team remains (or none) - ClearWinners(); - if (t1) SetWinners(team, NUM_TEAM_1); - if (t2) SetWinners(team, NUM_TEAM_2); - if (t3) SetWinners(team, NUM_TEAM_3); - if (t4) SetWinners(team, NUM_TEAM_4); - dprint("Have a winner, ending game.\n"); - return WINNING_YES; - } - - // Two or more teams remain - return WINNING_NO; -} - // Assault winning condition: If the attackers triggered a round end (by fulfilling all objectives) // they win. Otherwise the defending team wins once the timelimit passes. void assault_new_round(); @@ -2115,9 +2071,6 @@ void CheckRules_World() return; } - if(g_onslaught) - timelimit = 0; // ONS has its own overtime rule - float wantovertime; wantovertime = 0; @@ -2203,10 +2156,6 @@ void CheckRules_World() { checkrules_status = WinningCondition_LMS(); } - else if (g_onslaught) - { - checkrules_status = WinningCondition_Onslaught(); // TODO remove this? - } else { checkrules_status = WinningCondition_Scores(fraglimit, leadlimit); diff --git a/qcsrc/server/generator.qc b/qcsrc/server/generator.qc new file mode 100644 index 0000000000..3e0b5171f2 --- /dev/null +++ b/qcsrc/server/generator.qc @@ -0,0 +1,37 @@ +#include "generator.qh" + +bool generator_send(entity to, int sf) +{ + WriteByte(MSG_ENTITY, ENT_CLIENT_GENERATOR); + WriteByte(MSG_ENTITY, sf); + if(sf & GSF_SETUP) + { + WriteCoord(MSG_ENTITY, self.origin_x); + WriteCoord(MSG_ENTITY, self.origin_y); + WriteCoord(MSG_ENTITY, self.origin_z); + + WriteByte(MSG_ENTITY, self.health); + WriteByte(MSG_ENTITY, self.max_health); + WriteByte(MSG_ENTITY, self.count); + WriteByte(MSG_ENTITY, self.team); + } + + if(sf & GSF_STATUS) + { + WriteByte(MSG_ENTITY, self.team); + + if(self.health <= 0) + WriteByte(MSG_ENTITY, 0); + else + WriteByte(MSG_ENTITY, ceil((self.health / self.max_health) * 255)); + } + + return true; +} + +void generator_link(void() spawnproc) +{ + Net_LinkEntity(self, true, 0, generator_send); + self.think = spawnproc; + self.nextthink = time; +} diff --git a/qcsrc/server/generator.qh b/qcsrc/server/generator.qh new file mode 100644 index 0000000000..cbdb36e05f --- /dev/null +++ b/qcsrc/server/generator.qh @@ -0,0 +1,10 @@ +#ifndef GENERATOR_H +#define GENERATOR_H +const vector GENERATOR_MIN = '-52 -52 -14'; +const vector GENERATOR_MAX = '52 52 75'; + +const int GSF_STATUS = 4; +const int GSF_SETUP = 8; + +bool generator_send(entity to, int sf); +#endif diff --git a/qcsrc/server/miscfunctions.qc b/qcsrc/server/miscfunctions.qc index d777282151..88744acc0b 100644 --- a/qcsrc/server/miscfunctions.qc +++ b/qcsrc/server/miscfunctions.qc @@ -6,7 +6,6 @@ #include "g_hook.qh" #include "ipban.qh" #include "mutators/mutators_include.qh" -#include "tturrets/include/turrets_early.qh" #include "t_items.qh" #include "weapons/accuracy.qh" #include "weapons/csqcprojectile.qh" @@ -21,6 +20,7 @@ #include "../common/triggers/subs.qh" #include "../common/urllib.qh" #include "../common/util.qh" +#include "../common/turrets/sv_turrets.qh" #include "../common/weapons/all.qh" #include "../csqcmodellib/sv_model.qh" #include "../warpzonelib/anglestransform.qh" @@ -249,9 +249,16 @@ string formatmessage(string msg) entity cursor_ent; string escape; string replacement; + string ammoitems; p = 0; n = 7; + ammoitems = "batteries"; + if(self.items & ITEM_Plasma.m_itemid) ammoitems = ITEM_Plasma.m_name; + if(self.items & ITEM_Cells.m_itemid) ammoitems = ITEM_Cells.m_name; + if(self.items & ITEM_Rockets.m_itemid) ammoitems = ITEM_Rockets.m_name; + if(self.items & ITEM_Shells.m_itemid) ammoitems = ITEM_Shells.m_name; + WarpZone_crosshair_trace(self); cursor = trace_endpos; cursor_ent = trace_ent; @@ -278,45 +285,27 @@ string formatmessage(string msg) replacement = substring(msg, p, 2); escape = substring(msg, p + 1, 1); - if (escape == "%") - replacement = "%"; - else if (escape == "\\") - replacement = "\\"; - else if (escape == "n") - replacement = "\n"; - else if (escape == "a") - replacement = ftos(floor(self.armorvalue)); - else if (escape == "h") - replacement = ftos(floor(self.health)); - else if (escape == "l") - replacement = NearestLocation(self.origin); - else if (escape == "y") - replacement = NearestLocation(cursor); - else if (escape == "d") - replacement = NearestLocation(self.death_origin); - else if (escape == "w") { - float wep; - wep = self.weapon; - if (!wep) - wep = self.switchweapon; - if (!wep) - wep = self.cnt; - replacement = WEP_NAME(wep); - } else if (escape == "W") { - if (self.items & ITEM_Shells.m_itemid) replacement = "shells"; - else if (self.items & ITEM_Bullets.m_itemid) replacement = "bullets"; - else if (self.items & ITEM_Rockets.m_itemid) replacement = "rockets"; - else if (self.items & ITEM_Cells.m_itemid) replacement = "cells"; - else if (self.items & ITEM_Plasma.m_itemid) replacement = "plasma"; - else replacement = "batteries"; // ;) - } else if (escape == "x") { - replacement = cursor_ent.netname; - if (replacement == "" || !cursor_ent) - replacement = "nothing"; - } else if (escape == "s") - replacement = ftos(vlen(self.velocity - self.velocity.z * '0 0 1')); - else if (escape == "S") - replacement = ftos(vlen(self.velocity)); + switch(escape) + { + case "%": replacement = "%"; break; + case "\\":replacement = "\\"; break; + case "n": replacement = "\n"; break; + case "a": replacement = ftos(floor(self.armorvalue)); break; + case "h": replacement = ftos(floor(self.health)); break; + case "l": replacement = NearestLocation(self.origin); break; + case "y": replacement = NearestLocation(cursor); break; + case "d": replacement = NearestLocation(self.death_origin); break; + case "w": replacement = WEP_NAME((!self.weapon) ? (!self.switchweapon ? self.cnt : self.switchweapon) : self.weapon); break; + case "W": replacement = ammoitems; break; + case "x": replacement = ((cursor_ent.netname == "" || !cursor_ent) ? "nothing" : cursor_ent.netname); break; + case "s": replacement = ftos(vlen(self.velocity - self.velocity_z * '0 0 1')); break; + case "S": replacement = ftos(vlen(self.velocity)); break; + default: + { + MUTATOR_CALLHOOK(FormatMessage, escape, replacement); + break; + } + } msg = strcat(substring(msg, 0, p), replacement, substring(msg, p+2, strlen(msg) - (p+2))); p = p + strlen(replacement); @@ -489,16 +478,6 @@ string playername(entity p) return p.netname; } -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; - return v; -} - float want_weapon(entity weaponinfo, float allguns) // WEAPONTODO: what still needs done? { int i = weaponinfo.weapon; @@ -999,11 +978,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) { diff --git a/qcsrc/server/miscfunctions.qh b/qcsrc/server/miscfunctions.qh index a3dd45e51e..3b57673736 100644 --- a/qcsrc/server/miscfunctions.qh +++ b/qcsrc/server/miscfunctions.qh @@ -8,6 +8,7 @@ #include "../common/constants.qh" #include "../common/mapinfo.qh" +#include "../common/turrets/turrets.qh" #ifdef RELEASE #define cvar_string_normal builtin_cvar_string @@ -48,8 +49,6 @@ void modeleffect_spawn(string m, float s, float f, vector o, vector v, vector an void shockwave_spawn(string m, vector org, float sz, float t1, float t2); -vector randompos(vector m1, vector m2); - void play2team(float t, string filename); void GetCvars_handleFloat(string thisname, float f, .float field, string name); @@ -159,7 +158,7 @@ const string STR_OBSERVER = "observer"; #define IS_MONSTER(v) (v.flags & FL_MONSTER) #define IS_VEHICLE(v) (v.vehicle_flags & VHF_ISVEHICLE) -#define IS_TURRET(v) (v.turrcaps_flags & TFL_TURRCAPS_ISTURRET) +#define IS_TURRET(v) (v.turret_flags & TUR_FLAG_ISTURRET) #define FOR_EACH_CLIENTSLOT(v) for(v = world; (v = nextent(v)) && (num_for_edict(v) <= maxclients); ) #define FOR_EACH_CLIENT(v) FOR_EACH_CLIENTSLOT(v) if(IS_CLIENT(v)) diff --git a/qcsrc/server/mutators/events.qh b/qcsrc/server/mutators/events.qh index ab652d1b4f..01cdd168f7 100644 --- a/qcsrc/server/mutators/events.qh +++ b/qcsrc/server/mutators/events.qh @@ -56,6 +56,13 @@ entity frag_target; int frag_deathtype; MUTATOR_HOOKABLE(PlayerDies, EV_PlayerDies); +/** called when a player dies to e.g. remove stuff he was carrying. */ +#define EV_PlayHitsound(i, o) \ + /**/ i(entity, frag_victim) \ + /**/ +entity frag_victim; +MUTATOR_HOOKABLE(PlayHitsound, EV_PlayHitsound); + /** called when a player presses the jump key */ #define EV_PlayerJump(i, o) \ /**/ i(float, player_multijump) \ @@ -95,6 +102,16 @@ MUTATOR_HOOKABLE(GetTeamCount, EV_GetTeamCount); /**/ MUTATOR_HOOKABLE(SpectateCopy, EV_SpectateCopy); +/** called when formatting a chat message to replace fancy functions */ +#define EV_FormatMessage(i, o) \ + /**/ i(string, format_escape) \ + /**/ i(string, format_replacement) \ + /**/ o(string, format_replacement) \ + /**/ +string format_escape; +string format_replacement; +MUTATOR_HOOKABLE(FormatMessage, EV_FormatMessage); + /** returns 1 if throwing the current weapon shall not be allowed */ MUTATOR_HOOKABLE(ForbidThrowCurrentWeapon, EV_NO_ARGS); @@ -253,6 +270,18 @@ float frag_mirrordamage; vector frag_force; MUTATOR_HOOKABLE(PlayerDamage_Calculate, EV_PlayerDamage_Calculate); +/** + * Called when a player is damaged + */ +#define EV_PlayerDamaged(i, o) \ + /** attacker */ i(entity, mutator_argv_entity_0) \ + /** target */ i(entity, mutator_argv_entity_1) \ + /** health */ i(int, mutator_argv_int_0) \ + /** armor */ i(int, mutator_argv_int_1) \ + /** location */ i(vector, mutator_argv_vector_0) \ + /**/ +MUTATOR_HOOKABLE(PlayerDamaged, EV_PlayerDamaged); + /** called at the end of player_powerups() in cl_client.qc, used for manipulating the values which are set by powerup items. */ #define EV_PlayerPowerups(i, o) \ /**/ i(entity, self) \ diff --git a/qcsrc/server/mutators/gamemode_assault.qc b/qcsrc/server/mutators/gamemode_assault.qc index 40f3528496..4700c57d87 100644 --- a/qcsrc/server/mutators/gamemode_assault.qc +++ b/qcsrc/server/mutators/gamemode_assault.qc @@ -170,7 +170,6 @@ void assault_roundstart_use() activator = self; SUB_UseTargets(); -#ifdef TTURRETS_ENABLED entity ent, oldself; //(Re)spawn all turrets @@ -186,12 +185,11 @@ void assault_roundstart_use() self = ent; // Dubbles as teamchange - turret_stdproc_respawn(); + turret_respawn(); ent = find(ent, classname, "turret_main"); } self = oldself; -#endif } void assault_wall_think() @@ -574,6 +572,11 @@ MUTATOR_HOOKFUNCTION(assault_BotRoles) return true; } +MUTATOR_HOOKFUNCTION(assault_PlayHitsound) +{ + return (frag_victim.classname == "func_assault_destructible"); +} + // scoreboard setup void assault_ScoreRules() { @@ -589,6 +592,7 @@ MUTATOR_DEFINITION(gamemode_assault) MUTATOR_HOOK(TurretSpawn, assault_TurretSpawn, CBC_ORDER_ANY); MUTATOR_HOOK(VehicleSpawn, assault_VehicleSpawn, CBC_ORDER_ANY); MUTATOR_HOOK(HavocBot_ChooseRole, assault_BotRoles, CBC_ORDER_ANY); + MUTATOR_HOOK(PlayHitsound, assault_PlayHitsound, CBC_ORDER_ANY); MUTATOR_ONADD { diff --git a/qcsrc/server/mutators/gamemode_ctf.qc b/qcsrc/server/mutators/gamemode_ctf.qc index 31d21116a4..87bbb3b991 100644 --- a/qcsrc/server/mutators/gamemode_ctf.qc +++ b/qcsrc/server/mutators/gamemode_ctf.qc @@ -4,7 +4,7 @@ #include "gamemode.qh" #ifdef SVQC -#include "../../common/vehicles/sv_vehicles.qh" +#include "../../common/vehicles/all.qh" #endif #include "../../warpzonelib/common.qh" @@ -418,7 +418,7 @@ void ctf_Handle_Capture(entity flag, entity toucher, int capturetype) if(!player) { return; } // without someone to give the reward to, we can't possibly cap if(CTF_DIFFTEAM(player, flag)) { return; } - + if(ctf_oneflag) for(tmp_entity = ctf_worldflaglist; tmp_entity; tmp_entity = tmp_entity.ctf_worldflagnext) if(SAME_TEAM(tmp_entity, player)) @@ -556,13 +556,13 @@ void ctf_Handle_Pickup(entity flag, entity player, int pickuptype) else { Send_Notification(NOTIF_ONE, player, MSG_CENTER, ((SAME_TEAM(player, flag)) ? CENTER_CTF_PICKUP_TEAM : CENTER_CTF_PICKUP_TEAM_ENEMY), Team_ColorCode(flag.team)); } Send_Notification(NOTIF_TEAM_EXCEPT, player, MSG_CHOICE, ((flag.team) ? APP_TEAM_ENT_4(flag, CHOICE_CTF_PICKUP_TEAM_) : CHOICE_CTF_PICKUP_TEAM_NEUTRAL), Team_ColorCode(player.team), player.netname); - + if(!flag.team) FOR_EACH_PLAYER(tmp_entity) if(tmp_entity != player) if(DIFF_TEAM(player, tmp_entity)) Send_Notification(NOTIF_ONE, tmp_entity, MSG_CHOICE, CHOICE_CTF_PICKUP_ENEMY_NEUTRAL, Team_ColorCode(player.team), player.netname); - + if(flag.team) FOR_EACH_PLAYER(tmp_entity) if(tmp_entity != player) @@ -1184,7 +1184,7 @@ void ctf_FlagSetup(int teamnumber, entity flag) // called when spawning a flag e default: flag.effects |= EF_DIMLIGHT; break; } } - + // flag placement if((flag.spawnflags & 1) || flag.noalign) // don't drop to floor, just stay at fixed location { @@ -1900,7 +1900,7 @@ MUTATOR_HOOKFUNCTION(ctf_PlayerPreThink) int t = 0, t2 = 0, t3 = 0; // initially clear items so they can be set as necessary later. - self.ctf_flagstatus &= ~(CTF_RED_FLAG_CARRYING | CTF_RED_FLAG_TAKEN | CTF_RED_FLAG_LOST + self.ctf_flagstatus &= ~(CTF_RED_FLAG_CARRYING | CTF_RED_FLAG_TAKEN | CTF_RED_FLAG_LOST | CTF_BLUE_FLAG_CARRYING | CTF_BLUE_FLAG_TAKEN | CTF_BLUE_FLAG_LOST | CTF_YELLOW_FLAG_CARRYING | CTF_YELLOW_FLAG_TAKEN | CTF_YELLOW_FLAG_LOST | CTF_PINK_FLAG_CARRYING | CTF_PINK_FLAG_TAKEN | CTF_PINK_FLAG_LOST @@ -1923,7 +1923,7 @@ MUTATOR_HOOKFUNCTION(ctf_PlayerPreThink) { if((flag.owner == self) || (flag.pass_sender == self)) self.ctf_flagstatus |= t; // carrying: self is currently carrying the flag - else + else self.ctf_flagstatus |= t2; // taken: someone else is carrying the flag break; } @@ -2325,13 +2325,13 @@ void spawnfunc_item_flag_team2() /*QUAKED spawnfunc_item_flag_team3 (0 0.5 0.8) (-48 -48 -37) (48 48 37) CTF flag for team three (Yellow). -Keys: -"angle" Angle the flag will point (minus 90 degrees)... +Keys: +"angle" Angle the flag will point (minus 90 degrees)... "model" model to use, note this needs red, blue yellow and pink as skins 0, 1, 2 and 3... "noise" sound played when flag is picked up... "noise1" sound played when flag is returned by a teammate... "noise2" sound played when flag is captured... -"noise3" sound played when flag is lost in the field and respawns itself... +"noise3" sound played when flag is lost in the field and respawns itself... "noise4" sound played when flag is dropped by a player... "noise5" sound played when flag touches the ground... */ void spawnfunc_item_flag_team3() @@ -2343,13 +2343,13 @@ void spawnfunc_item_flag_team3() /*QUAKED spawnfunc_item_flag_team4 (0 0.5 0.8) (-48 -48 -37) (48 48 37) CTF flag for team four (Pink). -Keys: -"angle" Angle the flag will point (minus 90 degrees)... +Keys: +"angle" Angle the flag will point (minus 90 degrees)... "model" model to use, note this needs red, blue yellow and pink as skins 0, 1, 2 and 3... "noise" sound played when flag is picked up... "noise1" sound played when flag is returned by a teammate... "noise2" sound played when flag is captured... -"noise3" sound played when flag is lost in the field and respawns itself... +"noise3" sound played when flag is lost in the field and respawns itself... "noise4" sound played when flag is dropped by a player... "noise5" sound played when flag touches the ground... */ void spawnfunc_item_flag_team4() @@ -2361,13 +2361,13 @@ void spawnfunc_item_flag_team4() /*QUAKED spawnfunc_item_flag_neutral (0 0.5 0.8) (-48 -48 -37) (48 48 37) CTF flag (Neutral). -Keys: -"angle" Angle the flag will point (minus 90 degrees)... +Keys: +"angle" Angle the flag will point (minus 90 degrees)... "model" model to use, note this needs red, blue yellow and pink as skins 0, 1, 2 and 3... "noise" sound played when flag is picked up... "noise1" sound played when flag is returned by a teammate... "noise2" sound played when flag is captured... -"noise3" sound played when flag is lost in the field and respawns itself... +"noise3" sound played when flag is lost in the field and respawns itself... "noise4" sound played when flag is dropped by a player... "noise5" sound played when flag touches the ground... */ void spawnfunc_item_flag_neutral() diff --git a/qcsrc/server/mutators/gamemode_onslaught.qc b/qcsrc/server/mutators/gamemode_onslaught.qc index 7c46e29f8e..fb6e0c10ee 100644 --- a/qcsrc/server/mutators/gamemode_onslaught.qc +++ b/qcsrc/server/mutators/gamemode_onslaught.qc @@ -1,235 +1,212 @@ #include "../_all.qh" #include "gamemode.qh" +#include "../controlpoint.qh" +#include "../generator.qh" -float autocvar_g_onslaught_spawn_at_controlpoints; -float autocvar_g_onslaught_spawn_at_generator; -float autocvar_g_onslaught_cp_proxydecap; -float autocvar_g_onslaught_cp_proxydecap_distance = 512; -float autocvar_g_onslaught_cp_proxydecap_dps = 100; +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; + return v; +} -void onslaught_generator_updatesprite(entity e); -void onslaught_controlpoint_updatesprite(entity e); -void onslaught_link_checkupdate(); +// ======================= +// CaptureShield Functions +// ======================= -.entity sprite; -.string target2; -.float iscaptured; -.float islinked; -.float isgenneighbor_red; -.float isgenneighbor_blue; -.float iscpneighbor_red; -.float iscpneighbor_blue; -.float isshielded; -.float lasthealth; -.float lastteam; -.float lastshielded; -.float lastcaptured; +bool ons_CaptureShield_Customize() +{ + entity e = WaypointSprite_getviewentity(other); -entity ons_red_generator; -entity ons_blue_generator; + if(!self.enemy.isshielded && (ons_ControlPoint_Attackable(self.enemy, e.team) > 0 || self.enemy.classname != "onslaught_controlpoint")) { return false; } + if(SAME_TEAM(self, e)) { return false; } -void ons_gib_damage (entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector vforce) -{ - self.velocity = self.velocity + vforce; + return true; } -.float giblifetime; -void ons_throwgib_think() +void ons_CaptureShield_Touch() { - float d; + if(!self.enemy.isshielded && (ons_ControlPoint_Attackable(self.enemy, other.team) > 0 || self.enemy.classname != "onslaught_controlpoint")) { return; } + if(!IS_PLAYER(other)) { return; } + if(SAME_TEAM(other, self)) { return; } - self.nextthink = time + 0.05; + vector mymid = (self.absmin + self.absmax) * 0.5; + vector othermid = (other.absmin + other.absmax) * 0.5; - d = self.giblifetime - time; + Damage(other, self, self, 0, DEATH_HURTTRIGGER, mymid, normalize(othermid - mymid) * ons_captureshield_force); - if(d<0) + if(IS_REAL_CLIENT(other)) { - self.think = SUB_Remove; - return; + play2(other, "onslaught/damageblockedbyshield.wav"); + + if(self.enemy.classname == "onslaught_generator") + Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_ONS_GENERATOR_SHIELDED); + else + Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_ONS_CONTROLPOINT_SHIELDED); } - if(d<1) - self.alpha = d; +} - if(d>2) - if(random()<0.6) - Send_Effect("onslaught_generator_gib_flame", self.origin, '0 0 0', 1); +void ons_CaptureShield_Reset() +{ + self.colormap = self.enemy.colormap; + self.team = self.enemy.team; } -void ons_throwgib(vector v_from, vector v_to, string smodel, float f_lifetime, float b_burn) +void ons_CaptureShield_Spawn(entity generator, bool is_generator) { - entity gib; + entity shield = spawn(); + + shield.enemy = generator; + shield.team = generator.team; + shield.colormap = generator.colormap; + shield.reset = ons_CaptureShield_Reset; + shield.touch = ons_CaptureShield_Touch; + shield.customizeentityforclient = ons_CaptureShield_Customize; + shield.classname = "ons_captureshield"; + shield.effects = EF_ADDITIVE; + shield.movetype = MOVETYPE_NOCLIP; + shield.solid = SOLID_TRIGGER; + shield.avelocity = '7 0 11'; + shield.scale = 1; + shield.model = ((is_generator) ? "models/onslaught/generator_shield.md3" : "models/onslaught/controlpoint_shield.md3"); + + precache_model(shield.model); + setorigin(shield, generator.origin); + setmodel(shield, shield.model); + setsize(shield, shield.scale * shield.mins, shield.scale * shield.maxs); +} - gib = spawn(); - setmodel(gib, smodel); - setorigin(gib, v_from); - gib.solid = SOLID_BBOX; - gib.movetype = MOVETYPE_BOUNCE; - gib.takedamage = DAMAGE_YES; - gib.event_damage = ons_gib_damage; - gib.health = -1; - gib.effects = EF_LOWPRECISION; - gib.flags = FL_NOTARGET; - gib.velocity = v_to; - gib.giblifetime = time + f_lifetime; +// ========== +// Junk Pile +// ========== - if (b_burn) +void ons_debug(string input) +{ + switch(autocvar_g_onslaught_debug) { - gib.think = ons_throwgib_think; - gib.nextthink = time + 0.05; + case 1: dprint(input); break; + case 2: print(input); break; } - else - SUB_SetFade(gib, gib.giblifetime, 2); +} + +void setmodel_fixsize(entity e, string m) +{ + setmodel(e, m); + FixSize(e); } void onslaught_updatelinks() { - entity l, links; - float stop, t1, t2, t3, t4; + entity l; // first check if the game has ended - dprint("--- updatelinks ---\n"); - links = findchain(classname, "onslaught_link"); + ons_debug("--- updatelinks ---\n"); // mark generators as being shielded and networked - l = findchain(classname, "onslaught_generator"); - while (l) + for(l = ons_worldgeneratorlist; l; l = l.ons_worldgeneratornext) { if (l.iscaptured) - dprint(etos(l), " (generator) belongs to team ", ftos(l.team), "\n"); + ons_debug(strcat(etos(l), " (generator) belongs to team ", ftos(l.team), "\n")); else - dprint(etos(l), " (generator) is destroyed\n"); + ons_debug(strcat(etos(l), " (generator) is destroyed\n")); l.islinked = l.iscaptured; l.isshielded = l.iscaptured; - l = l.chain; + l.sprite.SendFlags |= 16; } // mark points as shielded and not networked - l = findchain(classname, "onslaught_controlpoint"); - while (l) + for(l = ons_worldcplist; l; l = l.ons_worldcpnext) { l.islinked = false; l.isshielded = true; - l.isgenneighbor_red = false; - l.isgenneighbor_blue = false; - l.iscpneighbor_red = false; - l.iscpneighbor_blue = false; - dprint(etos(l), " (point) belongs to team ", ftos(l.team), "\n"); - l = l.chain; + int i; + for(i = 0; i < 17; ++i) { l.isgenneighbor[i] = false; l.iscpneighbor[i] = false; } + ons_debug(strcat(etos(l), " (point) belongs to team ", ftos(l.team), "\n")); + l.sprite.SendFlags |= 16; } // flow power outward from the generators through the network - l = links; - while (l) - { - dprint(etos(l), " (link) connects ", etos(l.goalentity), " with ", etos(l.enemy), "\n"); - l = l.chain; - } - stop = false; + bool stop = false; while (!stop) { stop = true; - l = links; - while (l) + for(l = ons_worldlinklist; l; l = l.ons_worldlinknext) { // if both points are captured by the same team, and only one of // them is powered, mark the other one as powered as well if (l.enemy.iscaptured && l.goalentity.iscaptured) if (l.enemy.islinked != l.goalentity.islinked) - if (l.enemy.team == l.goalentity.team) + if(SAME_TEAM(l.enemy, l.goalentity)) { if (!l.goalentity.islinked) { stop = false; l.goalentity.islinked = true; - dprint(etos(l), " (link) is marking ", etos(l.goalentity), " (point) because its team matches ", etos(l.enemy), " (point)\n"); + ons_debug(strcat(etos(l), " (link) is marking ", etos(l.goalentity), " (point) because its team matches ", etos(l.enemy), " (point)\n")); } else if (!l.enemy.islinked) { stop = false; l.enemy.islinked = true; - dprint(etos(l), " (link) is marking ", etos(l.enemy), " (point) because its team matches ", etos(l.goalentity), " (point)\n"); + ons_debug(strcat(etos(l), " (link) is marking ", etos(l.enemy), " (point) because its team matches ", etos(l.goalentity), " (point)\n")); } } - l = l.chain; } } // now that we know which points are powered we can mark their neighbors // as unshielded if team differs - l = links; - while (l) + for(l = ons_worldlinklist; l; l = l.ons_worldlinknext) { if (l.goalentity.islinked) { - if (l.goalentity.team != l.enemy.team) + if(DIFF_TEAM(l.goalentity, l.enemy)) { - dprint(etos(l), " (link) is unshielding ", etos(l.enemy), " (point) because its team does not match ", etos(l.goalentity), " (point)\n"); + ons_debug(strcat(etos(l), " (link) is unshielding ", etos(l.enemy), " (point) because its team does not match ", etos(l.goalentity), " (point)\n")); l.enemy.isshielded = false; } if(l.goalentity.classname == "onslaught_generator") - { - if(l.goalentity.team == NUM_TEAM_1) - l.enemy.isgenneighbor_red = true; - else if(l.goalentity.team == NUM_TEAM_2) - l.enemy.isgenneighbor_blue = true; - } + l.enemy.isgenneighbor[l.goalentity.team] = true; else - { - if(l.goalentity.team == NUM_TEAM_1) - l.enemy.iscpneighbor_red = true; - else if(l.goalentity.team == NUM_TEAM_2) - l.enemy.iscpneighbor_blue = true; - } + l.enemy.iscpneighbor[l.goalentity.team] = true; } if (l.enemy.islinked) { - if (l.goalentity.team != l.enemy.team) + if(DIFF_TEAM(l.goalentity, l.enemy)) { - dprint(etos(l), " (link) is unshielding ", etos(l.goalentity), " (point) because its team does not match ", etos(l.enemy), " (point)\n"); + ons_debug(strcat(etos(l), " (link) is unshielding ", etos(l.goalentity), " (point) because its team does not match ", etos(l.enemy), " (point)\n")); l.goalentity.isshielded = false; } if(l.enemy.classname == "onslaught_generator") - { - if(l.enemy.team == NUM_TEAM_1) - l.goalentity.isgenneighbor_red = true; - else if(l.enemy.team == NUM_TEAM_2) - l.goalentity.isgenneighbor_blue = true; - } + l.goalentity.isgenneighbor[l.enemy.team] = true; else - { - if(l.enemy.team == NUM_TEAM_1) - l.goalentity.iscpneighbor_red = true; - else if(l.enemy.team == NUM_TEAM_2) - l.goalentity.iscpneighbor_blue = true; - } + l.goalentity.iscpneighbor[l.enemy.team] = true; } - l = l.chain; } - // now update the takedamage and alpha variables on generator shields - l = findchain(classname, "onslaught_generator"); - while (l) + // now update the generators + for(l = ons_worldgeneratorlist; l; l = l.ons_worldgeneratornext) { if (l.isshielded) { - dprint(etos(l), " (generator) is shielded\n"); - l.enemy.alpha = 1; + ons_debug(strcat(etos(l), " (generator) is shielded\n")); l.takedamage = DAMAGE_NO; l.bot_attack = false; } else { - dprint(etos(l), " (generator) is not shielded\n"); - l.enemy.alpha = -1; + ons_debug(strcat(etos(l), " (generator) is not shielded\n")); l.takedamage = DAMAGE_AIM; l.bot_attack = true; } - l = l.chain; + + ons_Generator_UpdateSprite(l); } // now update the takedamage and alpha variables on control point icons - l = findchain(classname, "onslaught_controlpoint"); - while (l) + for(l = ons_worldcplist; l; l = l.ons_worldcpnext) { if (l.isshielded) { - dprint(etos(l), " (point) is shielded\n"); - l.enemy.alpha = 1; + ons_debug(strcat(etos(l), " (point) is shielded\n")); if (l.goalentity) { l.goalentity.takedamage = DAMAGE_NO; @@ -238,105 +215,98 @@ void onslaught_updatelinks() } else { - dprint(etos(l), " (point) is not shielded\n"); - l.enemy.alpha = -1; + ons_debug(strcat(etos(l), " (point) is not shielded\n")); if (l.goalentity) { l.goalentity.takedamage = DAMAGE_AIM; l.goalentity.bot_attack = true; } } - onslaught_controlpoint_updatesprite(l); - l = l.chain; + ons_ControlPoint_UpdateSprite(l); } - // count generators owned by each team - t1 = t2 = t3 = t4 = 0; - l = findchain(classname, "onslaught_generator"); - while (l) + l = findchain(classname, "ons_captureshield"); + while(l) { - if (l.iscaptured) - { - if (l.team == NUM_TEAM_1) t1 = 1; - if (l.team == NUM_TEAM_2) t2 = 1; - if (l.team == NUM_TEAM_3) t3 = 1; - if (l.team == NUM_TEAM_4) t4 = 1; - } - onslaught_generator_updatesprite(l); + l.team = l.enemy.team; + l.colormap = l.enemy.colormap; l = l.chain; } - // see if multiple teams remain (if not, it's game over) - if (t1 + t2 + t3 + t4 < 2) - dprint("--- game over ---\n"); - else - dprint("--- done updating links ---\n"); } -float onslaught_controlpoint_can_be_linked(entity cp, float t) + +// =================== +// Main Link Functions +// =================== + +bool ons_Link_Send(entity to, int sendflags) { - if(t == NUM_TEAM_1) + WriteByte(MSG_ENTITY, ENT_CLIENT_RADARLINK); + WriteByte(MSG_ENTITY, sendflags); + if(sendflags & 1) { - if(cp.isgenneighbor_red) - return 2; - if(cp.iscpneighbor_red) - return 1; + WriteCoord(MSG_ENTITY, self.goalentity.origin_x); + WriteCoord(MSG_ENTITY, self.goalentity.origin_y); + WriteCoord(MSG_ENTITY, self.goalentity.origin_z); } - else if(t == NUM_TEAM_2) + if(sendflags & 2) { - if(cp.isgenneighbor_blue) - return 2; - if(cp.iscpneighbor_blue) - return 1; + WriteCoord(MSG_ENTITY, self.enemy.origin_x); + WriteCoord(MSG_ENTITY, self.enemy.origin_y); + WriteCoord(MSG_ENTITY, self.enemy.origin_z); } - return 0; - /* - entity e; - // check to see if this player has a legitimate claim to capture this - // control point - more specifically that there is a captured path of - // points leading back to the team generator - e = findchain(classname, "onslaught_link"); - while (e) - { - if (e.goalentity == cp) - { - dprint(etos(e), " (link) connects to ", etos(e.enemy), " (point)"); - if (e.enemy.islinked) - { - dprint(" which is linked"); - if (e.enemy.team == t) + if(sendflags & 4) { - dprint(" and has the correct team!\n"); - return 1; - } - else - dprint(" but has the wrong team\n"); - } - else - dprint("\n"); + WriteByte(MSG_ENTITY, self.clientcolors); // which is goalentity's color + enemy's color * 16 } - else if (e.enemy == cp) - { - dprint(etos(e), " (link) connects to ", etos(e.goalentity), " (point)"); - if (e.goalentity.islinked) - { - dprint(" which is linked"); - if (e.goalentity.team == t) + return true; +} + +void ons_Link_CheckUpdate() +{ + // TODO check if the two sides have moved (currently they won't move anyway) + float cc = 0, cc1 = 0, cc2 = 0; + + if(self.goalentity.islinked || self.goalentity.iscaptured) { cc1 = (self.goalentity.team - 1) * 0x01; } + if(self.enemy.islinked || self.enemy.iscaptured) { cc2 = (self.enemy.team - 1) * 0x10; } + + cc = cc1 + cc2; + + if(cc != self.clientcolors) { - dprint(" and has a team!\n"); - return 1; - } - else - dprint(" but has the wrong team\n"); - } - else - dprint("\n"); - } - e = e.chain; + self.clientcolors = cc; + self.SendFlags |= 4; } + + self.nextthink = time; +} + +void ons_DelayedLinkSetup() +{ + self.goalentity = find(world, targetname, self.target); + self.enemy = find(world, targetname, self.target2); + if(!self.goalentity) { objerror("can not find target\n"); } + if(!self.enemy) { objerror("can not find target2\n"); } + + ons_debug(strcat(etos(self.goalentity), " linked with ", etos(self.enemy), "\n")); + self.SendFlags |= 3; + self.think = ons_Link_CheckUpdate; + self.nextthink = time; +} + + +// ============================= +// Main Control Point Functions +// ============================= + +int ons_ControlPoint_CanBeLinked(entity cp, int teamnumber) +{ + if(cp.isgenneighbor[teamnumber]) { return 2; } + if(cp.iscpneighbor[teamnumber]) { return 1; } + return 0; - */ } -float onslaught_controlpoint_attackable(entity cp, float t) +int ons_ControlPoint_Attackable(entity cp, int teamnumber) // -2: SAME TEAM, attackable by enemy! // -1: SAME TEAM! // 0: off limits @@ -345,7 +315,7 @@ float onslaught_controlpoint_attackable(entity cp, float t) // 3: attack it (HIGH PRIO) // 4: touch it (HIGH PRIO) { - float a; + int a; if(cp.isshielded) { @@ -354,16 +324,16 @@ float onslaught_controlpoint_attackable(entity cp, float t) else if(cp.goalentity) { // if there's already an icon built, nothing happens - if(cp.team == t) + if(cp.team == teamnumber) { - a = onslaught_controlpoint_can_be_linked(cp, NUM_TEAM_1 + NUM_TEAM_2 - t); + a = ons_ControlPoint_CanBeLinked(cp, teamnumber); if(a) // attackable by enemy? return -2; // EMERGENCY! return -1; } // we know it can be linked, so no need to check // but... - a = onslaught_controlpoint_can_be_linked(cp, t); + a = ons_ControlPoint_CanBeLinked(cp, teamnumber); if(a == 2) // near our generator? return 3; // EMERGENCY! return 1; @@ -371,9 +341,9 @@ float onslaught_controlpoint_attackable(entity cp, float t) else { // free point - if(onslaught_controlpoint_can_be_linked(cp, t)) + if(ons_ControlPoint_CanBeLinked(cp, teamnumber)) { - a = onslaught_controlpoint_can_be_linked(cp, NUM_TEAM_1 + NUM_TEAM_2 - t); + a = ons_ControlPoint_CanBeLinked(cp, teamnumber); // why was this here NUM_TEAM_1 + NUM_TEAM_2 - t if(a == 2) return 4; // GET THIS ONE NOW! else @@ -383,428 +353,281 @@ float onslaught_controlpoint_attackable(entity cp, float t) return 0; } -float overtime_msg_time; -void onslaught_generator_think() +void ons_ControlPoint_Icon_Damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force) { - float d; - entity e; - self.nextthink = ceil(time + 1); - if (!gameover) + entity oself; + + if(damage <= 0) { return; } + + if (self.owner.isshielded) { - if (autocvar_timelimit && time > game_starttime + autocvar_timelimit * 60) - { - if (!overtime_msg_time) - { - Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_OVERTIME_CONTROLPOINT); - overtime_msg_time = time; - } - // self.max_health / 300 gives 5 minutes of overtime. - // control points reduce the overtime duration. - sound(self, CH_TRIGGER, "onslaught/generator_decay.wav", VOL_BASE, ATTEN_NORM); - d = 1; - e = findchain(classname, "onslaught_controlpoint"); - while (e) + // this is protected by a shield, so ignore the damage + if (time > self.pain_finished) + if (IS_PLAYER(attacker)) { - if (e.team != self.team) - if (e.islinked) - d = d + 1; - e = e.chain; + play2(attacker, "onslaught/damageblockedbyshield.wav"); + self.pain_finished = time + 1; + attacker.typehitsound += 1; // play both sounds (shield is way too quiet) } - if(autocvar_g_campaign && autocvar__campaign_testrun) - d = d * self.max_health; - else - d = d * self.max_health / max(30, 60 * autocvar_timelimit_suddendeath); - - Damage(self, self, self, d, DEATH_HURTTRIGGER, self.origin, '0 0 0'); - } - else if (overtime_msg_time) - overtime_msg_time = 0; - - if(!self.isshielded && self.wait < time) - { - self.wait = time + 5; - FOR_EACH_REALPLAYER(e) - { - if(SAME_TEAM(e, self)) - { - Send_Notification(NOTIF_ONE, e, MSG_CENTER, CENTER_ONS_NOTSHIELDED); - soundto(MSG_ONE, e, CHAN_AUTO, "kh/alarm.wav", VOL_BASE, ATTEN_NONE); // FIXME: Uniqe sound? - } - } - } + return; } -} - -void onslaught_generator_ring_spawn(vector org) -{ - modeleffect_spawn("models/onslaught/shockwavetransring.md3", 0, 0, org, '0 0 0', '0 0 0', '0 0 0', 0, -16, 0.1, 1.25, 0.25); -} -void onslaught_generator_ray_think() -{ - self.nextthink = time + 0.05; - if(self.count > 10) + if(IS_PLAYER(attacker)) + if(time - ons_notification_time[self.team] > 10) { - self.think = SUB_Remove; - return; + play2team(self.team, "onslaught/controlpoint_underattack.wav"); + ons_notification_time[self.team] = time; } - if(self.count > 5) - self.alpha -= 0.1; + self.health = self.health - damage; + if(self.owner.iscaptured) + WaypointSprite_UpdateHealth(self.owner.sprite, self.health); + else + WaypointSprite_UpdateBuildFinished(self.owner.sprite, time + (self.max_health - self.health) / (self.count / ONS_CP_THINKRATE)); + self.pain_finished = time + 1; + // particles on every hit + pointparticles(particleeffectnum("sparks"), hitloc, force*-1, 1); + //sound on every hit + if (random() < 0.5) + sound(self, CH_TRIGGER, "onslaught/ons_hit1.wav", VOL_BASE+0.3, ATTEN_NORM); else - self.alpha += 0.1; + sound(self, CH_TRIGGER, "onslaught/ons_hit2.wav", VOL_BASE+0.3, ATTEN_NORM); - self.scale += 0.2; - self.count +=1; -} + if (self.health < 0) + { + sound(self, CH_TRIGGER, "weapons/grenade_impact.wav", VOL_BASE, ATTEN_NORM); + pointparticles(particleeffectnum("rocket_explode"), self.origin, '0 0 0', 1); + Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM_4(self.team, INFO_ONSLAUGHT_CPDESTROYED_), self.owner.message, attacker.netname); -void onslaught_generator_ray_spawn(vector org) -{ - entity e; - e = spawn(); - setmodel(e, "models/onslaught/ons_ray.md3"); - setorigin(e, org); - e.angles = randomvec() * 360; - e.alpha = 0; - e.scale = random() * 5 + 8; - e.think = onslaught_generator_ray_think; - e.nextthink = time + 0.05; -} + PlayerScore_Add(attacker, SP_ONS_TAKES, 1); + PlayerScore_Add(attacker, SP_SCORE, 10); -void onslaught_generator_shockwave_spawn(vector org) -{ - shockwave_spawn("models/onslaught/shockwave.md3", org, -64, 0.75, 0.5); -} + self.owner.goalentity = world; + self.owner.islinked = false; + self.owner.iscaptured = false; + self.owner.team = 0; + self.owner.colormap = 1024; -void onslaught_generator_damage_think() -{ - if(self.owner.health < 0) - { - self.think = SUB_Remove; - return; + WaypointSprite_UpdateMaxHealth(self.owner.sprite, 0); + + onslaught_updatelinks(); + + // Use targets now (somebody make sure this is in the right place..) + oself = self; + self = self.owner; + activator = self; + SUB_UseTargets (); + self = oself; + + self.owner.waslinked = self.owner.islinked; + if(self.owner.model != "models/onslaught/controlpoint_pad.md3") + setmodel_fixsize(self.owner, "models/onslaught/controlpoint_pad.md3"); + //setsize(self, '-32 -32 0', '32 32 8'); + + remove(self); } - self.nextthink = time+0.1; - // damaged fx (less probable the more damaged is the generator) - if(random() < 0.9 - self.owner.health / self.owner.max_health) - if(random() < 0.01) - { - Send_Effect("electro_ballexplode", self.origin + randompos('-50 -50 -20', '50 50 50'), '0 0 0', 1); - sound(self, CH_TRIGGER, "onslaught/electricity_explode.wav", VOL_BASE, ATTEN_NORM); - } - else - Send_Effect("torch_small", self.origin + randompos('-60 -60 -20', '60 60 60'), '0 0 0', 1); + self.SendFlags |= CPSF_STATUS; } -void onslaught_generator_damage_spawn(entity gd_owner) +void ons_ControlPoint_Icon_Think() { - entity e; - e = spawn(); - e.owner = gd_owner; - e.health = self.owner.health; - setorigin(e, gd_owner.origin); - e.think = onslaught_generator_damage_think; - e.nextthink = time+1; -} + entity oself; + self.nextthink = time + ONS_CP_THINKRATE; -void onslaught_generator_deaththink() -{ - vector org; - float i; + if(autocvar_g_onslaught_cp_proxydecap) + { + int _enemy_count = 0; + int _friendly_count = 0; + float _dist; + entity _player; + + FOR_EACH_PLAYER(_player) + { + if(!_player.deadflag) + { + _dist = vlen(_player.origin - self.origin); + if(_dist < autocvar_g_onslaught_cp_proxydecap_distance) + { + if(SAME_TEAM(_player, self)) + ++_friendly_count; + else + ++_enemy_count; + } + } + } - if (!self.count) - self.count = 40; + _friendly_count = _friendly_count * (autocvar_g_onslaught_cp_proxydecap_dps * ONS_CP_THINKRATE); + _enemy_count = _enemy_count * (autocvar_g_onslaught_cp_proxydecap_dps * ONS_CP_THINKRATE); - // White shockwave - if(self.count==40||self.count==20) - { - onslaught_generator_ring_spawn(self.origin); - sound(self, CH_TRIGGER, "onslaught/shockwave.wav", VOL_BASE, ATTEN_NORM); - } + self.health = bound(0, self.health + (_friendly_count - _enemy_count), self.max_health); + self.SendFlags |= CPSF_STATUS; + if(self.health <= 0) + { + ons_ControlPoint_Icon_Damage(self, self, 1, 0, self.origin, '0 0 0'); + return; + } + } - // Throw some gibs - if(random() < 0.3) + if (time > self.pain_finished + 5) { - i = random(); - if(i < 0.3) - ons_throwgib(self.origin + '0 0 40', (100 * randomvec() - '1 1 1') * 11 + '0 0 20', "models/onslaught/gen_gib1.md3", 6, true); - else if(i > 0.7) - ons_throwgib(self.origin + '0 0 40', (100 * randomvec() - '1 1 1') * 12 + '0 0 20', "models/onslaught/gen_gib2.md3", 6, true); - else - ons_throwgib(self.origin + '0 0 40', (100 * randomvec() - '1 1 1') * 13 + '0 0 20', "models/onslaught/gen_gib3.md3", 6, true); + if(self.health < self.max_health) + { + self.health = self.health + self.count; + if (self.health >= self.max_health) + self.health = self.max_health; + WaypointSprite_UpdateHealth(self.owner.sprite, self.health); + } } - // Spawn fire balls - for(i=0;i < 10;++i) + if(self.owner.islinked != self.owner.waslinked) { - org = self.origin + randompos('-30 -30 -30' * i + '0 0 -20', '30 30 30' * i + '0 0 20'); - Send_Effect("onslaught_generator_gib_explode", org, '0 0 0', 1); - } + // unteam the spawnpoint if needed + int t = self.owner.team; + if(!self.owner.islinked) + self.owner.team = 0; - // Short explosion sound + small explosion - if(random() < 0.25) - { - te_explosion(self.origin); - sound(self, CH_TRIGGER, "weapons/grenade_impact.wav", VOL_BASE, ATTEN_NORM); - } + oself = self; + self = self.owner; + activator = self; + SUB_UseTargets (); + self = oself; - // Particles - org = self.origin + randompos(self.mins + '8 8 8', self.maxs + '-8 -8 -8'); - Send_Effect("onslaught_generator_smallexplosion", org, '0 0 0', 1); + self.owner.team = t; - // rays - if(random() > 0.25 ) - { - onslaught_generator_ray_spawn(self.origin); + self.owner.waslinked = self.owner.islinked; } - // Final explosion - if(self.count==1) + // damaged fx + if(random() < 0.6 - self.health / self.max_health) { - org = self.origin; - te_explosion(org); - onslaught_generator_shockwave_spawn(org); - Send_Effect("onslaught_generator_finalexplosion", org, '0 0 0', 1); - sound(self, CH_TRIGGER, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM); - } - else - self.nextthink = time + 0.05; + Send_Effect("electricity_sparks", self.origin + randompos('-10 -10 -20', '10 10 20'), '0 0 0', 1); - self.count = self.count - 1; + if(random() > 0.8) + sound(self, CH_PAIN, "onslaught/ons_spark1.wav", VOL_BASE, ATTEN_NORM); + else if (random() > 0.5) + sound(self, CH_PAIN, "onslaught/ons_spark2.wav", VOL_BASE, ATTEN_NORM); + } } -void onslaught_generator_damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force) +void ons_ControlPoint_Icon_BuildThink() { - float i; - if (damage <= 0) - return; - if(warmup_stage) + entity oself; + int a; + + self.nextthink = time + ONS_CP_THINKRATE; + + // only do this if there is power + a = ons_ControlPoint_CanBeLinked(self.owner, self.owner.team); + if(!a) return; - if (attacker != self) + + self.health = self.health + self.count; + + self.SendFlags |= CPSF_STATUS; + + if (self.health >= self.max_health) { - if (self.isshielded) - { - // this is protected by a shield, so ignore the damage - if (time > self.pain_finished) - if (IS_PLAYER(attacker)) - { - play2(attacker, "onslaught/damageblockedbyshield.wav"); - self.pain_finished = time + 1; - } - return; - } - if (time > self.pain_finished) - { - self.pain_finished = time + 10; - bprint(Team_ColoredFullName(self.team), " generator under attack!\n"); - play2team(self.team, "onslaught/generator_underattack.wav"); - } - } - self.health = self.health - damage; - WaypointSprite_UpdateHealth(self.sprite, self.health); - // choose an animation frame based on health - self.frame = 10 * bound(0, (1 - self.health / self.max_health), 1); - // see if the generator is still functional, or dying - if (self.health > 0) - { -#ifdef ONSLAUGHT_SPAM - float h, lh; - lh = ceil(self.lasthealth / 100) * 100; - h = ceil(self.health / 100) * 100; - if(lh != h) - bprint(Team_ColoredFullName(self.team), " generator has less than ", ftos(h), " health remaining\n"); -#endif - self.lasthealth = self.health; - } - else if (!warmup_stage) - { - if (attacker == self) - bprint(Team_ColoredFullName(self.team), " generator spontaneously exploded due to overtime!\n"); - else + self.health = self.max_health; + self.count = autocvar_g_onslaught_cp_regen * ONS_CP_THINKRATE; // slow repair rate from now on + self.think = ons_ControlPoint_Icon_Think; + sound(self, CH_TRIGGER, "onslaught/controlpoint_built.wav", VOL_BASE, ATTEN_NORM); + self.owner.iscaptured = true; + self.solid = SOLID_BBOX; + + Send_Effect(sprintf("%s_cap", Static_Team_ColorName_Lower(self.owner.team)), self.owner.origin, '0 0 0', 1); + + WaypointSprite_UpdateMaxHealth(self.owner.sprite, self.max_health); + WaypointSprite_UpdateHealth(self.owner.sprite, self.health); + + if(IS_PLAYER(self.owner.ons_toucher)) { - string t; - t = Team_ColoredFullName(attacker.team); - bprint(Team_ColoredFullName(self.team), " generator destroyed by ", t, "!\n"); + Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_ONSLAUGHT_CAPTURE, self.owner.ons_toucher.netname, self.owner.message); + Send_Notification(NOTIF_ALL_EXCEPT, self.owner.ons_toucher, MSG_CENTER, APP_TEAM_ENT_4(self.owner.ons_toucher, CENTER_ONS_CAPTURE_), self.owner.message); + Send_Notification(NOTIF_ONE, self.owner.ons_toucher, MSG_CENTER, CENTER_ONS_CAPTURE, self.owner.message); + PlayerScore_Add(self.owner.ons_toucher, SP_ONS_CAPS, 1); + PlayerTeamScore_AddScore(self.owner.ons_toucher, 10); } - 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 - self.think = onslaught_generator_deaththink; // explosion sequence - self.nextthink = time; // start exploding immediately - self.think(); // do the first explosion now - WaypointSprite_UpdateMaxHealth(self.sprite, 0); + self.owner.ons_toucher = world; onslaught_updatelinks(); - } - if(self.health <= 0) - setmodel(self, "models/onslaught/generator_dead.md3"); - else if(self.health < self.max_health * 0.10) - setmodel(self, "models/onslaught/generator_dmg9.md3"); - else if(self.health < self.max_health * 0.20) - setmodel(self, "models/onslaught/generator_dmg8.md3"); - else if(self.health < self.max_health * 0.30) - setmodel(self, "models/onslaught/generator_dmg7.md3"); - else if(self.health < self.max_health * 0.40) - setmodel(self, "models/onslaught/generator_dmg6.md3"); - else if(self.health < self.max_health * 0.50) - setmodel(self, "models/onslaught/generator_dmg5.md3"); - else if(self.health < self.max_health * 0.60) - setmodel(self, "models/onslaught/generator_dmg4.md3"); - else if(self.health < self.max_health * 0.70) - setmodel(self, "models/onslaught/generator_dmg3.md3"); - else if(self.health < self.max_health * 0.80) - setmodel(self, "models/onslaught/generator_dmg2.md3"); - else if(self.health < self.max_health * 0.90) - setmodel(self, "models/onslaught/generator_dmg1.md3"); - setsize(self, '-52 -52 -14', '52 52 75'); - - // Throw some flaming gibs on damage, more damage = more chance for gib - if(random() < damage/220) - { - 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); - else if(i > 0.7) - 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); - } - else - { - // particles on every hit - Send_Effect("sparks", hitloc, force * -1, 1); + // Use targets now (somebody make sure this is in the right place..) + oself = self; + self = self.owner; + activator = self; + SUB_UseTargets (); + self = oself; - //sound on every hit - if (random() < 0.5) - sound(self, CH_TRIGGER, "onslaught/ons_hit1.wav", VOL_BASE, ATTEN_NORM); - else - sound(self, CH_TRIGGER, "onslaught/ons_hit2.wav", VOL_BASE, ATTEN_NORM); + self.SendFlags |= CPSF_SETUP; } + if(self.owner.model != "models/onslaught/controlpoint_pad2.md3") + setmodel_fixsize(self.owner, "models/onslaught/controlpoint_pad2.md3"); - //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); + if(random() < 0.9 - self.health / self.max_health) + Send_Effect("rage", self.origin + 10 * randomvec(), '0 0 -1', 1); } -// update links after a delay -void onslaught_generator_delayed() +void ons_ControlPoint_Icon_Spawn(entity cp, entity player) { - onslaught_updatelinks(); - // now begin normal thinking - self.think = onslaught_generator_think; - self.nextthink = time; -} + entity e = spawn(); -string onslaught_generator_waypointsprite_for_team(entity e, float t) -{ - if(t == e.team) - { - if(e.team == NUM_TEAM_1) - return "ons-gen-red"; - else if(e.team == NUM_TEAM_2) - return "ons-gen-blue"; - } - if(e.isshielded) - return "ons-gen-shielded"; - if(e.team == NUM_TEAM_1) - return "ons-gen-red"; - else if(e.team == NUM_TEAM_2) - return "ons-gen-blue"; - return ""; -} + setsize(e, CPICON_MIN, CPICON_MAX); + setorigin(e, cp.origin + CPICON_OFFSET); -void onslaught_generator_updatesprite(entity e) -{ - string s1, s2, s3; - s1 = onslaught_generator_waypointsprite_for_team(e, NUM_TEAM_1); - s2 = onslaught_generator_waypointsprite_for_team(e, NUM_TEAM_2); - s3 = onslaught_generator_waypointsprite_for_team(e, -1); - WaypointSprite_UpdateSprites(e.sprite, s1, s2, s3); + e.classname = "onslaught_controlpoint_icon"; + e.owner = cp; + e.max_health = autocvar_g_onslaught_cp_health; + e.health = autocvar_g_onslaught_cp_buildhealth; + e.solid = SOLID_NOT; + e.takedamage = DAMAGE_AIM; + e.bot_attack = true; + e.event_damage = ons_ControlPoint_Icon_Damage; + e.team = player.team; + e.colormap = 1024 + (e.team - 1) * 17; + e.count = (e.max_health - e.health) * ONS_CP_THINKRATE / autocvar_g_onslaught_cp_buildtime; // how long it takes to build - if(e.lastteam != e.team + 2 || e.lastshielded != e.isshielded) - { - e.lastteam = e.team + 2; - e.lastshielded = e.isshielded; - 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)); - 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)); - else - WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_GENERATOR, '0.75 0.75 0.75'); - } - WaypointSprite_Ping(e.sprite); - } + sound(e, CH_TRIGGER, "onslaught/controlpoint_build.wav", VOL_BASE, ATTEN_NORM); + + cp.goalentity = e; + cp.team = e.team; + cp.colormap = e.colormap; + + Send_Effect(sprintf("%sflag_touch", Static_Team_ColorName_Lower(player.team)), e.origin, '0 0 0', 1); + + WaypointSprite_UpdateBuildFinished(cp.sprite, time + (e.max_health - e.health) / (e.count / ONS_CP_THINKRATE)); + WaypointSprite_UpdateRule(cp.sprite,cp.team,SPRITERULE_TEAMPLAY); + cp.sprite.SendFlags |= 16; + + onslaught_controlpoint_icon_link(e, ons_ControlPoint_Icon_BuildThink); } -string onslaught_controlpoint_waypointsprite_for_team(entity e, float t) +string ons_ControlPoint_Waypoint(entity e) { - float a; - if(t != -1) + if(e.team) { - a = onslaught_controlpoint_attackable(e, t); - if(a == 3 || a == 4) // ATTACK/TOUCH THIS ONE NOW - { - if(e.team == NUM_TEAM_1) - return "ons-cp-atck-red"; - else if(e.team == NUM_TEAM_2) - return "ons-cp-atck-blue"; - else - return "ons-cp-atck-neut"; - } - else if(a == -2) // DEFEND THIS ONE NOW - { - if(e.team == NUM_TEAM_1) - return "ons-cp-dfnd-red"; - else if(e.team == NUM_TEAM_2) - return "ons-cp-dfnd-blue"; - } - else if(e.team == t || a == -1 || a == 1) // own point, or fire at it - { - if(e.team == NUM_TEAM_1) - return "ons-cp-red"; - else if(e.team == NUM_TEAM_2) - return "ons-cp-blue"; - } - else if(a == 2) // touch it - return "ons-cp-neut"; + int a = ons_ControlPoint_Attackable(e, e.team); + + if(a == -2) { return "ons-cp-dfnd"; } // defend now + if(a == -1 || a == 1 || a == 2) { return "ons-cp"; } // touch + if(a == 3 || a == 4) { return "ons-cp-atck"; } // attack } else - { - if(e.team == NUM_TEAM_1) - return "ons-cp-red"; - else if(e.team == NUM_TEAM_2) - return "ons-cp-blue"; - else - return "ons-cp-neut"; - } + return "ons-cp"; + return ""; } -void onslaught_controlpoint_updatesprite(entity e) +void ons_ControlPoint_UpdateSprite(entity e) { - string s1, s2, s3; - s1 = onslaught_controlpoint_waypointsprite_for_team(e, NUM_TEAM_1); - s2 = onslaught_controlpoint_waypointsprite_for_team(e, NUM_TEAM_2); - s3 = onslaught_controlpoint_waypointsprite_for_team(e, -1); - WaypointSprite_UpdateSprites(e.sprite, s1, s2, s3); + string s1; + s1 = ons_ControlPoint_Waypoint(e); + WaypointSprite_UpdateSprites(e.sprite, s1, s1, s1); - float sh; - sh = !(onslaught_controlpoint_can_be_linked(e, NUM_TEAM_1) || onslaught_controlpoint_can_be_linked(e, NUM_TEAM_2)); + bool sh; + sh = !(ons_ControlPoint_CanBeLinked(e, NUM_TEAM_1) || ons_ControlPoint_CanBeLinked(e, NUM_TEAM_2) || ons_ControlPoint_CanBeLinked(e, NUM_TEAM_3) || ons_ControlPoint_CanBeLinked(e, NUM_TEAM_4)); if(e.lastteam != e.team + 2 || e.lastshielded != sh || e.iscaptured != e.lastcaptured) { @@ -822,14 +645,14 @@ void onslaught_controlpoint_updatesprite(entity e) } if(e.lastshielded) { - if(e.team == NUM_TEAM_1 || e.team == NUM_TEAM_2) + if(e.team) 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) + if(e.team) WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_CONTROLPOINT, colormapPaletteColor(e.team - 1, false)); else WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_CONTROLPOINT, '0.75 0.75 0.75'); @@ -842,666 +665,1407 @@ void onslaught_controlpoint_updatesprite(entity e) } } -void onslaught_generator_reset() +void ons_ControlPoint_Touch() { - 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.enemy.solid = SOLID_NOT; - self.think = onslaught_generator_delayed; - self.nextthink = time + 0.2; - setmodel(self, "models/onslaught/generator.md3"); - setsize(self, '-52 -52 -14', '52 52 75'); + entity toucher = other; + int attackable; + + if(IS_VEHICLE(toucher) && toucher.owner) + if(autocvar_g_onslaught_allow_vehicle_touch) + toucher = toucher.owner; + else + return; + + if(!IS_PLAYER(toucher)) { return; } + if(toucher.frozen) { return; } + if(toucher.deadflag != DEAD_NO) { return; } - if(!self.noalign) + if ( SAME_TEAM(self,toucher) ) + if ( self.iscaptured ) { - setorigin(self, self.origin + '0 0 20'); - droptofloor(); + if(time <= toucher.teleport_antispam) + Send_Notification(NOTIF_ONE, toucher, MSG_CENTER, CENTER_ONS_TELEPORT_ANTISPAM, rint(toucher.teleport_antispam - time)); + else + Send_Notification(NOTIF_ONE, toucher, MSG_CENTER, CENTER_ONS_TELEPORT); } - WaypointSprite_UpdateMaxHealth(self.sprite, self.max_health); - WaypointSprite_UpdateHealth(self.sprite, self.health); -} + attackable = ons_ControlPoint_Attackable(self, toucher.team); + if(attackable != 2 && attackable != 4) + return; + // we've verified that this player has a legitimate claim to this point, + // so start building the captured point icon (which only captures this + // point if it successfully builds without being destroyed first) + ons_ControlPoint_Icon_Spawn(self, toucher); -/*QUAKED spawnfunc_onslaught_generator (0 .5 .8) (-32 -32 -24) (32 32 64) - Base generator. + self.ons_toucher = toucher; - spawnfunc_onslaught_link entities can target this. + onslaught_updatelinks(); +} -keys: -"team" - team that owns this generator (5 = red, 14 = blue, etc), MUST BE SET. -"targetname" - name that spawnfunc_onslaught_link entities will use to target this. - */ -void spawnfunc_onslaught_generator() +void ons_ControlPoint_Think() { - if (!g_onslaught) - { - remove(self); - return; - } - - //entity e; - precache_model("models/onslaught/generator.md3"); - precache_model("models/onslaught/generator_shield.md3"); - precache_model("models/onslaught/generator_dmg1.md3"); - precache_model("models/onslaught/generator_dmg2.md3"); - precache_model("models/onslaught/generator_dmg3.md3"); - precache_model("models/onslaught/generator_dmg4.md3"); - precache_model("models/onslaught/generator_dmg5.md3"); - precache_model("models/onslaught/generator_dmg6.md3"); - precache_model("models/onslaught/generator_dmg7.md3"); - precache_model("models/onslaught/generator_dmg8.md3"); - precache_model("models/onslaught/generator_dmg9.md3"); - precache_model("models/onslaught/generator_dead.md3"); - precache_model("models/onslaught/shockwave.md3"); - precache_model("models/onslaught/shockwavetransring.md3"); - precache_model("models/onslaught/gen_gib1.md3"); - precache_model("models/onslaught/gen_gib2.md3"); - precache_model("models/onslaught/gen_gib3.md3"); - precache_model("models/onslaught/ons_ray.md3"); - precache_sound("onslaught/generator_decay.wav"); - precache_sound("weapons/grenade_impact.wav"); - precache_sound("weapons/rocket_impact.wav"); - precache_sound("onslaught/generator_underattack.wav"); - precache_sound("onslaught/shockwave.wav"); - precache_sound("onslaught/ons_hit1.wav"); - precache_sound("onslaught/ons_hit2.wav"); - precache_sound("onslaught/electricity_explode.wav"); - if (!self.team) - objerror("team must be set"); - - if(self.team == NUM_TEAM_1) - ons_red_generator = self; + self.nextthink = time + ONS_CP_THINKRATE; + CSQCMODEL_AUTOUPDATE(); +} - if(self.team == NUM_TEAM_2) - ons_blue_generator = self; +void ons_ControlPoint_Reset() +{ + if(self.goalentity) + remove(self.goalentity); - self.team_saved = self.team; - self.colormap = 1024 + (self.team - 1) * 17; - self.solid = SOLID_BBOX; - self.movetype = MOVETYPE_NONE; - self.lasthealth = self.max_health = self.health = autocvar_g_onslaught_gen_health; - setmodel(self, "models/onslaught/generator.md3"); - setsize(self, '-52 -52 -14', '52 52 75'); - setorigin(self, self.origin); - self.takedamage = DAMAGE_AIM; - self.bot_attack = true; - self.event_damage = onslaught_generator_damage; - self.iscaptured = true; - self.islinked = true; + self.goalentity = world; + self.team = 0; + self.colormap = 1024; + self.iscaptured = false; + self.islinked = false; 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 - self.enemy = spawn(); - setattachment(self.enemy , self, ""); - self.enemy.classname = "onslaught_generator_shield"; - self.enemy.solid = SOLID_NOT; - self.enemy.movetype = MOVETYPE_NONE; - self.enemy.effects = EF_ADDITIVE; - setmodel(self.enemy, "models/onslaught/generator_shield.md3"); - //setorigin(e, self.origin); - self.enemy.colormap = self.colormap; - self.enemy.team = self.team; - //self.think = onslaught_generator_delayed; - //self.nextthink = time + 0.2; - InitializeEntity(self, onslaught_generator_delayed, INITPRIO_LAST); - - WaypointSprite_SpawnFixed(string_null, self.origin + '0 0 128', self, sprite, RADARICON_NONE, '0 0 0'); - WaypointSprite_UpdateRule(self.sprite, NUM_TEAM_2, SPRITERULE_TEAMPLAY); - WaypointSprite_UpdateMaxHealth(self.sprite, self.max_health); - WaypointSprite_UpdateHealth(self.sprite, self.health); + self.think = ons_ControlPoint_Think; + self.ons_toucher = world; + self.nextthink = time + ONS_CP_THINKRATE; + setmodel_fixsize(self, "models/onslaught/controlpoint_pad.md3"); - waypoint_spawnforitem(self); + WaypointSprite_UpdateMaxHealth(self.sprite, 0); + WaypointSprite_UpdateRule(self.sprite,self.team,SPRITERULE_TEAMPLAY); onslaught_updatelinks(); - self.reset = onslaught_generator_reset; + activator = self; + SUB_UseTargets(); // to reset the structures, playerspawns etc. + + CSQCMODEL_AUTOUPDATE(); } -.float waslinked; -.float cp_bob_spd; -.vector cp_origin, cp_bob_origin, cp_bob_dmg; +void ons_DelayedControlPoint_Setup(void) +{ + onslaught_updatelinks(); + + // captureshield setup + ons_CaptureShield_Spawn(self, false); -float ons_notification_time_team1; -float ons_notification_time_team2; + CSQCMODEL_AUTOINIT(); +} -void onslaught_controlpoint_icon_damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force) +void ons_ControlPoint_Setup(entity cp) { - entity oself; - float nag; + // declarations + self = cp; // for later usage with droptofloor() + + // main setup + cp.ons_worldcpnext = ons_worldcplist; // link control point into ons_worldcplist + ons_worldcplist = cp; + + cp.netname = "Control point"; + cp.team = 0; + cp.solid = SOLID_BBOX; + cp.movetype = MOVETYPE_NONE; + cp.touch = ons_ControlPoint_Touch; + cp.think = ons_ControlPoint_Think; + cp.nextthink = time + ONS_CP_THINKRATE; + cp.reset = ons_ControlPoint_Reset; + cp.colormap = 1024; + cp.iscaptured = false; + cp.islinked = false; + cp.isshielded = true; + + if(cp.message == "") { cp.message = "a"; } + + // precache - TODO: clean up! + precache_model("models/onslaught/controlpoint_pad.md3"); + precache_model("models/onslaught/controlpoint_pad2.md3"); + precache_model("models/onslaught/controlpoint_shield.md3"); + precache_model("models/onslaught/controlpoint_icon.md3"); + precache_model("models/onslaught/controlpoint_icon_dmg1.md3"); + precache_model("models/onslaught/controlpoint_icon_dmg2.md3"); + precache_model("models/onslaught/controlpoint_icon_dmg3.md3"); + precache_model("models/onslaught/controlpoint_icon_gib1.md3"); + precache_model("models/onslaught/controlpoint_icon_gib2.md3"); + precache_model("models/onslaught/controlpoint_icon_gib4.md3"); + precache_sound("onslaught/controlpoint_build.wav"); + precache_sound("onslaught/controlpoint_built.wav"); + precache_sound("weapons/grenade_impact.wav"); + precache_sound("onslaught/damageblockedbyshield.wav"); + precache_sound("onslaught/controlpoint_underattack.wav"); + precache_sound("onslaught/ons_spark1.wav"); + precache_sound("onslaught/ons_spark2.wav"); - if (damage <= 0) - return; - if (self.owner.isshielded) + // appearence + setmodel_fixsize(cp, "models/onslaught/controlpoint_pad.md3"); + + // control point placement + if((cp.spawnflags & 1) || cp.noalign) // don't drop to floor, just stay at fixed location { - // this is protected by a shield, so ignore the damage - if (time > self.pain_finished) - if (IS_PLAYER(attacker)) - { - play2(attacker, "onslaught/damageblockedbyshield.wav"); - self.pain_finished = time + 1; - } - return; + cp.noalign = true; + cp.movetype = MOVETYPE_NONE; + } + else // drop to floor, automatically find a platform and set that as spawn origin + { + setorigin(cp, cp.origin + '0 0 20'); + cp.noalign = false; + self = cp; + droptofloor(); + cp.movetype = MOVETYPE_TOSS; } - if (IS_PLAYER(attacker)) + // waypointsprites + WaypointSprite_SpawnFixed(string_null, self.origin + CPGEN_WAYPOINT_OFFSET, self, sprite, RADARICON_NONE, '0 0 0'); + WaypointSprite_UpdateRule(self.sprite, self.team, SPRITERULE_TEAMPLAY); + + InitializeEntity(cp, ons_DelayedControlPoint_Setup, INITPRIO_SETLOCATION); +} + + +// ========================= +// Main Generator Functions +// ========================= + +string ons_Generator_Waypoint(entity e) +{ + if(e.isshielded) + return "ons-gen-shielded"; + return "ons-gen"; +} + +void ons_Generator_UpdateSprite(entity e) +{ + string s1 = ons_Generator_Waypoint(e); + WaypointSprite_UpdateSprites(e.sprite, s1, s1, s1); + + if(e.lastteam != e.team + 2 || e.lastshielded != e.isshielded) { - nag = false; - if(self.team == NUM_TEAM_1) + e.lastteam = e.team + 2; + e.lastshielded = e.isshielded; + if(e.lastshielded) { - if(time - ons_notification_time_team1 > 10) - { - nag = true; - ons_notification_time_team1 = time; - } + if(e.team) + 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(self.team == NUM_TEAM_2) + else { - if(time - ons_notification_time_team2 > 10) - { - nag = true; - ons_notification_time_team2 = time; - } + if(e.team) + WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_GENERATOR, colormapPaletteColor(e.team - 1, false)); + else + WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_GENERATOR, '0.75 0.75 0.75'); } - else - nag = true; - - if(nag) - play2team(self.team, "onslaught/controlpoint_underattack.wav"); + WaypointSprite_Ping(e.sprite); } +} - self.health = self.health - damage; - if(self.owner.iscaptured) - WaypointSprite_UpdateHealth(self.owner.sprite, self.health); - else - WaypointSprite_UpdateBuildFinished(self.owner.sprite, time + (self.max_health - self.health) / (self.count / sys_frametime)); - self.pain_finished = time + 1; - self.punchangle = (2 * randomvec() - '1 1 1') * 45; - self.cp_bob_dmg_z = (2 * random() - 1) * 15; - // colormod flash when shot - self.colormod = '2 2 2'; - // particles on every hit - Send_Effect("sparks", hitloc, force*-1, 1); - //sound on every hit - if (random() < 0.5) - sound(self, CH_TRIGGER, "onslaught/ons_hit1.wav", VOL_BASE+0.3, ATTEN_NORM); - else - sound(self, CH_TRIGGER, "onslaught/ons_hit2.wav", VOL_BASE+0.3, ATTEN_NORM); +void ons_GeneratorDamage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force) +{ + if(damage <= 0) { return; } + if(warmup_stage || gameover) { return; } + if(!round_handler_IsRoundStarted()) { return; } - if (self.health < 0) + if (attacker != self) { - sound(self, CH_TRIGGER, "weapons/grenade_impact.wav", VOL_BASE, ATTEN_NORM); - Send_Effect("rocket_explode", self.origin, '0 0 0', 1); + if (self.isshielded) + { + // this is protected by a shield, so ignore the damage + if (time > self.pain_finished) + if (IS_PLAYER(attacker)) + { + play2(attacker, "onslaught/damageblockedbyshield.wav"); + attacker.typehitsound += 1; + self.pain_finished = time + 1; + } + return; + } + if (time > self.pain_finished) { - 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); + self.pain_finished = time + 10; + entity head; + FOR_EACH_REALPLAYER(head) if(SAME_TEAM(head, self)) { Send_Notification(NOTIF_ONE, head, MSG_CENTER, CENTER_GENERATOR_UNDERATTACK); } + play2team(self.team, "onslaught/generator_underattack.wav"); } - self.owner.goalentity = world; - self.owner.islinked = false; - self.owner.iscaptured = false; - self.owner.team = 0; - self.owner.colormap = 1024; + } + self.health = self.health - damage; + WaypointSprite_UpdateHealth(self.sprite, self.health); + // choose an animation frame based on health + self.frame = 10 * bound(0, (1 - self.health / self.max_health), 1); + // see if the generator is still functional, or dying + if (self.health > 0) + { + self.lasthealth = self.health; + } + else + { + if (attacker == self) + Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM_4(self.team, INFO_ONSLAUGHT_GENDESTROYED_OVERTIME_)); + else + { + Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM_4(self.team, INFO_ONSLAUGHT_GENDESTROYED_)); + PlayerScore_Add(attacker, SP_SCORE, 100); + } + 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 + self.think = func_null; + self.nextthink = 0; + //self.think(); // do the first explosion now - WaypointSprite_UpdateMaxHealth(self.owner.sprite, 0); + WaypointSprite_UpdateMaxHealth(self.sprite, 0); + WaypointSprite_Ping(self.sprite); + //WaypointSprite_Kill(self.sprite); // can't do this yet, code too poor onslaught_updatelinks(); + } - // Use targets now (somebody make sure this is in the right place..) - oself = self; - self = self.owner; - activator = self; - SUB_UseTargets (); - self = oself; - - - self.owner.waslinked = self.owner.islinked; - if(self.owner.model != "models/onslaught/controlpoint_pad.md3") - setmodel(self.owner, "models/onslaught/controlpoint_pad.md3"); - //setsize(self, '-32 -32 0', '32 32 8'); + // Throw some flaming gibs on damage, more damage = more chance for gib + if(random() < damage/220) + { + sound(self, CH_TRIGGER, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM); + } + else + { + // particles on every hit + Send_Effect("sparks", hitloc, force * -1, 1); - remove(self); + //sound on every hit + if (random() < 0.5) + sound(self, CH_TRIGGER, "onslaught/ons_hit1.wav", VOL_BASE, ATTEN_NORM); + else + sound(self, CH_TRIGGER, "onslaught/ons_hit2.wav", VOL_BASE, ATTEN_NORM); } + + self.SendFlags |= GSF_STATUS; } -void onslaught_controlpoint_icon_think() +void ons_GeneratorThink() { - entity oself; - self.nextthink = time + sys_frametime; - - if(autocvar_g_onslaught_cp_proxydecap) + entity e; + self.nextthink = time + GEN_THINKRATE; + if (!gameover) { - float _enemy_count = 0; - float _friendly_count = 0; - float _dist; - entity _player; - - FOR_EACH_PLAYER(_player) + if(!self.isshielded && self.wait < time) { - if(!_player.deadflag) + self.wait = time + 5; + FOR_EACH_REALPLAYER(e) { - _dist = vlen(_player.origin - self.origin); - if(_dist < autocvar_g_onslaught_cp_proxydecap_distance) - { - if(_player.team == self.team) - ++_friendly_count; - else - ++_enemy_count; + if(SAME_TEAM(e, self)) + { + Send_Notification(NOTIF_ONE, e, MSG_CENTER, CENTER_ONS_NOTSHIELDED_TEAM); + soundto(MSG_ONE, e, CHAN_AUTO, "kh/alarm.wav", VOL_BASE, ATTEN_NONE); // FIXME: unique sound? } + else + Send_Notification(NOTIF_ONE, e, MSG_CENTER, APP_TEAM_NUM_4(self.team, CENTER_ONS_NOTSHIELDED_)); } } + } +} - _friendly_count = _friendly_count * (autocvar_g_onslaught_cp_proxydecap_dps * sys_frametime); - _enemy_count = _enemy_count * (autocvar_g_onslaught_cp_proxydecap_dps * sys_frametime); +void ons_GeneratorReset() +{ + 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.event_damage = ons_GeneratorDamage; + self.think = ons_GeneratorThink; + self.nextthink = time + GEN_THINKRATE; - self.health = bound(0, self.health + (_friendly_count - _enemy_count), self.max_health); - if(self.health <= 0) - { - onslaught_controlpoint_icon_damage(self, self, 1, 0, self.origin, '0 0 0'); - return; - } - } + Net_LinkEntity(self, false, 0, generator_send); - if (time > self.pain_finished + 5) + self.SendFlags = GSF_SETUP; // just incase + self.SendFlags |= GSF_STATUS; + + WaypointSprite_UpdateMaxHealth(self.sprite, self.max_health); + WaypointSprite_UpdateHealth(self.sprite, self.health); + WaypointSprite_UpdateRule(self.sprite,self.team,SPRITERULE_TEAMPLAY); + + onslaught_updatelinks(); +} + +void ons_DelayedGeneratorSetup() +{ + // bot waypoints + waypoint_spawnforitem_force(self, self.origin); + self.nearestwaypointtimeout = 0; // activate waypointing again + self.bot_basewaypoint = self.nearestwaypoint; + + // captureshield setup + ons_CaptureShield_Spawn(self, true); + + onslaught_updatelinks(); + + Net_LinkEntity(self, false, 0, generator_send); +} + + +void onslaught_generator_touch() +{ + if ( IS_PLAYER(other) ) + if ( SAME_TEAM(self,other) ) + if ( self.iscaptured ) { - if(self.health < self.max_health) + Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_ONS_TELEPORT); + } +} + +void ons_GeneratorSetup(entity gen) // called when spawning a generator entity on the map as a spawnfunc +{ + // declarations + int teamnumber = gen.team; + self = gen; // for later usage with droptofloor() + + // main setup + gen.ons_worldgeneratornext = ons_worldgeneratorlist; // link generator into ons_worldgeneratorlist + ons_worldgeneratorlist = gen; + + gen.netname = sprintf("%s generator", Team_ColoredFullName(teamnumber)); + gen.classname = "onslaught_generator"; + gen.solid = SOLID_BBOX; + gen.team_saved = teamnumber; + gen.movetype = MOVETYPE_NONE; + gen.lasthealth = gen.max_health = gen.health = autocvar_g_onslaught_gen_health; + gen.takedamage = DAMAGE_AIM; + gen.bot_attack = true; + gen.event_damage = ons_GeneratorDamage; + gen.reset = ons_GeneratorReset; + gen.think = ons_GeneratorThink; + gen.nextthink = time + GEN_THINKRATE; + gen.iscaptured = true; + gen.islinked = true; + gen.isshielded = true; + gen.touch = onslaught_generator_touch; + + // precache - TODO: clean up! + precache_model("models/onslaught/generator_shield.md3"); + precache_model("models/onslaught/gen_gib1.md3"); + precache_model("models/onslaught/gen_gib2.md3"); + precache_model("models/onslaught/gen_gib3.md3"); + precache_sound("onslaught/generator_decay.wav"); + precache_sound("weapons/grenade_impact.wav"); + precache_sound("weapons/rocket_impact.wav"); + precache_sound("onslaught/generator_underattack.wav"); + precache_sound("onslaught/shockwave.wav"); + precache_sound("onslaught/ons_hit1.wav"); + precache_sound("onslaught/ons_hit2.wav"); + precache_sound("onslaught/generator_underattack.wav"); + + // appearence + // model handled by CSQC + setsize(gen, GENERATOR_MIN, GENERATOR_MAX); + setorigin(gen, (gen.origin + CPGEN_SPAWN_OFFSET)); + gen.colormap = 1024 + (teamnumber - 1) * 17; + + // generator placement + self = gen; + droptofloor(); + + // waypointsprites + WaypointSprite_SpawnFixed(string_null, self.origin + CPGEN_WAYPOINT_OFFSET, self, sprite, RADARICON_NONE, '0 0 0'); + WaypointSprite_UpdateRule(self.sprite, self.team, SPRITERULE_TEAMPLAY); + WaypointSprite_UpdateMaxHealth(self.sprite, self.max_health); + WaypointSprite_UpdateHealth(self.sprite, self.health); + + InitializeEntity(gen, ons_DelayedGeneratorSetup, INITPRIO_SETLOCATION); +} + + +// =============== +// Round Handler +// =============== + +int total_generators; +void Onslaught_count_generators() +{ + entity e; + total_generators = redowned = blueowned = yellowowned = pinkowned = 0; + for(e = ons_worldgeneratorlist; e; e = e.ons_worldgeneratornext) + { + ++total_generators; + redowned += (e.team == NUM_TEAM_1 && e.health > 0); + blueowned += (e.team == NUM_TEAM_2 && e.health > 0); + yellowowned += (e.team == NUM_TEAM_3 && e.health > 0); + pinkowned += (e.team == NUM_TEAM_4 && e.health > 0); + } +} + +int Onslaught_GetWinnerTeam() +{ + int winner_team = 0; + if(redowned > 0) + winner_team = NUM_TEAM_1; + if(blueowned > 0) + { + if(winner_team) return 0; + winner_team = NUM_TEAM_2; + } + if(yellowowned > 0) + { + if(winner_team) return 0; + winner_team = NUM_TEAM_3; + } + if(pinkowned > 0) + { + if(winner_team) return 0; + winner_team = NUM_TEAM_4; + } + if(winner_team) + return winner_team; + return -1; // no generators left? +} + +#define ONS_OWNED_GENERATORS() ((redowned > 0) + (blueowned > 0) + (yellowowned > 0) + (pinkowned > 0)) +#define ONS_OWNED_GENERATORS_OK() (ONS_OWNED_GENERATORS() > 1) +bool Onslaught_CheckWinner() +{ + entity e; + + if ((autocvar_timelimit && time > game_starttime + autocvar_timelimit * 60) || (round_handler_GetEndTime() > 0 && round_handler_GetEndTime() - time <= 0)) + { + ons_stalemate = true; + + if (!wpforenemy_announced) { - self.health = self.health + self.count; - if (self.health >= self.max_health) - self.health = self.max_health; - WaypointSprite_UpdateHealth(self.owner.sprite, self.health); + Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_OVERTIME_CONTROLPOINT); + sound(world, CH_INFO, "onslaught/generator_decay.wav", VOL_BASE, ATTEN_NONE); + + wpforenemy_announced = true; + } + + entity tmp_entity; // temporary entity + float d; + for(tmp_entity = ons_worldgeneratorlist; tmp_entity; tmp_entity = tmp_entity.ons_worldgeneratornext) if(time >= tmp_entity.ons_overtime_damagedelay) + { + // tmp_entity.max_health / 300 gives 5 minutes of overtime. + // control points reduce the overtime duration. + d = 1; + for(e = ons_worldcplist; e; e = e.ons_worldcpnext) + { + if(DIFF_TEAM(e, tmp_entity)) + if(e.islinked) + d = d + 1; + } + + if(autocvar_g_campaign && autocvar__campaign_testrun) + d = d * tmp_entity.max_health; + else + d = d * tmp_entity.max_health / max(30, 60 * autocvar_timelimit_suddendeath); + + Damage(tmp_entity, tmp_entity, tmp_entity, d, DEATH_HURTTRIGGER, tmp_entity.origin, '0 0 0'); + + tmp_entity.sprite.SendFlags |= 16; + + tmp_entity.ons_overtime_damagedelay = time + 1; } } - if (self.health < self.max_health * 0.25) - setmodel(self, "models/onslaught/controlpoint_icon_dmg3.md3"); - else if (self.health < self.max_health * 0.50) - setmodel(self, "models/onslaught/controlpoint_icon_dmg2.md3"); - else if (self.health < self.max_health * 0.75) - setmodel(self, "models/onslaught/controlpoint_icon_dmg1.md3"); - else if (self.health < self.max_health * 0.90) - setmodel(self, "models/onslaught/controlpoint_icon.md3"); - // colormod flash when shot - self.colormod = '1 1 1' * (2 - bound(0, (self.pain_finished - time) / 10, 1)); + else { wpforenemy_announced = false; ons_stalemate = false; } - if(self.owner.islinked != self.owner.waslinked) + Onslaught_count_generators(); + + if(ONS_OWNED_GENERATORS_OK()) + return 0; + + int winner_team = Onslaught_GetWinnerTeam(); + + if(winner_team > 0) { - // unteam the spawnpoint if needed - float t; - t = self.owner.team; - if(!self.owner.islinked) - self.owner.team = 0; + Send_Notification(NOTIF_ALL, world, MSG_CENTER, APP_TEAM_NUM_4(winner_team, CENTER_ROUND_TEAM_WIN_)); + Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM_4(winner_team, INFO_ROUND_TEAM_WIN_)); + TeamScore_AddToTeam(winner_team, ST_ONS_CAPS, +1); + } + else if(winner_team == -1) + { + Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_ROUND_TIED); + Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_ROUND_TIED); + } - oself = self; - self = self.owner; - activator = self; - SUB_UseTargets (); - self = oself; + ons_stalemate = false; - self.owner.team = t; + play2all(sprintf("ctf/%s_capture.wav", Static_Team_ColorName_Lower(winner_team))); - self.owner.waslinked = self.owner.islinked; + round_handler_Init(7, autocvar_g_onslaught_warmup, autocvar_g_onslaught_round_timelimit); + + FOR_EACH_PLAYER(e) + { + e.ons_roundlost = true; + e.player_blocked = true; + + nades_Clear(e); + } + + return 1; +} + +bool Onslaught_CheckPlayers() +{ + return 1; +} + +void Onslaught_RoundStart() +{ + entity tmp_entity; + FOR_EACH_PLAYER(tmp_entity) { tmp_entity.player_blocked = false; } + + for(tmp_entity = ons_worldcplist; tmp_entity; tmp_entity = tmp_entity.ons_worldcpnext) + tmp_entity.sprite.SendFlags |= 16; + + for(tmp_entity = ons_worldgeneratorlist; tmp_entity; tmp_entity = tmp_entity.ons_worldgeneratornext) + tmp_entity.sprite.SendFlags |= 16; +} + + +// ================ +// Bot player logic +// ================ + +// NOTE: LEGACY CODE, needs to be re-written! + +void havocbot_goalrating_ons_offenseitems(float ratingscale, vector org, float sradius) +{ + entity head; + float t, c; + int i; + bool needarmor = false, needweapons = false; + + // Needs armor/health? + if(self.health<100) + needarmor = true; + + // Needs weapons? + c = 0; + for(i = WEP_FIRST; i <= WEP_LAST ; ++i) + { + // Find weapon + if(self.weapons & WepSet_FromWeapon(i)) + if(++c>=4) + break; + } + + if(c<4) + needweapons = true; + + if(!needweapons && !needarmor) + return; + + ons_debug(strcat(self.netname, " needs weapons ", ftos(needweapons) , "\n")); + ons_debug(strcat(self.netname, " needs armor ", ftos(needarmor) , "\n")); + + // See what is around + head = findchainfloat(bot_pickup, true); + while (head) + { + // gather health and armor only + if (head.solid) + if ( ((head.health || head.armorvalue) && needarmor) || (head.weapons && needweapons ) ) + if (vlen(head.origin - org) < sradius) + { + t = head.bot_pickupevalfunc(self, head); + if (t > 0) + navigation_routerating(head, t * ratingscale, 500); + } + head = head.chain; } +} + +void havocbot_role_ons_setrole(entity bot, int role) +{ + ons_debug(strcat(bot.netname," switched to ")); + switch(role) + { + case HAVOCBOT_ONS_ROLE_DEFENSE: + ons_debug("defense"); + bot.havocbot_role = havocbot_role_ons_defense; + bot.havocbot_role_flags = HAVOCBOT_ONS_ROLE_DEFENSE; + bot.havocbot_role_timeout = 0; + break; + case HAVOCBOT_ONS_ROLE_ASSISTANT: + ons_debug("assistant"); + bot.havocbot_role = havocbot_role_ons_assistant; + bot.havocbot_role_flags = HAVOCBOT_ONS_ROLE_ASSISTANT; + bot.havocbot_role_timeout = 0; + break; + case HAVOCBOT_ONS_ROLE_OFFENSE: + ons_debug("offense"); + bot.havocbot_role = havocbot_role_ons_offense; + bot.havocbot_role_flags = HAVOCBOT_ONS_ROLE_OFFENSE; + bot.havocbot_role_timeout = 0; + break; + } + ons_debug("\n"); +} + +int havocbot_ons_teamcount(entity bot, int role) +{ + int c = 0; + entity head; + + FOR_EACH_PLAYER(head) + if(SAME_TEAM(head, self)) + if(head.havocbot_role_flags & role) + ++c; + + return c; +} - if (self.punchangle.x > 0) +void havocbot_goalrating_ons_controlpoints_attack(float ratingscale) +{ + entity cp, cp1, cp2, best, pl, wp; + float radius, bestvalue; + int c; + bool found; + + // Filter control points + for(cp2 = ons_worldcplist; cp2; cp2 = cp2.ons_worldcpnext) { - self.punchangle_x = self.punchangle.x - 60 * sys_frametime; - if (self.punchangle.x < 0) - self.punchangle_x = 0; + cp2.wpcost = c = 0; + cp2.wpconsidered = false; + + if(cp2.isshielded) + continue; + + // Ignore owned controlpoints + if(!(cp2.isgenneighbor[self.team] || cp2.iscpneighbor[self.team])) + continue; + + // Count team mates interested in this control point + // (easier and cleaner than keeping counters per cp and teams) + FOR_EACH_PLAYER(pl) + if(SAME_TEAM(pl, self)) + if(pl.havocbot_role_flags & HAVOCBOT_ONS_ROLE_OFFENSE) + if(pl.havocbot_ons_target==cp2) + ++c; + + // NOTE: probably decrease the cost of attackable control points + cp2.wpcost = c; + cp2.wpconsidered = true; } - else if (self.punchangle.x < 0) + + // We'll consider only the best case + bestvalue = 99999999999; + cp = world; + for(cp1 = ons_worldcplist; cp1; cp1 = cp1.ons_worldcpnext) { - self.punchangle_x = self.punchangle.x + 60 * sys_frametime; - if (self.punchangle.x > 0) - self.punchangle_x = 0; + if (!cp1.wpconsidered) + continue; + + if(cp1.wpcost 0) + if (!cp) + return; + + ons_debug(strcat(self.netname, " chose cp ranked ", ftos(bestvalue), "\n")); + + if(cp.goalentity) { - self.punchangle_y = self.punchangle.y - 60 * sys_frametime; - if (self.punchangle.y < 0) - self.punchangle_y = 0; + // Should be attacked + // Rate waypoints near it + found = false; + best = world; + bestvalue = 99999999999; + for(radius=0; radius<1000 && !found; radius+=500) + { + for(wp=findradius(cp.origin,radius); wp; wp=wp.chain) + { + if(!(wp.wpflags & WAYPOINTFLAG_GENERATED)) + if(wp.classname=="waypoint") + if(checkpvs(wp.origin,cp)) + { + found = true; + if(wp.cnt 0) - self.punchangle_y = 0; + // Should be touched + ons_debug(strcat(self.netname, " found a touchable controlpoint at ", vtos(cp.origin) ,"\n")); + found = false; + + // Look for auto generated waypoint + if (!bot_waypoints_for_items) + for (wp = findradius(cp.origin,100); wp; wp = wp.chain) + { + if(wp.classname=="waypoint") + { + navigation_routerating(wp, ratingscale, 10000); + found = true; + } + } + + // Nothing found, rate the controlpoint itself + if (!found) + navigation_routerating(cp, ratingscale, 10000); } +} - if (self.punchangle.z > 0) +bool havocbot_goalrating_ons_generator_attack(float ratingscale) +{ + entity g, wp, bestwp; + bool found; + int best; + + for(g = ons_worldgeneratorlist; g; g = g.ons_worldgeneratornext) { - self.punchangle_z = self.punchangle.z - 60 * sys_frametime; - if (self.punchangle.z < 0) - self.punchangle_z = 0; + if(SAME_TEAM(g, self) || g.isshielded) + continue; + + // Should be attacked + // Rate waypoints near it + found = false; + bestwp = world; + best = 99999999999; + + for(wp=findradius(g.origin,400); wp; wp=wp.chain) + { + if(wp.classname=="waypoint") + if(checkpvs(wp.origin,g)) + { + found = true; + if(wp.cnt 0) - self.punchangle_z = 0; + self.havocbot_attack_time = 0; + havocbot_ons_reset_role(self); + return; } - 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; + // Set the role timeout if necessary + if (!self.havocbot_role_timeout) + self.havocbot_role_timeout = time + 120; - 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; - else - self.cp_bob_dmg_z = 0; - setorigin(self,self.cp_origin + self.cp_bob_origin + self.cp_bob_dmg); + if (time > self.havocbot_role_timeout) + { + havocbot_ons_reset_role(self); + return; + } - // damaged fx - if(random() < 0.6 - self.health / self.max_health) + if(self.havocbot_attack_time>time) + return; + + if (self.bot_strategytime < time) { - Send_Effect("electricity_sparks", self.origin + randompos('-10 -10 -20', '10 10 20'), '0 0 0', 1); + navigation_goalrating_start(); + havocbot_goalrating_enemyplayers(20000, self.origin, 650); + if(!havocbot_goalrating_ons_generator_attack(20000)) + havocbot_goalrating_ons_controlpoints_attack(20000); + havocbot_goalrating_ons_offenseitems(10000, self.origin, 10000); + navigation_goalrating_end(); - if(random() > 0.8) - sound(self, CH_PAIN, "onslaught/ons_spark1.wav", VOL_BASE, ATTEN_NORM); - else if (random() > 0.5) - sound(self, CH_PAIN, "onslaught/ons_spark2.wav", VOL_BASE, ATTEN_NORM); + self.bot_strategytime = time + autocvar_bot_ai_strategyinterval; + } +} + +void havocbot_role_ons_assistant() +{ + havocbot_ons_reset_role(self); +} + +void havocbot_role_ons_defense() +{ + havocbot_ons_reset_role(self); +} + +void havocbot_ons_reset_role(entity bot) +{ + entity head; + int c = 0; + + if(self.deadflag != DEAD_NO) + return; + + bot.havocbot_ons_target = world; + + // TODO: Defend control points or generator if necessary + + // if there is only me on the team switch to offense + c = 0; + FOR_EACH_PLAYER(head) + if(SAME_TEAM(head, self)) + ++c; + + if(c==1) + { + havocbot_role_ons_setrole(bot, HAVOCBOT_ONS_ROLE_OFFENSE); + return; + } + + havocbot_role_ons_setrole(bot, HAVOCBOT_ONS_ROLE_OFFENSE); +} + + +/* + * Find control point or generator owned by the same team self which is nearest to pos + * if max_dist is positive, only control points within this range will be considered + */ +entity ons_Nearest_ControlPoint(vector pos, float max_dist) +{ + entity tmp_entity, closest_target = world; + tmp_entity = findchain(classname, "onslaught_controlpoint"); + while(tmp_entity) + { + if(SAME_TEAM(tmp_entity, self)) + if(tmp_entity.iscaptured) + if(max_dist <= 0 || vlen(tmp_entity.origin - pos) <= max_dist) + if(vlen(tmp_entity.origin - pos) <= vlen(closest_target.origin - pos) || closest_target == world) + closest_target = tmp_entity; + tmp_entity = tmp_entity.chain; + } + tmp_entity = findchain(classname, "onslaught_generator"); + while(tmp_entity) + { + if(SAME_TEAM(tmp_entity, self)) + if(max_dist <= 0 || vlen(tmp_entity.origin - pos) < max_dist) + if(vlen(tmp_entity.origin - pos) <= vlen(closest_target.origin - pos) || closest_target == world) + closest_target = tmp_entity; + tmp_entity = tmp_entity.chain; + } + + return closest_target; +} + +/* + * Find control point or generator owned by the same team self which is nearest to pos + * if max_dist is positive, only control points within this range will be considered + * This function only check distances on the XY plane, disregarding Z + */ +entity ons_Nearest_ControlPoint_2D(vector pos, float max_dist) +{ + entity tmp_entity, closest_target = world; + vector delta; + float smallest_distance = 0, distance; + + tmp_entity = findchain(classname, "onslaught_controlpoint"); + while(tmp_entity) + { + delta = tmp_entity.origin - pos; + delta_z = 0; + distance = vlen(delta); + + if(SAME_TEAM(tmp_entity, self)) + if(tmp_entity.iscaptured) + if(max_dist <= 0 || distance <= max_dist) + if(closest_target == world || distance <= smallest_distance ) + { + closest_target = tmp_entity; + smallest_distance = distance; + } + + tmp_entity = tmp_entity.chain; + } + tmp_entity = findchain(classname, "onslaught_generator"); + while(tmp_entity) + { + delta = tmp_entity.origin - pos; + delta_z = 0; + distance = vlen(delta); + + if(SAME_TEAM(tmp_entity, self)) + if(max_dist <= 0 || distance <= max_dist) + if(closest_target == world || distance <= smallest_distance ) + { + closest_target = tmp_entity; + smallest_distance = distance; + } + + tmp_entity = tmp_entity.chain; + } + + return closest_target; +} +/** + * find the number of control points and generators in the same team as self + */ +int ons_Count_SelfControlPoints() +{ + entity tmp_entity; + tmp_entity = findchain(classname, "onslaught_controlpoint"); + int n = 0; + while(tmp_entity) + { + if(SAME_TEAM(tmp_entity, self)) + if(tmp_entity.iscaptured) + n++; + tmp_entity = tmp_entity.chain; + } + tmp_entity = findchain(classname, "onslaught_generator"); + while(tmp_entity) + { + if(SAME_TEAM(tmp_entity, self)) + n++; + tmp_entity = tmp_entity.chain; + } + return n; +} + +/** + * Teleport player to a random position near tele_target + * if tele_effects is true, teleport sound+particles are created + * return false on failure + */ +bool ons_Teleport(entity player, entity tele_target, float range, bool tele_effects) +{ + if ( !tele_target ) + return false; + + int i; + vector loc; + float theta; + for(i = 0; i < 16; ++i) + { + theta = random() * 2 * M_PI; + loc_y = sin(theta); + loc_x = cos(theta); + loc_z = 0; + loc *= random() * range; + + loc += tele_target.origin + '0 0 128'; + + tracebox(loc, PL_MIN, PL_MAX, loc, MOVE_NORMAL, player); + if(trace_fraction == 1.0 && !trace_startsolid) + { + traceline(tele_target.origin, loc, MOVE_NOMONSTERS, tele_target); // double check to make sure we're not spawning outside the world + if(trace_fraction == 1.0 && !trace_startsolid) + { + if ( tele_effects ) + { + Send_Effect("teleport", player.origin, '0 0 0', 1); + sound (player, CH_TRIGGER, "misc/teleport.wav", VOL_BASE, ATTEN_NORM); + } + setorigin(player, loc); + player.angles = '0 1 0' * ( theta * RAD2DEG + 180 ); + makevectors(player.angles); + player.fixangle = true; + player.teleport_antispam = time + autocvar_g_onslaught_teleport_wait; + + if ( tele_effects ) + Send_Effect("teleport", player.origin + v_forward * 32, '0 0 0', 1); + return true; + } + } + } + + return false; +} + +// ============== +// Hook Functions +// ============== + +MUTATOR_HOOKFUNCTION(ons_ResetMap) +{ + FOR_EACH_PLAYER(self) + { + self.ons_roundlost = false; + self.ons_deathloc = '0 0 0'; + PutClientInServer(); + } + return false; +} + +MUTATOR_HOOKFUNCTION(ons_RemovePlayer) +{ + self.ons_deathloc = '0 0 0'; + return false; +} + +MUTATOR_HOOKFUNCTION(ons_PlayerSpawn) +{ + if(!round_handler_IsRoundStarted()) + { + self.player_blocked = true; + return false; + } + + entity l; + for(l = ons_worldgeneratorlist; l; l = l.ons_worldgeneratornext) + { + l.sprite.SendFlags |= 16; + } + for(l = ons_worldcplist; l; l = l.ons_worldcpnext) + { + l.sprite.SendFlags |= 16; + } + + if(ons_stalemate) { Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_OVERTIME_CONTROLPOINT); } + + if ( autocvar_g_onslaught_spawn_choose ) + if ( self.ons_spawn_by ) + if ( ons_Teleport(self,self.ons_spawn_by,autocvar_g_onslaught_teleport_radius,false) ) + { + self.ons_spawn_by = world; + return false; + } + + if(autocvar_g_onslaught_spawn_at_controlpoints) + if(random() <= autocvar_g_onslaught_spawn_at_controlpoints_chance) + { + float random_target = autocvar_g_onslaught_spawn_at_controlpoints_random; + entity tmp_entity, closest_target = world; + vector spawn_loc = self.ons_deathloc; + + // new joining player or round reset, don't bother checking + if(spawn_loc == '0 0 0') { return false; } + + if(random_target) { RandomSelection_Init(); } + + for(tmp_entity = ons_worldcplist; tmp_entity; tmp_entity = tmp_entity.ons_worldcpnext) + { + if(SAME_TEAM(tmp_entity, self)) + if(random_target) + RandomSelection_Add(tmp_entity, 0, string_null, 1, 1); + else if(vlen(tmp_entity.origin - spawn_loc) <= vlen(closest_target.origin - spawn_loc) || closest_target == world) + closest_target = tmp_entity; + } + + if(random_target) { closest_target = RandomSelection_chosen_ent; } + + if(closest_target) + { + float i; + vector loc; + for(i = 0; i < 10; ++i) + { + loc = closest_target.origin + '0 0 96'; + loc += ('0 1 0' * random()) * 128; + tracebox(loc, PL_MIN, PL_MAX, loc, MOVE_NORMAL, self); + if(trace_fraction == 1.0 && !trace_startsolid) + { + traceline(closest_target.origin, loc, MOVE_NOMONSTERS, closest_target); // double check to make sure we're not spawning outside the world + if(trace_fraction == 1.0 && !trace_startsolid) + { + setorigin(self, loc); + self.angles = normalize(loc - closest_target.origin) * RAD2DEG; + return false; + } + } + } + } + } + + if(autocvar_g_onslaught_spawn_at_generator) + if(random() <= autocvar_g_onslaught_spawn_at_generator_chance) + { + float random_target = autocvar_g_onslaught_spawn_at_generator_random; + entity tmp_entity, closest_target = world; + vector spawn_loc = self.ons_deathloc; + + // new joining player or round reset, don't bother checking + if(spawn_loc == '0 0 0') { return false; } + + if(random_target) { RandomSelection_Init(); } + + for(tmp_entity = ons_worldgeneratorlist; tmp_entity; tmp_entity = tmp_entity.ons_worldgeneratornext) + { + if(random_target) + RandomSelection_Add(tmp_entity, 0, string_null, 1, 1); + else + { + if(SAME_TEAM(tmp_entity, self)) + if(vlen(tmp_entity.origin - spawn_loc) <= vlen(closest_target.origin - spawn_loc) || closest_target == world) + closest_target = tmp_entity; + } + } + + if(random_target) { closest_target = RandomSelection_chosen_ent; } + + if(closest_target) + { + float i; + vector loc; + for(i = 0; i < 10; ++i) + { + loc = closest_target.origin + '0 0 128'; + loc += ('0 1 0' * random()) * 256; + tracebox(loc, PL_MIN, PL_MAX, loc, MOVE_NORMAL, self); + if(trace_fraction == 1.0 && !trace_startsolid) + { + traceline(closest_target.origin, loc, MOVE_NOMONSTERS, closest_target); // double check to make sure we're not spawning outside the world + if(trace_fraction == 1.0 && !trace_startsolid) + { + setorigin(self, loc); + self.angles = normalize(loc - closest_target.origin) * RAD2DEG; + return false; + } + } + } + } + } + + return false; +} + +MUTATOR_HOOKFUNCTION(ons_PlayerDies) +{ + frag_target.ons_deathloc = frag_target.origin; + entity l; + for(l = ons_worldgeneratorlist; l; l = l.ons_worldgeneratornext) + { + l.sprite.SendFlags |= 16; + } + for(l = ons_worldcplist; l; l = l.ons_worldcpnext) + { + l.sprite.SendFlags |= 16; + } + + if ( autocvar_g_onslaught_spawn_choose ) + if ( ons_Count_SelfControlPoints() > 1 ) + stuffcmd(self, "qc_cmd_cl hud clickradar\n"); + + return false; +} + +MUTATOR_HOOKFUNCTION(ons_MonsterThink) +{ + entity e = find(world, targetname, self.target); + if (e != world) + self.team = e.team; + + return false; +} + +void ons_MonsterSpawn_Delayed() +{ + entity e, own = self.owner; + + if(!own) { remove(self); return; } + + if(own.targetname) + { + e = find(world, target, own.targetname); + if(e != world) + { + own.team = e.team; + + activator = e; + own.use(); + } } + + remove(self); } -void onslaught_controlpoint_icon_buildthink() +MUTATOR_HOOKFUNCTION(ons_MonsterSpawn) { - entity oself; - float a; + entity e = spawn(); + e.owner = self; + InitializeEntity(e, ons_MonsterSpawn_Delayed, INITPRIO_FINDTARGET); - self.nextthink = time + sys_frametime; + return false; +} - // only do this if there is power - a = onslaught_controlpoint_can_be_linked(self.owner, self.owner.team); - if(!a) - return; +void ons_TurretSpawn_Delayed() +{ + entity e, own = self.owner; - self.health = self.health + self.count; + if(!own) { remove(self); return; } - if (self.health >= self.max_health) + if(own.targetname) { - self.health = self.max_health; - self.count = autocvar_g_onslaught_cp_regen * sys_frametime; // slow repair rate from now on - 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; - - WaypointSprite_UpdateMaxHealth(self.owner.sprite, self.max_health); - WaypointSprite_UpdateHealth(self.owner.sprite, self.health); - - onslaught_updatelinks(); + e = find(world, target, own.targetname); + if(e != world) + { + own.team = e.team; + own.active = ACTIVE_NOT; - // Use targets now (somebody make sure this is in the right place..) - oself = self; - self = self.owner; - activator = self; - SUB_UseTargets (); - self = oself; - self.cp_origin = self.origin; - self.cp_bob_origin = '0 0 0.1'; - self.cp_bob_spd = 0; + activator = e; + own.use(); + } } - self.alpha = self.health / self.max_health; - // colormod flash when shot - self.colormod = '1 1 1' * (2 - bound(0, (self.pain_finished - time) / 10, 1)); - if(self.owner.model != "models/onslaught/controlpoint_pad2.md3") - setmodel(self.owner, "models/onslaught/controlpoint_pad2.md3"); - //setsize(self, '-32 -32 0', '32 32 8'); - if(random() < 0.9 - self.health / self.max_health) - Send_Effect("rage", self.origin + 10 * randomvec(), '0 0 -1', 1); + remove(self); } -void onslaught_controlpoint_touch() +MUTATOR_HOOKFUNCTION(ons_TurretSpawn) { - entity e; - float a; - if (!IS_PLAYER(other)) - return; - a = onslaught_controlpoint_attackable(self, other.team); - if(a != 2 && a != 4) - return; - // we've verified that this player has a legitimate claim to this point, - // so start building the captured point icon (which only captures this - // point if it successfully builds without being destroyed first) - self.goalentity = e = spawn(); - e.classname = "onslaught_controlpoint_icon"; + entity e = spawn(); e.owner = self; - e.max_health = autocvar_g_onslaught_cp_health; - e.health = autocvar_g_onslaught_cp_buildhealth; - e.solid = SOLID_BBOX; - e.movetype = MOVETYPE_NONE; - setmodel(e, "models/onslaught/controlpoint_icon.md3"); - setsize(e, '-32 -32 -32', '32 32 32'); - setorigin(e, self.origin + '0 0 96'); - e.takedamage = DAMAGE_AIM; - e.bot_attack = true; - e.event_damage = onslaught_controlpoint_icon_damage; - e.team = other.team; - e.colormap = 1024 + (e.team - 1) * 17; - e.think = onslaught_controlpoint_icon_buildthink; - e.nextthink = time + sys_frametime; - e.count = (e.max_health - e.health) * sys_frametime / autocvar_g_onslaught_cp_buildtime; // how long it takes to build - sound(e, CH_TRIGGER, "onslaught/controlpoint_build.wav", VOL_BASE, ATTEN_NORM); - self.team = e.team; - self.colormap = e.colormap; - WaypointSprite_UpdateBuildFinished(self.sprite, time + (e.max_health - e.health) / (e.count / sys_frametime)); - onslaught_updatelinks(); + InitializeEntity(e, ons_TurretSpawn_Delayed, INITPRIO_FINDTARGET); + + return false; } -void onslaught_controlpoint_think() +MUTATOR_HOOKFUNCTION(ons_BotRoles) { - self.nextthink = time; - CSQCMODEL_AUTOUPDATE(); + havocbot_ons_reset_role(self); + return true; } -void onslaught_controlpoint_reset() +MUTATOR_HOOKFUNCTION(ons_GetTeamCount) { - if(self.goalentity && self.goalentity != world) - remove(self.goalentity); - self.goalentity = world; - self.team = 0; - self.colormap = 1024; - self.iscaptured = false; - self.islinked = false; - self.isshielded = true; - self.enemy.solid = SOLID_NOT; - self.enemy.colormap = self.colormap; - self.think = onslaught_controlpoint_think; - self.enemy.think = func_null; - self.nextthink = time; // don't like func_null :P - setmodel(self, "models/onslaught/controlpoint_pad.md3"); - //setsize(self, '-32 -32 0', '32 32 8'); - - WaypointSprite_UpdateMaxHealth(self.sprite, 0); - - onslaught_updatelinks(); - - activator = self; - SUB_UseTargets(); // to reset the structures, playerspawns etc. + // onslaught is special + entity tmp_entity; + for(tmp_entity = ons_worldgeneratorlist; tmp_entity; tmp_entity = tmp_entity.ons_worldgeneratornext) + { + switch(tmp_entity.team) + { + case NUM_TEAM_1: c1 = 0; break; + case NUM_TEAM_2: c2 = 0; break; + case NUM_TEAM_3: c3 = 0; break; + case NUM_TEAM_4: c4 = 0; break; + } + } - CSQCMODEL_AUTOUPDATE(); + return true; } -/*QUAKED spawnfunc_onslaught_controlpoint (0 .5 .8) (-32 -32 0) (32 32 128) - Control point. Be sure to give this enough clearance so that the shootable part has room to exist - - This should link to an spawnfunc_onslaught_controlpoint entity or spawnfunc_onslaught_generator entity. - -keys: -"targetname" - name that spawnfunc_onslaught_link entities will use to target this. -"target" - target any entities that are tied to this control point, such as vehicles and buildable structure entities. -"message" - name of this control point (should reflect the location in the map, such as "center bridge", "north tower", etc) - */ +MUTATOR_HOOKFUNCTION(ons_SpectateCopy) +{ + self.ons_roundlost = other.ons_roundlost; // make spectators see it too + return false; +} -void spawnfunc_onslaught_controlpoint() +MUTATOR_HOOKFUNCTION(ons_SV_ParseClientCommand) { - //entity e; - if (!g_onslaught) - { - remove(self); - return; - } - precache_model("models/onslaught/controlpoint_pad.md3"); - precache_model("models/onslaught/controlpoint_pad2.md3"); - precache_model("models/onslaught/controlpoint_shield.md3"); - precache_model("models/onslaught/controlpoint_icon.md3"); - precache_model("models/onslaught/controlpoint_icon_dmg1.md3"); - precache_model("models/onslaught/controlpoint_icon_dmg2.md3"); - precache_model("models/onslaught/controlpoint_icon_dmg3.md3"); - precache_model("models/onslaught/controlpoint_icon_gib1.md3"); - precache_model("models/onslaught/controlpoint_icon_gib2.md3"); - precache_model("models/onslaught/controlpoint_icon_gib4.md3"); - precache_sound("onslaught/controlpoint_build.wav"); - precache_sound("onslaught/controlpoint_built.wav"); - precache_sound("weapons/grenade_impact.wav"); - precache_sound("onslaught/damageblockedbyshield.wav"); - precache_sound("onslaught/controlpoint_underattack.wav"); - precache_sound("onslaught/ons_spark1.wav"); - precache_sound("onslaught/ons_spark2.wav"); + if(MUTATOR_RETURNVALUE) // command was already handled? + return false; - self.solid = SOLID_BBOX; - self.movetype = MOVETYPE_NONE; - setmodel(self, "models/onslaught/controlpoint_pad.md3"); - //setsize(self, '-32 -32 0', '32 32 8'); - if(!self.noalign) + if ( cmd_name == "ons_spawn" ) { - setorigin(self, self.origin + '0 0 20'); - droptofloor(); - } - self.touch = onslaught_controlpoint_touch; - self.team = 0; - self.colormap = 1024; - self.iscaptured = false; - self.islinked = false; - self.isshielded = true; + vector pos = self.origin; + if(cmd_argc > 1) + pos_x = stof(argv(1)); + if(cmd_argc > 2) + pos_y = stof(argv(2)); + if(cmd_argc > 3) + pos_z = stof(argv(3)); - // spawn shield model which indicates whether this can be damaged - self.enemy = spawn(); - self.enemy.classname = "onslaught_controlpoint_shield"; - self.enemy.solid = SOLID_NOT; - self.enemy.movetype = MOVETYPE_NONE; - self.enemy.effects = EF_ADDITIVE; - setmodel(self.enemy , "models/onslaught/controlpoint_shield.md3"); + if ( IS_PLAYER(self) ) + { + if ( !self.frozen ) + { + entity source_point = ons_Nearest_ControlPoint(self.origin, autocvar_g_onslaught_teleport_radius); - setattachment(self.enemy , self, ""); - //setsize(e, '-32 -32 0', '32 32 128'); + if ( !source_point && self.health > 0 ) + { + sprint(self, "\nYou need to be next to a control point\n"); + return 1; + } - //setorigin(e, self.origin); - self.enemy.colormap = self.colormap; - waypoint_spawnforitem(self); + entity closest_target = ons_Nearest_ControlPoint_2D(pos, autocvar_g_onslaught_click_radius); - self.think = onslaught_controlpoint_think; - self.nextthink = time; + if ( closest_target == world ) + { + sprint(self, "\nNo control point found\n"); + return 1; + } - WaypointSprite_SpawnFixed(string_null, self.origin + '0 0 128', self, sprite, RADARICON_NONE, '0 0 0'); - WaypointSprite_UpdateRule(self.sprite, NUM_TEAM_2, SPRITERULE_TEAMPLAY); + if ( self.health <= 0 ) + { + self.ons_spawn_by = closest_target; + self.respawn_flags = self.respawn_flags | RESPAWN_FORCE; + } + else + { + if ( source_point == closest_target ) + { + sprint(self, "\nTeleporting to the same point\n"); + return 1; + } - onslaught_updatelinks(); + if ( !ons_Teleport(self,closest_target,autocvar_g_onslaught_teleport_radius,true) ) + sprint(self, "\nUnable to teleport there\n"); + } - self.reset = onslaught_controlpoint_reset; + return 1; + } - CSQCMODEL_AUTOINIT(); -} + sprint(self, "\nNo teleportation for you\n"); + } -float onslaught_link_send(entity to, float sendflags) -{ - WriteByte(MSG_ENTITY, ENT_CLIENT_RADARLINK); - 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); - } - if(sendflags & 2) - { - 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 1; } - return true; + return 0; } -void onslaught_link_checkupdate() +MUTATOR_HOOKFUNCTION(ons_PlayerUseKey) { - // TODO check if the two sides have moved (currently they won't move anyway) - float redpower, bluepower; - - redpower = bluepower = 0; - if(self.goalentity.islinked) - { - if(self.goalentity.team == NUM_TEAM_1) - redpower = 1; - else if(self.goalentity.team == NUM_TEAM_2) - bluepower = 1; - } - if(self.enemy.islinked) - { - if(self.enemy.team == NUM_TEAM_1) - redpower = 2; - else if(self.enemy.team == NUM_TEAM_2) - bluepower = 2; - } - - float cc; - if(redpower == 1 && bluepower == 2) - cc = (NUM_TEAM_1 - 1) * 0x01 + (NUM_TEAM_2 - 1) * 0x10; - else if(redpower == 2 && bluepower == 1) - cc = (NUM_TEAM_1 - 1) * 0x10 + (NUM_TEAM_2 - 1) * 0x01; - else if(redpower) - cc = (NUM_TEAM_1 - 1) * 0x11; - else if(bluepower) - cc = (NUM_TEAM_2 - 1) * 0x11; - else - cc = 0; - - //print(etos(self), " rp=", ftos(redpower), " bp=", ftos(bluepower), " "); - //print("cc=", ftos(cc), "\n"); + if(MUTATOR_RETURNVALUE || gameover) { return false; } - if(cc != self.clientcolors) + if((time > self.teleport_antispam) && (self.deadflag == DEAD_NO) && !self.vehicle) { - self.clientcolors = cc; - self.SendFlags |= 4; + entity source_point = ons_Nearest_ControlPoint(self.origin, autocvar_g_onslaught_teleport_radius); + if ( source_point ) + { + stuffcmd(self, "qc_cmd_cl hud clickradar\n"); + return true; + } } - self.nextthink = time; + return false; } -void onslaught_link_delayed() +MUTATOR_HOOKFUNCTION(ons_PlayHitsound) { - self.goalentity = find(world, targetname, self.target); - self.enemy = find(world, targetname, self.target2); - if (!self.goalentity) - objerror("can not find target\n"); - if (!self.enemy) - objerror("can not find target2\n"); - dprint(etos(self.goalentity), " linked with ", etos(self.enemy), "\n"); - self.SendFlags |= 3; - self.think = onslaught_link_checkupdate; - self.nextthink = time; + return (frag_victim.classname == "onslaught_generator" && !frag_victim.isshielded) + || (frag_victim.classname == "onslaught_controlpoint_icon" && !frag_victim.owner.isshielded); } +// ========== +// Spawnfuncs +// ========== + /*QUAKED spawnfunc_onslaught_link (0 .5 .8) (-16 -16 -16) (16 16 16) Link between control points. @@ -1513,196 +2077,115 @@ keys: */ void spawnfunc_onslaught_link() { - if (!g_onslaught) - { - remove(self); - return; - } + if(!g_onslaught) { remove(self); return; } + 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); -} -MUTATOR_HOOKFUNCTION(ons_BuildMutatorsString) -{ - ret_string = strcat(ret_string, ":ONS"); - return 0; -} + self.ons_worldlinknext = ons_worldlinklist; // link into ons_worldlinklist + ons_worldlinklist = self; -MUTATOR_HOOKFUNCTION(ons_BuildMutatorsPrettyString) -{ - ret_string = strcat(ret_string, ", Onslaught"); - return 0; + InitializeEntity(self, ons_DelayedLinkSetup, INITPRIO_FINDTARGET); + Net_LinkEntity(self, false, 0, ons_Link_Send); } -MUTATOR_HOOKFUNCTION(ons_Spawn_Score) -{ - - /* - float _neer_home = (random() > 0.5 ? true : false); +/*QUAKED spawnfunc_onslaught_controlpoint (0 .5 .8) (-32 -32 0) (32 32 128) + Control point. Be sure to give this enough clearance so that the shootable part has room to exist - RandomSelection_Init(); + This should link to an spawnfunc_onslaught_controlpoint entity or spawnfunc_onslaught_generator entity. - if(self.team == NUM_TEAM_1) - RandomSelection_Add(ons_red_generator, 0, string_null, 1, 1); +keys: +"targetname" - name that spawnfunc_onslaught_link entities will use to target this. +"target" - target any entities that are tied to this control point, such as vehicles and buildable structure entities. +"message" - name of this control point (should reflect the location in the map, such as "center bridge", "north tower", etc) + */ - if(self.team == NUM_TEAM_2) - RandomSelection_Add(ons_blue_generator, 0, string_null, 1, 1); +void spawnfunc_onslaught_controlpoint() +{ + if(!g_onslaught) { remove(self); return; } - entity _cp = findchain(classname, "onslaught_controlpoint"): - while _cp; - { - if(_cp.team == self.team) - RandomSelection_Add(_cp, 0, string_null, 1, 1); + ons_ControlPoint_Setup(self); +} - _cp = _cp.chain; - } +/*QUAKED spawnfunc_onslaught_generator (0 .5 .8) (-32 -32 -24) (32 32 64) + Base generator. - if(RandomSelection_chosen_ent) - { - self.tur_head = RandomSelection_chosen_ent; - spawn_score_x += SPAWN_PRIO_NEAR_TEAMMATE_FOUND; - } - else if(self.team == spawn_spot.team) - spawn_score_x += SPAWN_PRIO_NEAR_TEAMMATE_SAMETEAM; // prefer same team, if we can't find a spawn near teammate + spawnfunc_onslaught_link entities can target this. - */ +keys: +"team" - team that owns this generator (5 = red, 14 = blue, etc), MUST BE SET. +"targetname" - name that spawnfunc_onslaught_link entities will use to target this. + */ +void spawnfunc_onslaught_generator() +{ + if(!g_onslaught) { remove(self); return; } + if(!self.team) { objerror("team must be set"); } - return 0; + ons_GeneratorSetup(self); } -MUTATOR_HOOKFUNCTION(ons_PlayerSpawn) +// scoreboard setup +void ons_ScoreRules() { - if(!autocvar_g_onslaught_spawn_at_controlpoints) - return 0; - - if(random() < 0.5) // 50/50 chane to use default spawnsystem. - return 0; - - float _close_to_home = ((random() > 0.5) ? true : false); - entity _best = world, _trg_gen = world; - float _score, _best_score = MAX_SHOT_DISTANCE; - - RandomSelection_Init(); - - if(self.team == NUM_TEAM_1) - { - if(!_close_to_home) - _trg_gen = ons_blue_generator; - else - _trg_gen = ons_red_generator; - } - - if(self.team == NUM_TEAM_2) - { - if(_close_to_home) - _trg_gen = ons_blue_generator; - else - _trg_gen = ons_red_generator; - } - - entity _cp = findchain(classname, "onslaught_controlpoint"); - while(_cp) - { - if(_cp.team == self.team) - { - _score = vlen(_trg_gen.origin - _cp.origin); - if(_score < _best_score) - { - _best = _cp; - _best_score = _score; - } - } - _cp = _cp.chain; - } - - vector _loc; - float i; - if(_best) - { - for(i = 0; i < 10; ++i) - { - _loc = _best.origin + '0 0 96'; - _loc += ('0 1 0' * random()) * 128; - tracebox(_loc, PL_MIN, PL_MAX, _loc, MOVE_NORMAL, self); - if(trace_fraction == 1.0 && !trace_startsolid) - { - setorigin(self, _loc); - self.angles = normalize(_loc - _best.origin) * RAD2DEG; - return 0; - } - } - } - else - { - if(!autocvar_g_onslaught_spawn_at_generator) - return 0; - - _trg_gen = ((self.team == NUM_TEAM_1) ? ons_red_generator : ons_blue_generator); - - for(i = 0; i < 10; ++i) - { - _loc = _trg_gen.origin + '0 0 96'; - _loc += ('0 1 0' * random()) * 128; - tracebox(_loc, PL_MIN, PL_MAX, _loc, MOVE_NORMAL, self); - if(trace_fraction == 1.0 && !trace_startsolid) - { - setorigin(self, _loc); - self.angles = normalize(_loc - _trg_gen.origin) * RAD2DEG; - return 0; - } - } - } - - return 0; + CheckAllowedTeams(world); + ScoreRules_basics(((c4>=0) ? 4 : (c3>=0) ? 3 : 2), SFL_SORT_PRIO_PRIMARY, 0, true); + ScoreInfo_SetLabel_TeamScore (ST_ONS_CAPS, "destroyed", SFL_SORT_PRIO_PRIMARY); + ScoreInfo_SetLabel_PlayerScore(SP_ONS_CAPS, "caps", SFL_SORT_PRIO_SECONDARY); + ScoreInfo_SetLabel_PlayerScore(SP_ONS_TAKES, "takes", 0); + ScoreRules_basics_end(); } -MUTATOR_HOOKFUNCTION(ons_MonsterThink) +void ons_DelayedInit() // Do this check with a delay so we can wait for teams to be set up { - entity e = find(world, targetname, self.target); - if (e != world) - self.team = e.team; + ons_ScoreRules(); - return false; + round_handler_Spawn(Onslaught_CheckPlayers, Onslaught_CheckWinner, Onslaught_RoundStart); + round_handler_Init(5, autocvar_g_onslaught_warmup, autocvar_g_onslaught_round_timelimit); } -MUTATOR_HOOKFUNCTION(ons_MonsterSpawn) +void ons_Initialize() { - entity e, ee = world; + precache_sound("ctf/red_capture.wav"); + precache_sound("ctf/blue_capture.wav"); + precache_sound("ctf/yellow_capture.wav"); + precache_sound("ctf/pink_capture.wav"); - if(self.targetname) - { - e = find(world,target,self.targetname); - if(e != world) - { - self.team = e.team; - ee = e; - } - } + ons_captureshield_force = autocvar_g_onslaught_shield_force; - if(ee) - { - activator = ee; - self.use(); - } + addstat(STAT_ROUNDLOST, AS_INT, ons_roundlost); - return false; + InitializeEntity(world, ons_DelayedInit, INITPRIO_GAMETYPE); } MUTATOR_DEFINITION(gamemode_onslaught) { - MUTATOR_HOOK(BuildMutatorsPrettyString, ons_BuildMutatorsPrettyString, CBC_ORDER_ANY); - MUTATOR_HOOK(BuildMutatorsString, ons_BuildMutatorsString, CBC_ORDER_ANY); + MUTATOR_HOOK(reset_map_global, ons_ResetMap, CBC_ORDER_ANY); + MUTATOR_HOOK(MakePlayerObserver, ons_RemovePlayer, CBC_ORDER_ANY); + MUTATOR_HOOK(ClientDisconnect, ons_RemovePlayer, CBC_ORDER_ANY); MUTATOR_HOOK(PlayerSpawn, ons_PlayerSpawn, CBC_ORDER_ANY); + MUTATOR_HOOK(PlayerDies, ons_PlayerDies, 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); + MUTATOR_HOOK(TurretSpawn, ons_TurretSpawn, CBC_ORDER_ANY); + MUTATOR_HOOK(HavocBot_ChooseRole, ons_BotRoles, CBC_ORDER_ANY); + MUTATOR_HOOK(GetTeamCount, ons_GetTeamCount, CBC_ORDER_ANY); + MUTATOR_HOOK(SpectateCopy, ons_SpectateCopy, CBC_ORDER_ANY); + MUTATOR_HOOK(SV_ParseClientCommand, ons_SV_ParseClientCommand, CBC_ORDER_ANY); + MUTATOR_HOOK(PlayerUseKey, ons_PlayerUseKey, CBC_ORDER_ANY); + MUTATOR_HOOK(PlayHitsound, ons_PlayHitsound, CBC_ORDER_ANY); MUTATOR_ONADD { if(time > 1) // game loads at time 1 error("This is a game type and it cannot be added at runtime."); + ons_Initialize(); + } + + MUTATOR_ONROLLBACK_OR_REMOVE + { + // we actually cannot roll back ons_Initialize here + // BUT: we don't need to! If this gets called, adding always + // succeeds. } MUTATOR_ONREMOVE @@ -1711,5 +2194,5 @@ MUTATOR_DEFINITION(gamemode_onslaught) return -1; } - return 0; + return false; } diff --git a/qcsrc/server/mutators/gamemode_onslaught.qh b/qcsrc/server/mutators/gamemode_onslaught.qh new file mode 100644 index 0000000000..c6c3d18145 --- /dev/null +++ b/qcsrc/server/mutators/gamemode_onslaught.qh @@ -0,0 +1,93 @@ +// these are needed since mutators are compiled last + +#ifdef SVQC + +.entity ons_toucher; // player who touched the control point + +// control point / generator constants +const float ONS_CP_THINKRATE = 0.2; +const float GEN_THINKRATE = 1; +#define CPGEN_SPAWN_OFFSET ('0 0 1' * (PL_MAX_CONST.z - 13)) +const vector CPGEN_WAYPOINT_OFFSET = ('0 0 128'); +const vector CPICON_OFFSET = ('0 0 96'); + +// list of generators on the map +entity ons_worldgeneratorlist; +.entity ons_worldgeneratornext; +.entity ons_stalegeneratornext; + +// list of control points on the map +entity ons_worldcplist; +.entity ons_worldcpnext; +.entity ons_stalecpnext; + +// list of links on the map +entity ons_worldlinklist; +.entity ons_worldlinknext; +.entity ons_stalelinknext; + +// definitions +.entity sprite; +.string target2; +.int iscaptured; +.int islinked; +.int isshielded; +.float lasthealth; +.int lastteam; +.int lastshielded; +.int lastcaptured; + +.bool waslinked; + +bool ons_stalemate; + +.float teleport_antispam; + +.bool ons_roundlost; + +// waypoint sprites +.entity bot_basewaypoint; // generator waypointsprite + +.bool isgenneighbor[17]; +.bool iscpneighbor[17]; +float ons_notification_time[17]; + +.float ons_overtime_damagedelay; + +.vector ons_deathloc; + +.entity ons_spawn_by; + +// declarations for functions used outside gamemode_onslaught.qc +void ons_Generator_UpdateSprite(entity e); +void ons_ControlPoint_UpdateSprite(entity e); +bool ons_ControlPoint_Attackable(entity cp, int teamnumber); + +// CaptureShield: Prevent capturing or destroying control point/generator if it is not available yet +float ons_captureshield_force; // push force of the shield + +// bot player logic +const int HAVOCBOT_ONS_ROLE_NONE = 0; +const int HAVOCBOT_ONS_ROLE_DEFENSE = 2; +const int HAVOCBOT_ONS_ROLE_ASSISTANT = 4; +const int HAVOCBOT_ONS_ROLE_OFFENSE = 8; + +.entity havocbot_ons_target; + +.int havocbot_role_flags; +.float havocbot_attack_time; + +void havocbot_role_ons_defense(); +void havocbot_role_ons_offense(); +void havocbot_role_ons_assistant(); + +void havocbot_ons_reset_role(entity bot); +void havocbot_goalrating_items(float ratingscale, vector org, float sradius); +void havocbot_goalrating_enemyplayers(float ratingscale, vector org, float sradius); + +// score rule declarations +const int ST_ONS_CAPS = 1; +const int SP_ONS_CAPS = 4; +const int SP_ONS_TAKES = 6; + +#endif diff --git a/qcsrc/server/mutators/mutators_include.qc b/qcsrc/server/mutators/mutators_include.qc index ae13c7d020..3129af92fa 100644 --- a/qcsrc/server/mutators/mutators_include.qc +++ b/qcsrc/server/mutators/mutators_include.qc @@ -45,8 +45,8 @@ #include "../../common/notifications.qh" #include "../../common/deathtypes.qh" #include "mutators_include.qh" - #include "../tturrets/include/turrets_early.qh" - #include "../../common/vehicles/sv_vehicles.qh" + #include "../../common/turrets/sv_turrets.qh" + #include "../../common/vehicles/all.qh" #include "../campaign.qh" #include "../../common/campaign_common.qh" #include "../../common/mapinfo.qh" @@ -75,7 +75,7 @@ #include "../round_handler.qh" #include "../item_key.qh" #include "../pathlib/pathlib.qh" - #include "../tturrets/include/turrets.qh" + #include "../../common/vehicles/all.qh" #endif #include "../../common/mutators/base.qh" diff --git a/qcsrc/server/mutators/mutators_include.qh b/qcsrc/server/mutators/mutators_include.qh index 44e51828b1..2d1c3b4502 100644 --- a/qcsrc/server/mutators/mutators_include.qh +++ b/qcsrc/server/mutators/mutators_include.qh @@ -14,6 +14,7 @@ #include "gamemode_invasion.qh" #include "gamemode_race.qh" #include "gamemode_cts.qh" +#include "gamemode_onslaught.qh" #include "mutator_dodging.qh" #include "mutator_overkill.qh" diff --git a/qcsrc/server/progs.src b/qcsrc/server/progs.src index 2ed1e03d60..3d39893d06 100644 --- a/qcsrc/server/progs.src +++ b/qcsrc/server/progs.src @@ -14,6 +14,7 @@ cheats.qc cl_client.qc cl_impulse.qc cl_player.qc +controlpoint.qc csqceffects.qc ent_cs.qc g_casings.qc @@ -25,6 +26,7 @@ g_subs.qc g_tetris.qc g_violence.qc g_world.qc +generator.qc ipban.qc item_key.qc mapvoting.qc @@ -55,7 +57,6 @@ bot/waypoints.qc bot/havocbot/havocbot.qc bot/havocbot/role_keyhunt.qc -bot/havocbot/role_onslaught.qc bot/havocbot/roles.qc command/all.qc @@ -87,7 +88,6 @@ weapons/weaponsystem.qc ../common/campaign_setup.qc ../common/effects.qc ../common/mapinfo.qc -../common/monsters/all.qc ../common/monsters/spawn.qc ../common/monsters/sv_monsters.qc ../common/movetypes/include.qc @@ -102,12 +102,20 @@ weapons/weaponsystem.qc ../common/triggers/include.qc ../common/urllib.qc ../common/util.qc -../common/vehicles/vehicles_include.qc ../common/items/all.qc +../common/monsters/all.qc +../common/mutators/all.qc +../common/vehicles/all.qc +../common/weapons/all.qc // TODO +../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/all.qc // TODO ../csqcmodellib/sv_model.qc diff --git a/qcsrc/server/sv_main.qc b/qcsrc/server/sv_main.qc index 9e4296539e..18ea24d949 100644 --- a/qcsrc/server/sv_main.qc +++ b/qcsrc/server/sv_main.qc @@ -17,7 +17,7 @@ #include "../common/mapinfo.qh" #include "../common/util.qh" -#include "../common/vehicles/sv_vehicles.qh" +#include "../common/vehicles/all.qh" #include "../common/weapons/all.qh" #include "../csqcmodellib/sv_model.qh" diff --git a/qcsrc/server/teamplay.qc b/qcsrc/server/teamplay.qc index b19597cdeb..b50c49eb5a 100644 --- a/qcsrc/server/teamplay.qc +++ b/qcsrc/server/teamplay.qc @@ -163,6 +163,7 @@ void InitGameplayMode() if(g_onslaught) { ActivateTeamplay(); + fraglimit_override = autocvar_g_onslaught_point_limit; have_team_spawns = -1; // request team spawns MUTATOR_ADD(gamemode_onslaught); } diff --git a/qcsrc/server/tturrets/include/turrets.qh b/qcsrc/server/tturrets/include/turrets.qh deleted file mode 100644 index 50bfa326c6..0000000000 --- a/qcsrc/server/tturrets/include/turrets.qh +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef TURRETS_H -#define TURRETS_H - -#ifdef TTURRETS_ENABLED - -// Include section. -#include "../system/system_misc.qc" /// Assorted junk & jewls -#include "../system/system_main.qc" /// And routines -#include "../system/system_aimprocs.qc" /// Aiming realted stuff -#include "../system/system_scoreprocs.qc" /// Target calssification -#include "../system/system_damage.qc" /// Outch, they are hurting me! what should i do? - -// Non combat units -#include "../units/unit_fusionreactor.qc" /// Supply unites that need it with power -#include "../units/unit_targettrigger.qc" /// Hit me! -#include "../units/unit_checkpoint.qc" /// Halfsmart pathing. - -// Combat units -#include "../units/unit_plasma.qc" /// Basic energy cannon -#include "../units/unit_mlrs.qc" /// Basic multibay RL -#include "../units/unit_hellion.qc" /// Seeking missiles MLRS -#include "../units/unit_flac.qc" /// anti missile turret -#include "../units/unit_phaser.qc" /// ZzzapT -#include "../units/unit_hk.qc" /// Hunter killers -#include "../units/unit_machinegun.qc" /// whacka -#include "../units/unit_tessla.qc" /// Chain lightning capabale turret -#include "../units/unit_walker.qc" /// Moving minigun-rocket-meele err thing -#include "../units/unit_ewheel.qc" /// A evil wheel. with guns on. -//#include "../units/unit_repulsor.qc" /// Fires a wave that knocks foes back -//#include "../units/unit_hive.qc" /// Swarm AI - -#endif // TTURRETS_ENABLED -#endif diff --git a/qcsrc/server/tturrets/include/turrets_early.qh b/qcsrc/server/tturrets/include/turrets_early.qh deleted file mode 100644 index 1cb23e67be..0000000000 --- a/qcsrc/server/tturrets/include/turrets_early.qh +++ /dev/null @@ -1,475 +0,0 @@ -#ifndef TURRETS_EARLY_H -#define TURRETS_EARLY_H - -// Comment out below to skip turrets -#define TTURRETS_ENABLED - -#ifdef TTURRETS_ENABLED -#ifdef SVQC -//#message "with tZork turrets" - -float turret_count; - -vector real_origin(entity ent); - -/// 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; - -/// Used for cvar reloading -.string cvar_basename; - -//.float spawnflags -const float TSF_SUSPENDED = 1; -/// Spawn a pillar model under the turret to make it look ok on uneven ground surfaces -const float TSF_TERRAINBASE = 2; -/// Disable builtin ammo regeneration -const float TSF_NO_AMMO_REGEN = 4; -/// Dont break path to chase enemys. will still fire at them if possible. -const float TSF_NO_PATHBREAK = 8; -/// Dont respawn -const float TSL_NO_RESPAWN = 16; -/// Let this turret roam when idle. -const float TSL_ROAM = 32; - -/// target selection flags -.float target_select_flags; -/// target validatoin flags -.float target_validate_flags; -/// Dont select a target on its own. -const float TFL_TARGETSELECT_NO = 2; -/// Need line of sight -const float TFL_TARGETSELECT_LOS = 4; -/// Players are valid targets -const float TFL_TARGETSELECT_PLAYERS = 8; -/// Missiles are valid targets -const float TFL_TARGETSELECT_MISSILES = 16; -/// Responds to turret_trigger_target events -const float TFL_TARGETSELECT_TRIGGERTARGET = 32; -/// Angular limitations of turret head limits target selection -const float TFL_TARGETSELECT_ANGLELIMITS = 64; -/// Range limits apply in targetselection -const float TFL_TARGETSELECT_RANGELIMTS = 128; -/// DOnt select targets with a .team matching its own -const float TFL_TARGETSELECT_TEAMCHECK = 256; -/// Cant select targets on its own. needs to be triggerd or slaved. -const float TFL_TARGETSELECT_NOBUILTIN = 512; -/// TFL_TARGETSELECT_TEAMCHECK is inverted (selects only mebers of own .team) -const float TFL_TARGETSELECT_OWNTEAM = 1024; -/// Turrets aren't valid targets -const float TFL_TARGETSELECT_NOTURRETS = 2048; -/// Use feild of view -const float TFL_TARGETSELECT_FOV = 4096; - -const float TFL_TARGETSELECT_MISSILESONLY = 8192; - -/// aim flags -.float aim_flags; -/// Dont aim. -const float TFL_AIM_NO = 1; -/// Go for ground, not direct hit, but only if target is on ground. -const float TFL_AIM_GROUNDGROUND = 2; -/// Try to predict target movement (does not account for gravity) -const float TFL_AIM_LEAD = 4; -/// Compensate for shot traveltime when lead -const float TFL_AIM_SHOTTIMECOMPENSATE = 8; -/// Try to do real prediction of targets z pos at impact. -const float TFL_AIM_ZPREDICT = 16; -/// Simply aim at target's current location -const float TFL_AIM_SIMPLE = 32; - -/// track (turn and pitch head) flags -.float track_flags; -/// Dont move head -const float TFL_TRACK_NO = 2; -/// Pitch the head -const float TFL_TRACK_PITCH = 4; -/// Rotate the head -const float TFL_TRACK_ROT = 8; - -/// How tracking is preformed -.float track_type; -/// Hard angle increments. Ugly for fast turning, best accuracy. -const float TFL_TRACKTYPE_STEPMOTOR = 1; -/// Smoth absolute movement. Looks ok, fair accuracy. -const float TFL_TRACKTYPE_FLUIDPRECISE = 2; -/// Simulated inertia. "Wobbly mode" Looks kool, can mean really bad accuracy depending on how the fields below are set -const float TFL_TRACKTYPE_FLUIDINERTIA = 3; -/// TFL_TRACKTYPE_FLUIDINERTIA: pitch multiplier -.float track_accel_pitch; -/// TFL_TRACKTYPE_FLUIDINERTIA: rotation multiplier -.float track_accel_rot; -/// TFL_TRACKTYPE_FLUIDINERTIA: Blendrate with old rotation (inertia simulation) 1 = only old, 0 = only new -.float track_blendrate; - -/// How prefire check is preformed -.float firecheck_flags; -/// Dont kill the dead -const float TFL_FIRECHECK_DEAD = 4; -/// Range limits apply -const float TFL_FIRECHECK_DISTANCES = 8; -/// Line Of Sight needs to be clear -const float TFL_FIRECHECK_LOS = 16; -/// Consider distance inpactpoint<->aimspot -const float TFL_FIRECHECK_AIMDIST = 32; -/// Consider enemy origin<->impactpoint -const float TFL_FIRECHECK_REALDIST = 64; -/// Consider angular diff head<->aimspot -const float TFL_FIRECHECK_ANGLEDIST = 128; -/// (re)consider target.team<->self.team -const float TFL_FIRECHECK_TEAMCECK = 256; -/// Try to avoid friendly fire -const float TFL_FIRECHECK_AFF = 512; -/// Own .ammo needs to be >= then own .shot_dmg -const float TFL_FIRECHECK_OWM_AMMO = 1024; -/// Others ammo need to be < others .ammo_max -const float TFL_FIRECHECK_OTHER_AMMO = 2048; -/// Check own .attack_finished_single vs time -const float TFL_FIRECHECK_REFIRE = 4096; -/// Move the acctual target to aimspot before tracing impact (and back after) -//#define TFL_FIRECHECK_VERIFIED 8192 -/// Dont do any chekcs -const float TFL_FIRECHECK_NO = 16384; - -/// How shooting is done -.float shoot_flags; -/// Dont shoot -const float TFL_SHOOT_NO = 64; -/// Fire in vollys (partial implementation through .shot_volly) -const float TFL_SHOOT_VOLLY = 2; -/// Always do a full volly, even if target is lost or dead. (not implemented) -const float TFL_SHOOT_VOLLYALWAYS = 4; -/// Loop though all valid tarters, and hit them. -const float TFL_SHOOT_HITALLVALID = 8; -/// Fiering makes unit loose target (after volly is done, if in volly mode) -const float TFL_SHOOT_CLEARTARGET = 16; -///Custom shooting; -const float TFL_SHOOT_CUSTOM = 32; - -/// Information aboute the units capabilities -.float turrcaps_flags; -/// No kown capabilities -const float TFL_TURRCAPS_NONE = 0; -/// Capable of sniping -const float TFL_TURRCAPS_SNIPER = 2; -/// Capable of splasdamage -const float TFL_TURRCAPS_RADIUSDMG = 4; -/// Has one or more cannons with zero shot traveltime -const float TFL_TURRCAPS_HITSCAN = 8; -/// More then one (type of) gun -const float TFL_TURRCAPS_MULTIGUN = 16; -/// Carries at least one guided weapon -const float TFL_TURRCAPS_GUIDED = 32; -/// At least one gun fiers slow projectiles -const float TFL_TURRCAPS_SLOWPROJ = 64; -/// At least one gun fiers medium speed projectiles -const float TFL_TURRCAPS_MEDPROJ = 128; -/// At least one gun fiers fast projectiles -const float TFL_TURRCAPS_FASTPROJ = 256; -/// At least one gun capable of damaging players -const float TFL_TURRCAPS_PLAYERKILL = 512; -/// At least one gun that can shoot town missiles -const float TFL_TURRCAPS_MISSILEKILL = 1024; -/// Has support capabilities. powerplants and sutch. -const float TFL_TURRCAPS_SUPPORT = 2048; -/// Proveides at least one type of ammmo -const float TFL_TURRCAPS_AMMOSOURCE = 4096; -/// Can recive targets from external sources -const float TFL_TURRCAPS_RECIVETARGETS = 8192; -/// Capable of self-transport -const float TFL_TURRCAPS_MOVE = 16384; -/// Will roam arround even if not chasing anyting -const float TFL_TURRCAPS_ROAM = 32768; -const float TFL_TURRCAPS_ISTURRET = 65536; - -/// Ammo types needed and/or provided -//.float ammo_flags; -#define ammo_flags currentammo -/// Has and needs no ammo -const float TFL_AMMO_NONE = 64; -/// Uses power -const float TFL_AMMO_ENERGY = 2; -/// Uses bullets -const float TFL_AMMO_BULLETS = 4; -/// Uses explosives -const float TFL_AMMO_ROCKETS = 8; -/// Regenerates ammo on its own -const float TFL_AMMO_RECHARGE = 16; -/// Can recive ammo from others -const float TFL_AMMO_RECIVE = 32; - -/// How incomming damage is handeld -.float damage_flags; -/// Cant be hurt -const float TFL_DMG_NO = 256; -/// Can be damaged -const float TFL_DMG_YES = 2; -/// Can be damaged by teammates -const float TFL_DMG_TAKEFROMTEAM = 4; -/// Traget attackers -const float TFL_DMG_RETALIATE = 8; -/// Target attackers, even is on own team -const float TFL_DMG_RETALIATEONTEAM = 16; -/// Loses target when damaged -const float TFL_DMG_TARGETLOSS = 32; -/// Reciving damage trows off aim (pointless atm, aim gets recalculated to fast). not implemented. -const float TFL_DMG_AIMSHAKE = 64; -/// Reciving damage slaps the head arround -const float TFL_DMG_HEADSHAKE = 128; -/// Die and stay dead. -const float TFL_DMG_DEATH_NORESPAWN = 256; - -// Spawnflags -/// Spawn in teambased modes -const float TFL_SPAWN_TEAM = 2; -/// Spawn in FFA modes -const float TFL_SPAWN_FFA = 4; - - -/* -* Fields used by turrets -*/ -/// Turrets internal ai speed -.float ticrate; - -/// Where to point the when no target -.vector idle_aim; - -/// Top part of turret -.entity tur_head; - -/// Start/respawn health -.float tur_health; - -/// Defend this entity (or ratehr this entitys position) -.entity tur_defend; - -/// and shoot from here. (can be non constant, think MLRS) -.vector tur_shotorg; - -/// Aim at this spot -.vector tur_aimpos; - -/// Predicted time the round will impact -.float tur_impacttime; - -// Predicted place the round will impact -//.vector tur_impactpoint; // unused - -/// What entity the aimtrace hit, if any. -.entity tur_impactent; - -/// Distance to enemy -.float tur_dist_enemy; - -/// Distance to aimspot -.float tur_dist_aimpos; - -/// Distance impact<->aim -.float tur_dist_impact_to_aimpos; - -/// Decresment counter form .shot_volly to 0. -.float volly_counter; - -/* -* Projectile/missile. its up to the individual turret implementation to -** deal the damage, blow upp the missile or whatever. -*/ -/// Track then refireing is possible -//.float attack_finished; = attack_finished_single -/// Shoot this often -.float shot_refire; -/// Shots travel this fast, when appliable -.float shot_speed; -/// Inaccuracy -.float shot_spread; -/// Estimated (core) damage of projectiles. also reduce on ammo with this amount when fiering -.float shot_dmg; -/// If radius dmg, this is how big that radius is. -.float shot_radius; -/// Max force exserted by round impact -.float shot_force; -/// < 1 = shoot # times at target (if possible) -.float shot_volly; -/// Refire after a compleated volly. -.float shot_volly_refire; - -/// Consider targets within this range -.float target_range; -/// Dont consider targets closer then -.float target_range_min; -/// Targets closer to this are prefered -.float target_range_optimal; - -/* -* The standard targetselection tries to select a target based on -* range, angle offset, target type, "is old target" -* Thise biases will allow score scaling to (dis)favor diffrent targets -*/ -/// (dis)Favor best range this mutch -.float target_select_rangebias; -/// (dis)Favor targeting my old enemy this mutch -.float target_select_samebias; -/// (dis)Favor targeting the enemy closest to my guns current angle this mutch -.float target_select_anglebias; -/// (dis)Favor Missiles? (-1 to diable targeting compleatly) -.float target_select_missilebias; -/// (dis)Favot living players (-1 to diable targeting compleatly) -.float target_select_playerbias; -/// Field of view -//.float target_select_fov; -/// Last timestamp this turret aquierd a valid target -.float target_select_time; -/// Throttle re-validation of current target -.float target_validate_time; -/* -* Aim refers to real aiming, not gun pos (thats done by track) -*/ -/// Maximum offset between impact and aim spot to fire -.float aim_firetolerance_dist; -/// How fast can i rotate/pitch (per second in stepmotor mode, base force in smooth modes) -.float aim_speed; -/// cant aim higher/lower then this -.float aim_maxpitch; -/// I cant rotate more then this -.float aim_maxrot; - -// Ammo/power. keeping dmg and ammo on a one to one ratio is preferable (for rating) -/// Staring & current ammo -.float ammo; -/// Regenerate this mutch ammo (per second) -.float ammo_recharge; -/// Max amount of ammo i can hold -.float ammo_max; - - -// Uncomment below to enable various debug output. -//#define TURRET_DEBUG -//#define TURRET_DEBUG_TARGETVALIDATE -//#define TURRET_DEBUG_TARGETSELECT - -#ifdef TURRET_DEBUG -.float tur_dbg_dmg_t_h; // Total dmg that hit something (can be more then tur_dbg_dmg_t_f since it should count radius dmg. -.float tur_dbg_dmg_t_f; // Total damage spent -.float tur_dbg_start; // When did i go online? -.float tur_dbg_tmr1; // timer for random use -.float tur_dbg_tmr2; // timer for random use -.float tur_dbg_tmr3; // timer for random use -.vector tur_dbg_rvec; // Random vector, mainly for coloruing stuff' -#endif - -// System main's -/// Main AI loop -void turret_think(); -/// Prefire checks and sutch -void turret_fire(); - -// Callbacks -/// implements the actual fiering -.void() turret_firefunc; -/// prefire checks go here. return 1 to go bang, 0 not to. -.float() turret_firecheckfunc; -/// Execure AFTER main AI loop -.void() turret_postthink; - -/// Add a target -.float(entity e_target,entity e_sender) turret_addtarget; - -.void() turret_diehook; -.void() turret_respawnhook; - -/* -* Target selection, preferably but not nessesarely -* return a normalized result. -*/ -/// Function to use for target evaluation. usualy turret_stdproc_targetscore_generic -.float(entity _turret, entity _target) turret_score_target; - -/* -* Target selection -*/ -/// Generic, fairly smart, bias-aware target selection. -float turret_stdproc_targetscore_generic(entity _turret, entity _target); -/// Experimental supportunits targetselector -float turret_stdproc_targetscore_support(entity _turret,entity _target); - -/* -* Aim functions -*/ -/// Generic aimer guided by self.aim_flags -vector turret_stdproc_aim_generic(); - -/* -* Turret turning & pitch -*/ -/// Tries to line up the turret head with the aimpos -void turret_stdproc_track(); - -/// Generic damage handeling. blows up the turret when health <= 0 -void turret_stdproc_damage (entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector vforce); -/// Spawns a explotion, does some damage & trows bits arround. -void turret_stdproc_die(); -/// reassembles the turret. -void turret_stdproc_respawn(); - -/// Evaluate target validity -float turret_validate_target(entity e_turret,entity e_target,float validate_flags); -/// Turret Head Angle Diff Vector. updated by a sucsessfull call to turret_validate_target -vector tvt_thadv; -/// Turret Angle Diff Vector. updated by a sucsessfull call to turret_validate_target -vector tvt_tadv; -/// Turret Head Angle Diff Float. updated by a sucsessfull call to turret_validate_target -float tvt_thadf; -/// Turret Angle Diff Float. updated by a sucsessfull call to turret_validate_target -float tvt_tadf; -/// Distance. updated by a sucsessfull call to turret_validate_target -float tvt_dist; - -/// updates aim org, shot org, shot dir and enemy org for selected turret -void turret_do_updates(entity e_turret); -.vector tur_shotdir_updated; - -void turrets_precash(); -#endif // SVQC - -// common -.int turret_type; -const int TID_COMMON = 1; -const int TID_EWHEEL = 2; -const int TID_FLAC = 3; -const int TID_FUSION = 4; -const int TID_HELLION = 5; -const int TID_HK = 6; -const int TID_MACHINEGUN = 7; -const int TID_MLRS = 8; -const int TID_PHASER = 9; -const int TID_PLASMA = 10; -const int TID_PLASMA_DUAL = 11; -const int TID_TESLA = 12; -const int TID_WALKER = 13; -const int TID_LAST = 13; - -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 int TNSF_ANIM = 128; - -const int TNSF_FULL_UPDATE = 16777215; - -#endif // TTURRETS_ENABLED -#endif diff --git a/qcsrc/server/tturrets/system/system_aimprocs.qc b/qcsrc/server/tturrets/system/system_aimprocs.qc deleted file mode 100644 index fa21f1ac66..0000000000 --- a/qcsrc/server/tturrets/system/system_aimprocs.qc +++ /dev/null @@ -1,71 +0,0 @@ -/* -* Generic aim - -supports: -TFL_AIM_NO -TFL_AIM_GROUNDGROUND -TFL_AIM_LEAD -TFL_AIM_SHOTTIMECOMPENSATE -*/ -vector turret_stdproc_aim_generic() -{ - - vector pre_pos, prep; - float distance, 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 - { - // FIXME: this cant be the best way to do this.. - prep = pre_pos; - float impact_time = 0; - for(i = 0; i < 4; ++i) - { - distance = vlen(prep - self.tur_shotorg); - impact_time = distance / self.shot_speed; - prep = pre_pos + self.enemy.velocity * impact_time; - } - - 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_GROUNDGROUND) - { - //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; -} diff --git a/qcsrc/server/tturrets/system/system_damage.qc b/qcsrc/server/tturrets/system/system_damage.qc deleted file mode 100644 index 43567fcbfc..0000000000 --- a/qcsrc/server/tturrets/system/system_damage.qc +++ /dev/null @@ -1,131 +0,0 @@ -/* -* Spawn a boom, trow fake bits arround -* and hide the real ones. -*/ -void turret_hide() -{ - self.effects |= EF_NODRAW; - self.nextthink = time + self.respawntime - 0.2; - self.think = turret_stdproc_respawn; -} - -void turret_stdproc_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) - { - if (self.turret_diehook) - self.turret_diehook(); - - remove(self.tur_head); - remove(self); - } - else - { - // Setup respawn - self.SendFlags |= TNSF_STATUS; - self.nextthink = time + 0.2; - self.think = turret_hide; - - if (self.turret_diehook) - self.turret_diehook(); - } -} - -void turret_stdproc_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_stdproc_damage; - - self.avelocity = '0 0 0'; - self.tur_head.avelocity = self.avelocity; - self.tur_head.angles = self.idle_aim; - self.health = self.tur_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; - - if (self.turret_respawnhook) - self.turret_respawnhook(); -} - -/* -* Standard damage proc. -*/ -void turret_stdproc_damage (entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector vforce) -{ - // Enougth allready! - if(self.deadflag == DEAD_DEAD) - return; - - // Inactive turrets take no damage. (hm..) - if (!self.active) - return; - - if (teamplay) - if (self.team == attacker.team) - { - // This does not happen anymore. Re-enable if you fix that. - if(IS_REAL_CLIENT(attacker)) - sprint(attacker, "\{1}Turret tells you: I'm on your team!\n"); - - if(autocvar_g_friendlyfire) - damage = damage * autocvar_g_friendlyfire; - else - return; - } - - self.health = 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.turrcaps_flags & TFL_TURRCAPS_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_stdproc_die; - } - - self.SendFlags |= TNSF_STATUS; -} diff --git a/qcsrc/server/tturrets/system/system_main.qc b/qcsrc/server/tturrets/system/system_main.qc deleted file mode 100644 index deee89542b..0000000000 --- a/qcsrc/server/tturrets/system/system_main.qc +++ /dev/null @@ -1,1370 +0,0 @@ -#include "../../_all.qh" - -#include "../../g_damage.qh" -#include "../../bot/bot.qh" - -#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, int 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); - - 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.tur_health) * 255)); - } - - return true; -} - -void load_unit_settings(entity ent, string unitname, float is_reload) -{ - string sbase; - - if (ent == world) - return; - - if (!ent.turret_scale_damage) ent.turret_scale_damage = 1; - if (!ent.turret_scale_range) ent.turret_scale_range = 1; - if (!ent.turret_scale_refire) ent.turret_scale_refire = 1; - if (!ent.turret_scale_ammo) ent.turret_scale_ammo = 1; - if (!ent.turret_scale_aim) ent.turret_scale_aim = 1; - if (!ent.turret_scale_health) ent.turret_scale_health = 1; - if (!ent.turret_scale_respawn) ent.turret_scale_respawn = 1; - - sbase = strcat(cvar_base,unitname); - if (is_reload) - { - ent.enemy = world; - ent.tur_head.avelocity = '0 0 0'; - - ent.tur_head.angles = '0 0 0'; - } - - ent.health = cvar(strcat(sbase,"_health")) * ent.turret_scale_health; - ent.respawntime = cvar(strcat(sbase,"_respawntime")) * ent.turret_scale_respawn; - - ent.shot_dmg = cvar(strcat(sbase,"_shot_dmg")) * ent.turret_scale_damage; - ent.shot_refire = cvar(strcat(sbase,"_shot_refire")) * ent.turret_scale_refire; - ent.shot_radius = cvar(strcat(sbase,"_shot_radius")) * ent.turret_scale_damage; - ent.shot_speed = cvar(strcat(sbase,"_shot_speed")); - ent.shot_spread = cvar(strcat(sbase,"_shot_spread")); - ent.shot_force = cvar(strcat(sbase,"_shot_force")) * ent.turret_scale_damage; - ent.shot_volly = cvar(strcat(sbase,"_shot_volly")); - ent.shot_volly_refire = cvar(strcat(sbase,"_shot_volly_refire")) * ent.turret_scale_refire; - - ent.target_range = cvar(strcat(sbase,"_target_range")) * ent.turret_scale_range; - ent.target_range_min = cvar(strcat(sbase,"_target_range_min")) * ent.turret_scale_range; - ent.target_range_optimal = cvar(strcat(sbase,"_target_range_optimal")) * ent.turret_scale_range; - //ent.target_range_fire = cvar(strcat(sbase,"_target_range_fire")) * ent.turret_scale_range; - - ent.target_select_rangebias = cvar(strcat(sbase,"_target_select_rangebias")); - ent.target_select_samebias = cvar(strcat(sbase,"_target_select_samebias")); - ent.target_select_anglebias = cvar(strcat(sbase,"_target_select_anglebias")); - ent.target_select_playerbias = cvar(strcat(sbase,"_target_select_playerbias")); - //ent.target_select_fov = cvar(cvar_gets(sbase,"_target_select_fov")); - - ent.ammo_max = cvar(strcat(sbase,"_ammo_max")) * ent.turret_scale_ammo; - ent.ammo_recharge = cvar(strcat(sbase,"_ammo_recharge")) * ent.turret_scale_ammo; - - ent.aim_firetolerance_dist = cvar(strcat(sbase,"_aim_firetolerance_dist")); - ent.aim_speed = cvar(strcat(sbase,"_aim_speed")) * ent.turret_scale_aim; - ent.aim_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, int deathtype, vector hitloc, vector vforce) -{ - self.velocity += vforce; - self.health -= damage; - //self.realowner = attacker; // Dont change realowner, it does not make much sense for turrets - if(self.health <= 0) - W_PrepareExplosionByDamage(self.owner, turret_projectile_explode); -} - -entity turret_projectile(string _snd, float _size, float _health, float _death, float _proj_type, float _cull, float _cli_anim) -{ - entity proj; - - sound (self, CH_WEAPON_A, _snd, VOL_BASE, ATTEN_NORM); - proj = spawn (); - setorigin(proj, self.tur_shotorg); - setsize(proj, '-0.5 -0.5 -0.5' * _size, '0.5 0.5 0.5' * _size); - proj.owner = self; - proj.realowner = self; - proj.bot_dodge = true; - proj.bot_dodgerating = self.shot_dmg; - proj.think = turret_projectile_explode; - proj.touch = turret_projectile_touch; - proj.nextthink = time + 9; - proj.movetype = MOVETYPE_FLYMISSILE; - proj.velocity = normalize(self.tur_shotdir_updated + randomvec() * self.shot_spread) * self.shot_speed; - proj.flags = FL_PROJECTILE; - proj.enemy = self.enemy; - proj.totalfrags = _death; - PROJECTILE_MAKETRIGGER(proj); - if(_health) - { - proj.health = _health; - proj.takedamage = DAMAGE_YES; - proj.event_damage = turret_projectile_damage; - } - else - proj.flags |= FL_NOTARGET; - - CSQCProjectile(proj, _cli_anim, _proj_type, _cull); - - return proj; -} - -/** -** updates enemy distances, predicted impact point/time -** and updated aim<->predict impact distance. -**/ -void turret_do_updates(entity t_turret) -{ - vector enemy_pos; - entity oldself; - - oldself = self; - self = t_turret; - - enemy_pos = real_origin(self.enemy); - - turret_tag_fire_update(); - - self.tur_shotdir_updated = v_forward; - self.tur_dist_enemy = vlen(self.tur_shotorg - enemy_pos); - self.tur_dist_aimpos = vlen(self.tur_shotorg - self.tur_aimpos); - - /*if((self.firecheck_flags & TFL_FIRECHECK_VERIFIED) && (self.enemy)) - { - oldpos = self.enemy.origin; - setorigin(self.enemy, self.tur_aimpos); - tracebox(self.tur_shotorg, '-1 -1 -1', '1 1 1', self.tur_shotorg + (self.tur_shotdir_updated * self.tur_dist_aimpos), MOVE_NORMAL,self); - setorigin(self.enemy, oldpos); - - if(trace_ent == self.enemy) - self.tur_dist_impact_to_aimpos = 0; - else - self.tur_dist_impact_to_aimpos = vlen(trace_endpos - self.tur_aimpos); - } - else*/ - tracebox(self.tur_shotorg, '-1 -1 -1','1 1 1', self.tur_shotorg + (self.tur_shotdir_updated * self.tur_dist_aimpos), MOVE_NORMAL,self); - - self.tur_dist_impact_to_aimpos = vlen(trace_endpos - self.tur_aimpos) - (vlen(self.enemy.maxs - self.enemy.mins) * 0.5); - self.tur_impactent = trace_ent; - self.tur_impacttime = vlen(self.tur_shotorg - trace_endpos) / self.shot_speed; - - self = oldself; -} - -/* -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); - - // 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_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 = 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 = (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_ROT) - { - self.tur_head.avelocity_y = move_angle.y; - - 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) - { - 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(IS_VEHICLE(e_target)) - { - 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) - return -17; - - 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) - 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); - 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) - { - e = nextent(world); - while (e) - { - if(IS_TURRET(e)) - { - 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? - - 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; - - 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, self)) - 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); -#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 --git a/qcsrc/server/tturrets/system/system_misc.qc b/qcsrc/server/tturrets/system/system_misc.qc deleted file mode 100644 index 1885f67c17..0000000000 --- a/qcsrc/server/tturrets/system/system_misc.qc +++ /dev/null @@ -1,354 +0,0 @@ -/* -* 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() -{ - if(!self.tur_head) - { - error("Call to turret_tag_fire_update with self.tur_head missing!\n"); - self.tur_shotorg = '0 0 0'; - return false; - } - - self.tur_shotorg = gettaginfo(self.tur_head, gettagindex(self.tur_head, "tag_fire")); - v_forward = normalize(v_forward); - - return true; -} - -/* -* Railgun-like beam, but has thickness and suppots slowing of target -*/ -void FireImoBeam (vector start, vector end, vector smin, vector smax, - float bforce, float f_dmg, float f_velfactor, int deathtype) - -{ - vector hitloc, force, endpoint, dir; - entity ent; - - dir = normalize(end - start); - force = dir * bforce; - - // go a little bit into the wall because we need to hit this wall later - end = end + dir; - - // trace multiple times until we hit a wall, each obstacle will be made unsolid. - // note down which entities were hit so we can damage them later - while (1) - { - tracebox(start, smin, smax, end, false, self); - - // if it is world we can't hurt it so stop now - if (trace_ent == world || trace_fraction == 1) - break; - - if (trace_ent.solid == SOLID_BSP) - break; - - // make the entity non-solid so we can hit the next one - trace_ent.railgunhit = true; - trace_ent.railgunhitloc = end; - trace_ent.railgunhitsolidbackup = trace_ent.solid; - - // stop if this is a wall - - // make the entity non-solid - trace_ent.solid = SOLID_NOT; - } - - endpoint = trace_endpos; - - // find all the entities the railgun hit and restore their solid state - ent = findfloat(world, railgunhit, true); - while (ent) - { - // restore their solid type - ent.solid = ent.railgunhitsolidbackup; - ent = findfloat(ent, railgunhit, true); - } - - // find all the entities the railgun hit and hurt them - ent = findfloat(world, railgunhit, true); - while (ent) - { - // get the details we need to call the damage function - hitloc = ent.railgunhitloc; - ent.railgunhitloc = '0 0 0'; - ent.railgunhitsolidbackup = SOLID_NOT; - ent.railgunhit = false; - - // apply the damage - if (ent.takedamage) - { - Damage (ent, self, self, f_dmg, deathtype, hitloc, force); - ent.velocity = ent.velocity * f_velfactor; - //ent.alpha = 0.25 + random() * 0.75; - } - - // advance to the next entity - ent = findfloat(ent, railgunhit, true); - } - trace_endpos = endpoint; -} - -// Plug this into wherever precache is done. -void g_turrets_common_precash() -{ - precache_model ("models/turrets/c512.md3"); - precache_model ("models/marker.md3"); -} - -void turrets_precache_debug_models() -{ - precache_model ("models/turrets/c512.md3"); - precache_model ("models/pathlib/goodsquare.md3"); - precache_model ("models/pathlib/badsquare.md3"); - precache_model ("models/pathlib/square.md3"); - precache_model ("models/pathlib/edge.md3"); -} - -void turrets_precash() -{ - #ifdef TURRET_DEBUG - turrets_precache_debug_models(); - #endif -} - - -#ifdef TURRET_DEBUG -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 --git a/qcsrc/server/tturrets/system/system_scoreprocs.qc b/qcsrc/server/tturrets/system/system_scoreprocs.qc deleted file mode 100644 index 539be2ad9e..0000000000 --- a/qcsrc/server/tturrets/system/system_scoreprocs.qc +++ /dev/null @@ -1,130 +0,0 @@ -float turret_stdproc_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_stdproc_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_maxrot; - - 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; -} - -/* -float turret_stdproc_targetscore_close(entity _turret,entity _target) -{ - return 1 - (tvt_dist / _turret.target_range); -} - -float turret_stdproc_targetscore_far (entity _turret,entity _target) -{ - return tvt_dist / _turret.target_range; -} - -float turret_stdproc_targetscore_optimal(entity _turret,entity _target) -{ - return min(_turret.target_range_optimal,tvt_dist) / max(_turret.target_range_optimal,tvt_dist); -} - -float turret_stdproc_score_angular(entity _turret,entity _target) -{ - return 1 - (tvt_thadf / _turret.aim_maxrot); -} - -float turret_stdproc_targetscore_defend(entity _turret,entity _target) -{ - return 0; - //min(_target.origin,_turret.tur_defend.origin) / max(_target.origin,_turret.tur_defend.origin); -} -*/ diff --git a/qcsrc/server/tturrets/units/unit_checkpoint.qc b/qcsrc/server/tturrets/units/unit_checkpoint.qc deleted file mode 100644 index c919601a33..0000000000 --- a/qcsrc/server/tturrets/units/unit_checkpoint.qc +++ /dev/null @@ -1,83 +0,0 @@ -/** - turret_checkpoint -**/ - - -//.entity checkpoint_target; - -/* -#define checkpoint_cache_who flagcarried -#define checkpoint_cache_from lastrocket -#define checkpoint_cache_to selected_player -*/ - -.entity pathgoal; -.entity pathcurrent; - -/* -entity path_makeorcache(entity forwho,entity start, entity end) -{ - entity oldself; - entity pth; - oldself = self; - self = forwho; - - //pth = pathlib_makepath(start.origin,end.origin,PFL_GROUNDSNAP,500,1.5,PT_QUICKSTAR); - - self = oldself; - return pth; -} -*/ - -void turret_checkpoint_use() -{ -} - -#if 0 -void turret_checkpoint_think() -{ - if(self.enemy) - te_lightning1(self,self.origin, self.enemy.origin); - - self.nextthink = time + 0.25; -} -#endif -/*QUAKED turret_checkpoint (1 0 1) (-32 -32 -32) (32 32 32) ------------KEYS------------ -target: .targetname of next waypoint in chain. -wait: Pause at this point # seconds. ------------SPAWNFLAGS----------- ----------NOTES---------- -If a loop is of targets are formed, any unit entering this loop will patrol it indefinitly. -If the checkpoint chain in not looped, the unit will go "Roaming" when the last point is reached. -*/ -//float tc_acum; -void turret_checkpoint_init() -{ - traceline(self.origin + '0 0 16', self.origin - '0 0 1024', MOVE_WORLDONLY, self); - setorigin(self, trace_endpos + '0 0 32'); - - if(self.target != "") - { - self.enemy = find(world, targetname, self.target); - if(self.enemy == world) - dprint("A turret_checkpoint faild to find its target!\n"); - } - //self.think = turret_checkpoint_think; - //self.nextthink = time + tc_acum + 0.25; - //tc_acum += 0.25; -} - -void spawnfunc_turret_checkpoint() -{ - setorigin(self,self.origin); - self.think = turret_checkpoint_init; - self.nextthink = time + 0.2; -} - -// Compat. -void spawnfunc_walker_checkpoint() -{ - self.classname = "turret_checkpoint"; - spawnfunc_turret_checkpoint(); -} diff --git a/qcsrc/server/tturrets/units/unit_ewheel.qc b/qcsrc/server/tturrets/units/unit_ewheel.qc deleted file mode 100644 index 4efdf6716b..0000000000 --- a/qcsrc/server/tturrets/units/unit_ewheel.qc +++ /dev/null @@ -1,312 +0,0 @@ -#include "../../bot/navigation.qh" - -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.missile_flags = MIF_SPLASH; - - Send_Effect("laser_muzzleflash", self.tur_shotorg, self.tur_shotdir_updated * 1000, 1); - - self.tur_head.frame += 2; - - if (self.tur_head.frame > 3) - self.tur_head.frame = 0; - } - -} -//#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); - - /*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; - - 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; -} - -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.teleportable = TELEPORT_NORMAL; - self.damagedbycontents = true; - self.movetype = MOVETYPE_WALK; - self.solid = SOLID_SLIDEBOX; - self.takedamage = DAMAGE_AIM; - self.idle_aim = '0 0 0'; - self.pos1 = self.origin; - - 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 --git a/qcsrc/server/tturrets/units/unit_flac.qc b/qcsrc/server/tturrets/units/unit_flac.qc deleted file mode 100644 index be277c5551..0000000000 --- a/qcsrc/server/tturrets/units/unit_flac.qc +++ /dev/null @@ -1,74 +0,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); - Send_Effect("laser_muzzleflash", self.tur_shotorg, self.tur_shotdir_updated * 1000, 1); - proj.think = turret_flac_projectile_think_explode; - proj.nextthink = time + self.tur_impacttime + (random() * 0.01 - random() * 0.01); - proj.missile_flags = MIF_SPLASH | MIF_PROXY; - - 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 --git a/qcsrc/server/tturrets/units/unit_fusionreactor.qc b/qcsrc/server/tturrets/units/unit_fusionreactor.qc deleted file mode 100644 index 014fa25f69..0000000000 --- a/qcsrc/server/tturrets/units/unit_fusionreactor.qc +++ /dev/null @@ -1,94 +0,0 @@ -void spawnfunc_turret_fusionreactor(); -void turret_fusionreactor_dinit(); -void turret_fusionreactor_fire(); - -void turret_fusionreactor_fire() -{ - 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); -} - -void turret_fusionreactor_postthink() -{ - self.tur_head.avelocity = '0 250 0' * (self.ammo / self.ammo_max); -} - -/* -void turret_fusionreactor_respawnhook() -{ - self.tur_head.avelocity = '0 50 0'; -} -*/ - -/** -** Preforms pre-fire checks for fusionreactor -**/ -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 turret_fusionreactor_dinit() -{ - if (self.netname == "") self.netname = "Fusionreactor"; - - self.turrcaps_flags = TFL_TURRCAPS_SUPPORT | TFL_TURRCAPS_AMMOSOURCE; - self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE; - self.target_select_flags = TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_OWNTEAM | TFL_TARGETSELECT_RANGELIMTS; - self.firecheck_flags = TFL_FIRECHECK_OWM_AMMO | TFL_FIRECHECK_OTHER_AMMO | 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.turret_respawnhook = turret_fusionreactor_respawnhook; - - if (turret_stdproc_init("fusreac_std", "models/turrets/base.md3", "models/turrets/reactor.md3", TID_FUSION) == 0) - { - remove(self); - return; - } - self.tur_head.scale = 0.75; - self.tur_head.avelocity = '0 50 0'; - setsize(self,'-34 -34 0','34 34 90'); - - self.turret_firecheckfunc = turret_fusionreactor_firecheck; - self.turret_firefunc = turret_fusionreactor_fire; - self.turret_postthink = turret_fusionreactor_postthink; -} - -/*QUAKED turret_fusionreactor (0 .5 .8) ? -*/ -void spawnfunc_turret_fusionreactor() -{ - precache_model ("models/turrets/reactor.md3"); - precache_model ("models/turrets/base.md3"); - - self.think = turret_fusionreactor_dinit; - self.nextthink = time + 0.5; -} diff --git a/qcsrc/server/tturrets/units/unit_hellion.qc b/qcsrc/server/tturrets/units/unit_hellion.qc deleted file mode 100644 index 5a3e80f69c..0000000000 --- a/qcsrc/server/tturrets/units/unit_hellion.qc +++ /dev/null @@ -1,126 +0,0 @@ -void spawnfunc_turret_hellion(); -void turret_hellion_dinit(); -void turret_hellion_attack(); - -void turret_hellion_missile_think() -{ - vector olddir,newdir; - vector pre_pos; - float itime; - - self.nextthink = time + 0.05; - - olddir = normalize(self.velocity); - - if(self.tur_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_std_shot_speed_gain, autocvar_g_turrets_unit_hellion_std_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_std_shot_speed_gain, autocvar_g_turrets_unit_hellion_std_shot_speed_max); - - if (itime < 0.05) - self.think = turret_projectile_explode; - - UpdateCSQCProjectile(self); -} -void turret_hellion_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.tur_health = time + 9; - missile.tur_aimpos = randomvec() * 128; - missile.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_GUIDED_HEAT; - self.tur_head.frame += 1; -} - -void turret_hellion_postthink() -{ - if (self.tur_head.frame != 0) - self.tur_head.frame += 1; - - if (self.tur_head.frame >= 7) - self.tur_head.frame = 0; -} - -void turret_hellion_dinit() -{ - if (self.netname == "") self.netname = "Hellion Missile Turret"; - - self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_FASTPROJ | TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_MISSILEKILL; - self.aim_flags = TFL_AIM_SIMPLE; - self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK ; - self.firecheck_flags = TFL_FIRECHECK_DEAD | TFL_FIRECHECK_DISTANCES | TFL_FIRECHECK_TEAMCECK | TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AFF | TFL_FIRECHECK_OWM_AMMO; - self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE; - - if (turret_stdproc_init("hellion_std", "models/turrets/base.md3", "models/turrets/hellion.md3", TID_HELLION) == 0) - { - remove(self); - return; - } - - self.turret_firefunc = turret_hellion_attack; - self.turret_postthink = turret_hellion_postthink; -} - -/*QUAKED turret_hellion (0 .5 .8) ? -*/ -void spawnfunc_turret_hellion() -{ - precache_model ("models/turrets/hellion.md3"); - precache_model ("models/turrets/base.md3"); - - self.think = turret_hellion_dinit; - self.nextthink = time + 0.5; -} - - diff --git a/qcsrc/server/tturrets/units/unit_hk.qc b/qcsrc/server/tturrets/units/unit_hk.qc deleted file mode 100644 index cb8c743fb4..0000000000 --- a/qcsrc/server/tturrets/units/unit_hk.qc +++ /dev/null @@ -1,336 +0,0 @@ -//#define TURRET_DEBUG_HK - -#ifdef TURRET_DEBUG_HK -.float atime; -#endif - -void spawnfunc_turret_hk(); -void turret_hk_dinit(); -void turret_hk_attack(); - - -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); - ve = normalize(pre_pos - self.origin); - fe = trace_fraction; - - } - else - { - edist = 0; - ve = '0 0 0'; - fe = 0; - } - - if ((fe != 1) || (self.enemy == world) || (edist > 1000)) - { - myspeed = vlen(self.velocity); - - lt_for = myspeed * 3; - lt_seek = myspeed * 2.95; - - // Trace forward - traceline(self.origin, self.origin + v_forward * lt_for,false,self); - vf = trace_endpos; - ff = trace_fraction; - - // Find angular offset - ad = vlen(vectoangles(normalize(self.enemy.origin - self.origin)) - self.angles); - - // To close to something, Slow down! - if ( ((ff < 0.7) || (ad > 4)) && (myspeed > autocvar_g_turrets_unit_hk_std_shot_speed) ) - myspeed = max(myspeed * autocvar_g_turrets_unit_hk_std_shot_speed_decel, autocvar_g_turrets_unit_hk_std_shot_speed); - - // Failry clear, accelerate. - if ( (ff > 0.7) && (myspeed < autocvar_g_turrets_unit_hk_std_shot_speed_max) ) - myspeed = min(myspeed * autocvar_g_turrets_unit_hk_std_shot_speed_accel, autocvar_g_turrets_unit_hk_std_shot_speed_max); - - // Setup trace pitch - pt_seek = 1 - ff; - pt_seek = bound(0.15,pt_seek,0.8); - if (ff < 0.5) pt_seek = 1; - - // Trace left - traceline(self.origin, self.origin + (-1 * (v_right * pt_seek) + (v_forward * ff)) * lt_seek,false,self); - vl = trace_endpos; - fl = trace_fraction; - - // Trace right - traceline(self.origin, self.origin + ((v_right * pt_seek) + (v_forward * ff)) * lt_seek ,false,self); - vr = trace_endpos; - fr = trace_fraction; - - // Trace up - traceline(self.origin, self.origin + ((v_up * pt_seek) + (v_forward * ff)) * lt_seek ,false,self); - vu = trace_endpos; - fu = trace_fraction; - - // Trace down - traceline(self.origin, self.origin + (-1 * (v_up * pt_seek) + (v_forward * ff)) * lt_seek ,false,self); - vd = trace_endpos; - fd = trace_fraction; - - vl = normalize(vl - self.origin); - vr = normalize(vr - self.origin); - vu = normalize(vu - self.origin); - vd = normalize(vd - self.origin); - - // Panic tresh passed, find a single direction and turn as hard as we can - if (pt_seek == 1) - { - wishdir = v_right; - if (fl > fr) wishdir = -1 * v_right; - if (fu > fl) wishdir = v_up; - if (fd > fu) wishdir = -1 * v_up; - } - else - { - // Normalize our trace vectors to make a smooth path - wishdir = normalize( (vl * fl) + (vr * fr) + (vu * fu) + (vd * fd) ); - } - - if (self.enemy) - { - if (fe < 0.1) fe = 0.1; // Make sure we always try to move sligtly towards our target - wishdir = (wishdir * (1 - fe)) + (ve * fe); - } - } - else - { - // Got a clear path to target, speed up fast (if not at full speed) and go straight for it. - myspeed = vlen(self.velocity); - if (myspeed < autocvar_g_turrets_unit_hk_std_shot_speed_max) - myspeed = min(myspeed * autocvar_g_turrets_unit_hk_std_shot_speed_accel2,autocvar_g_turrets_unit_hk_std_shot_speed_max); - - wishdir = ve; - } - - if ((myspeed > autocvar_g_turrets_unit_hk_std_shot_speed) && (self.cnt > time)) - myspeed = min(myspeed * autocvar_g_turrets_unit_hk_std_shot_speed_accel2,autocvar_g_turrets_unit_hk_std_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_std_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); -} - -void turret_hk_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; - -} - -void turret_hk_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; -} - -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 turret_hk_dinit() -{ - if (self.netname == "") - self.netname = "Hunter-killer turret"; - - self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_MEDPROJ | TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_RECIVETARGETS; - 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_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK; - self.firecheck_flags = TFL_FIRECHECK_DEAD | TFL_FIRECHECK_TEAMCECK | TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AFF; - self.shoot_flags = TFL_SHOOT_CLEARTARGET; - - if (turret_stdproc_init("hk_std", "models/turrets/base.md3", "models/turrets/hk.md3", TID_HK) == 0) - { - remove(self); - return; - } - - self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_TEAMCHECK; - - // Our fire routine - self.turret_firefunc = turret_hk_attack; - - // re-color badge & handle recoil effect - self.turret_postthink = turret_hk_postthink; - - // What to do when reciveing foreign target data - self.turret_addtarget = turret_hk_addtarget; -} - - -/*QUAKED turret_hk (0 .5 .8) ? -* Turret that fires Hunter-killer missiles. -* Missiles seek their target and try to avoid obstacles. If target dies early, they -* pick a new one on their own. -*/ - -void spawnfunc_turret_hk() -{ - precache_model ("models/turrets/base.md3"); - precache_model ("models/turrets/hk.md3"); - - self.think = turret_hk_dinit; - self.nextthink = time + 0.5; -} - - diff --git a/qcsrc/server/tturrets/units/unit_machinegun.qc b/qcsrc/server/tturrets/units/unit_machinegun.qc deleted file mode 100644 index 21c6acfcce..0000000000 --- a/qcsrc/server/tturrets/units/unit_machinegun.qc +++ /dev/null @@ -1,54 +0,0 @@ -void W_MachineGun_MuzzleFlash(void); - -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 --git a/qcsrc/server/tturrets/units/unit_mlrs.qc b/qcsrc/server/tturrets/units/unit_mlrs.qc deleted file mode 100644 index 0b03dbce28..0000000000 --- a/qcsrc/server/tturrets/units/unit_mlrs.qc +++ /dev/null @@ -1,63 +0,0 @@ -void spawnfunc_turret_mlrs(); -void turret_mlrs_dinit(); -void turret_mlrs_attack(); - -void turret_mlrs_postthink() -{ - // 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"); - } -} - -void turret_mlrs_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); -} - -void turret_mlrs_dinit() -{ - if (self.netname == "") self.netname = "MLRS turret"; - - self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_MEDPROJ | TFL_TURRCAPS_PLAYERKILL; - self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE; - self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE; - - if (turret_stdproc_init("mlrs_std", "models/turrets/base.md3", "models/turrets/mlrs.md3", TID_MLRS) == 0) - { - remove(self); - return; - } - - self.damage_flags |= TFL_DMG_HEADSHAKE; - self.shoot_flags |= TFL_SHOOT_VOLLYALWAYS; - self.volly_counter = self.shot_volly; - - // Our fire routine - self.turret_firefunc = turret_mlrs_attack; - self.turret_postthink = turret_mlrs_postthink; - -} - -/*QUAKED turret_mlrs (0 .5 .8) ? -*/ - -void spawnfunc_turret_mlrs() -{ - precache_model ("models/turrets/mlrs.md3"); - precache_model ("models/turrets/base.md3"); - - self.think = turret_mlrs_dinit; - self.nextthink = time + 0.5; -} - - diff --git a/qcsrc/server/tturrets/units/unit_phaser.qc b/qcsrc/server/tturrets/units/unit_phaser.qc deleted file mode 100644 index dfda7a9134..0000000000 --- a/qcsrc/server/tturrets/units/unit_phaser.qc +++ /dev/null @@ -1,144 +0,0 @@ -#include "../../_all.qh" - -void spawnfunc_turret_phaser(); -void turret_phaser_dinit(); -void turret_phaser_attack(); - -.float fireflag; - -float turret_phaser_firecheck() -{ - if (self.fireflag != 0) return 0; - return turret_stdproc_firecheck(); -} - -void turret_phaser_postthink() -{ - if (self.tur_head.frame == 0) - return; - - 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; - } - } -} - -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 turret_phaser_attack() -{ - entity beam; - - beam = spawn(); - beam.ticrate = 0.1; //autocvar_sys_ticrate; - setmodel(beam,"models/turrets/phaser_beam.md3"); - beam.effects = EF_LOWPRECISION; - beam.solid = SOLID_NOT; - beam.think = beam_think; - beam.cnt = time + self.shot_speed; - beam.shot_spread = time + 2; - beam.nextthink = time; - beam.owner = self; - beam.shot_dmg = self.shot_dmg / (self.shot_speed / beam.ticrate); - beam.scale = self.target_range / 256; - beam.movetype = MOVETYPE_NONE; - beam.enemy = self.enemy; - beam.bot_dodge = true; - beam.bot_dodgerating = beam.shot_dmg; - sound (beam, CH_SHOTS_SINGLE, "turrets/phaser.wav", VOL_BASE, ATTEN_NORM); - self.fireflag = 1; - - beam.attack_finished_single = self.attack_finished_single; - self.attack_finished_single = time; // + autocvar_sys_ticrate; - - setattachment(beam,self.tur_head,"tag_fire"); - - soundat (self, trace_endpos, CH_SHOTS, "weapons/neximpact.wav", VOL_BASE, ATTEN_NORM); - - if (self.tur_head.frame == 0) - self.tur_head.frame = 1; -} - -void turret_phaser_dinit() -{ - if (self.netname == "") self.netname = "Phaser Cannon"; - - self.turrcaps_flags = TFL_TURRCAPS_SNIPER|TFL_TURRCAPS_HITSCAN|TFL_TURRCAPS_PLAYERKILL; - self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE; - self.aim_flags = TFL_AIM_LEAD; - - if (turret_stdproc_init("phaser_std", "models/turrets/base.md3","models/turrets/phaser.md3", TID_PHASER) == 0) - { - remove(self); - return; - } - - self.turret_firecheckfunc = turret_phaser_firecheck; - self.turret_firefunc = turret_phaser_attack; - self.turret_postthink = turret_phaser_postthink; - -} - -/*QUAKED turret_phaser(0 .5 .8) ? -*/ -void spawnfunc_turret_phaser() -{ - precache_sound ("turrets/phaser.wav"); - precache_model ("models/turrets/phaser.md3"); - precache_model ("models/turrets/phaser_beam.md3"); - precache_model ("models/turrets/base.md3"); - - self.think = turret_phaser_dinit; - self.nextthink = time + 0.5; -} - diff --git a/qcsrc/server/tturrets/units/unit_plasma.qc b/qcsrc/server/tturrets/units/unit_plasma.qc deleted file mode 100644 index 357826aff4..0000000000 --- a/qcsrc/server/tturrets/units/unit_plasma.qc +++ /dev/null @@ -1,173 +0,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); - - - Send_Effect("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); - missile.missile_flags = MIF_SPLASH; - - Send_Effect("laser_muzzleflash", self.tur_shotorg, self.tur_shotdir_updated * 1000, 1); - if (self.tur_head.frame == 0) - self.tur_head.frame = 1; -} - -void turret_plasma_dual_attack() -{ - entity missile = turret_projectile("weapons/hagar_fire.wav", 1, 0, DEATH_TURRET_PLASMA, PROJECTILE_ELECTRO_BEAM, true, true); - missile.missile_flags = MIF_SPLASH; - Send_Effect("laser_muzzleflash", self.tur_shotorg, self.tur_shotdir_updated * 1000, 1); - self.tur_head.frame += 1; -} - -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 --git a/qcsrc/server/tturrets/units/unit_targettrigger.qc b/qcsrc/server/tturrets/units/unit_targettrigger.qc deleted file mode 100644 index 0f2de3c869..0000000000 --- a/qcsrc/server/tturrets/units/unit_targettrigger.qc +++ /dev/null @@ -1,42 +0,0 @@ -void spawnfunc_turret_targettrigger(); -void turret_targettrigger_touch(); - -void turret_targettrigger_touch() -{ - entity e; - if (self.cnt > time) return; - entity oldself; - oldself = self; - - e = find(world, targetname, self.target); - while (e) - { - if (e.turrcaps_flags & TFL_TURRCAPS_RECIVETARGETS) - { - self = e; - if(e.turret_addtarget) - e.turret_addtarget(other,oldself); - } - - e = find(e, targetname, oldself.target); - } - - oldself.cnt = time + 0.5; - - self = oldself; -} - -/*QUAKED turret_targettrigger (.5 .5 .5) ? -*/ -void spawnfunc_turret_targettrigger() -{ - if (!autocvar_g_turrets) - { - remove(self); - return; - } - - InitTrigger (); - - self.touch = turret_targettrigger_touch; -} diff --git a/qcsrc/server/tturrets/units/unit_tessla.qc b/qcsrc/server/tturrets/units/unit_tessla.qc deleted file mode 100644 index c95de1373a..0000000000 --- a/qcsrc/server/tturrets/units/unit_tessla.qc +++ /dev/null @@ -1,193 +0,0 @@ -#include "../../csqceffects.qh" - -void spawnfunc_turret_tesla(); -void turret_tesla_dinit(); -void turret_tesla_fire(); - -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_stdproc_firecheck()) - return 0; - - if(self.enemy) - return 1; - - return 0; -} - - -void turret_tesla_fire() -{ - 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_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK; - - t = toast(e,r,d); - remove(e); - - if (t == world) return; - - 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; - } -} - -void turret_tesla_postthink() -{ - if (!self.active) - { - self.tur_head.avelocity = '0 0 0'; - return; - } - - 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; - - 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)); - } -} - - -void turret_tesla_dinit() -{ - if (self.netname == "") self.netname = "Tesla Coil"; - - self.turrcaps_flags = TFL_TURRCAPS_HITSCAN | TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_MISSILEKILL; - - self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES | - TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK; - - self.firecheck_flags = TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_OWM_AMMO; - self.shoot_flags = TFL_SHOOT_CUSTOM; - self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE; - self.aim_flags = TFL_AIM_NO; - self.track_flags = TFL_TRACK_NO; - - if (turret_stdproc_init("tesla_std", "models/turrets/tesla_base.md3", "models/turrets/tesla_head.md3", TID_TESLA) == 0) - { - remove(self); - return; - } - setsize(self,'-60 -60 0','60 60 128'); - - self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES | - TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK; - - self.turret_firefunc = turret_tesla_fire; - self.turret_postthink = turret_tesla_postthink; - self.turret_firecheckfunc = turret_tesla_firecheck; -} - -/*QUAKED turret_tesla (0 .5 .8) ? -*/ -void spawnfunc_turret_tesla() -{ - precache_model ("models/turrets/tesla_head.md3"); - precache_model ("models/turrets/tesla_base.md3"); - - - self.think = turret_tesla_dinit; - self.nextthink = time + 0.5; -} - diff --git a/qcsrc/server/tturrets/units/unit_walker.qc b/qcsrc/server/tturrets/units/unit_walker.qc deleted file mode 100644 index 16e8c5cad0..0000000000 --- a/qcsrc/server/tturrets/units/unit_walker.qc +++ /dev/null @@ -1,648 +0,0 @@ -#include "../../_all.qh" - -#include "../../movelib.qh" -#include "../../steerlib.qh" - -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; - -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); - 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, int 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_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 -} - -.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; - 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) - { - 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; - - 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); - 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); -} - -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); - Send_Effect("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.teleportable = TELEPORT_NORMAL; - 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 --git a/qcsrc/server/waypointsprites.qc b/qcsrc/server/waypointsprites.qc index 6130b61654..136beddb96 100644 --- a/qcsrc/server/waypointsprites.qc +++ b/qcsrc/server/waypointsprites.qc @@ -203,7 +203,7 @@ float WaypointSprite_visible_for_player(entity e) { if(!autocvar_sv_itemstime) return FALSE; - if(!warmup_stage && e.classname == "player") + if(!warmup_stage && IS_PLAYER(e)) return FALSE; } else if(self.team && self.rule == SPRITERULE_DEFAULT) @@ -313,12 +313,27 @@ float WaypointSprite_SendEntity(entity to, float sendflags) WriteCoord(MSG_ENTITY, self.fade_time); WriteCoord(MSG_ENTITY, self.teleport_time); WriteShort(MSG_ENTITY, self.fade_rate); // maxdist - float f; - f = 0; + float f = 0; if(self.currentammo) f |= 1; // hideable if(self.exteriormodeltoclient == to) f |= 2; // my own + if(g_onslaught) + { + if(self.owner.classname == "onslaught_controlpoint") + { + entity wp_owner = self.owner; + entity e = WaypointSprite_getviewentity(to); + if(SAME_TEAM(e, wp_owner) && wp_owner.goalentity.health >= wp_owner.goalentity.max_health) { f |= 2; } + if(!ons_ControlPoint_Attackable(wp_owner, e.team)) { f |= 2; } + } + if(self.owner.classname == "onslaught_generator") + { + entity wp_owner = self.owner; + if(wp_owner.isshielded && wp_owner.health >= wp_owner.max_health) { f |= 2; } + if(wp_owner.health <= 0) { f |= 2; } + } + } WriteByte(MSG_ENTITY, f); } diff --git a/qcsrc/whitespace.sh b/qcsrc/whitespace.sh index a017dc84f5..1e42413a1b 100755 --- a/qcsrc/whitespace.sh +++ b/qcsrc/whitespace.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash - -find . -type f -print0 | \ +cd ${0%[\\/]*} +find . -name .git -prune -o -type f -print0 | \ xargs -0 sed -i \ `# strip trailing spaces` \ -e 's/[[:space:]]*$//' \ diff --git a/turrets.cfg b/turrets.cfg index 876862b1c5..0c7b3be58a 100644 --- a/turrets.cfg +++ b/turrets.cfg @@ -2,57 +2,487 @@ set g_turrets 1 set g_turrets_reloadcvars 0 set g_turrets_nofire 0 -// Target scanning and validation can be resource intensive -// Dont let turrets look for new targets more frequently then this -set g_turrets_targetscan_mindelay 0.1 +set g_turrets_targetscan_mindelay 0.1 "delay target rescanning to lower resource usage" +set g_turrets_targetscan_maxdelay 1 "scan at least this often" +set g_turrets_aimidle_delay 5 "become idle if target is lost for this long" -// Do a targetscan at least this often regarless. -set g_turrets_targetscan_maxdelay 1 +alias g_turrets_reload "set g_turrets_reloadcvars 1" -// Turrets with no target returns to their idle aim after this much time. -set g_turrets_aimidle_delay 5 +// {{{ #1: eWheel Turret +set g_turrets_unit_ewheel_health 200 +set g_turrets_unit_ewheel_respawntime 30 -// --- Units --- +set g_turrets_unit_ewheel_turnrate 200 -// Machinegun on a stick. -exec unit_machinegun.cfg +set g_turrets_unit_ewheel_speed_fast 500 +set g_turrets_unit_ewheel_speed_slow 150 +set g_turrets_unit_ewheel_speed_slower 50 +set g_turrets_unit_ewheel_speed_stop 25 -// Hunter killer rocket turret. "smart rockets" -exec unit_hk.cfg +set g_turrets_unit_ewheel_shot_dmg 30 +set g_turrets_unit_ewheel_shot_refire 0.1 +set g_turrets_unit_ewheel_shot_spread 0.025 +set g_turrets_unit_ewheel_shot_force 125 +set g_turrets_unit_ewheel_shot_radius 50 +set g_turrets_unit_ewheel_shot_speed 9000 -// Fires a pair of accelerating, simple homing rockets. -exec unit_hellion.cfg +set g_turrets_unit_ewheel_shot_volly 2 +set g_turrets_unit_ewheel_shot_volly_refire 1 -// Fire lots of dumbfire rockets -exec unit_mlrs.cfg +set g_turrets_unit_ewheel_target_range 5000 +set g_turrets_unit_ewheel_target_range_optimal 900 +set g_turrets_unit_ewheel_target_range_min 0.1 -// Kills killable enemy missiles. -exec unit_flac.cfg +set g_turrets_unit_ewheel_target_select_rangebias 0.25 +set g_turrets_unit_ewheel_target_select_samebias 2 +set g_turrets_unit_ewheel_target_select_anglebias 0.5 +set g_turrets_unit_ewheel_target_select_playerbias 1 +set g_turrets_unit_ewheel_target_select_missilebias 0 -// Support unit. Recharges friendly energy based turrets in range -exec unit_fusreac.cfg +set g_turrets_unit_ewheel_ammo_max 4000 +set g_turrets_unit_ewheel_ammo 500 +set g_turrets_unit_ewheel_ammo_recharge 50 -// "Electro" turret. -exec unit_plasma.cfg +set g_turrets_unit_ewheel_aim_firetolerance_dist 150 +set g_turrets_unit_ewheel_aim_speed 90 +set g_turrets_unit_ewheel_aim_maxrot 20 +set g_turrets_unit_ewheel_aim_maxpitch 45 -// The the all new "Electro" turret, same ting with two barrels. -exec unit_plasma2.cfg +set g_turrets_unit_ewheel_track_type 1 +set g_turrets_unit_ewheel_track_accel_pitch 0 +set g_turrets_unit_ewheel_track_accel_rot 0 +// }}} +// {{{ #2: FLAC Cannon +set g_turrets_unit_flac_health 700 +set g_turrets_unit_flac_respawntime 90 -// AAAaaaarg! Bzzaat! yber turret. chain lightning missile and player killing. -exec unit_tesla.cfg +set g_turrets_unit_flac_shot_dmg 20 +set g_turrets_unit_flac_shot_refire 0.1 +set g_turrets_unit_flac_shot_radius 100 +set g_turrets_unit_flac_shot_speed 9000 +set g_turrets_unit_flac_shot_spread 0.02 +set g_turrets_unit_flac_shot_force 25 +set g_turrets_unit_flac_shot_volly 0 +set g_turrets_unit_flac_shot_volly_refire 0 -// Fires a constant beam that slows down and slowly damages its target. -exec unit_phaser.cfg +set g_turrets_unit_flac_target_range 4000 +set g_turrets_unit_flac_target_range_min 500 +set g_turrets_unit_flac_target_range_optimal 1250 -// The bastred son of a turret and a quake monster. -// A walking minigun with longrage missiles and closerange meele attack. -exec unit_walker.cfg +set g_turrets_unit_flac_target_select_rangebias 0.25 +set g_turrets_unit_flac_target_select_samebias 1 +set g_turrets_unit_flac_target_select_anglebias 0.5 +set g_turrets_unit_flac_target_select_playerbias 0 +set g_turrets_unit_flac_target_select_missilebias 1 -// OMG! Its the Evil Wheel! :O -exec unit_ewheel.cfg +set g_turrets_unit_flac_ammo_max 1000 +set g_turrets_unit_flac_ammo 400 +set g_turrets_unit_flac_ammo_recharge 100 -// It is so repulsive, it doesn't even exist! -// exec unit_repulsor.cfg +set g_turrets_unit_flac_aim_firetolerance_dist 150 +set g_turrets_unit_flac_aim_speed 200 +set g_turrets_unit_flac_aim_maxrot 360 +set g_turrets_unit_flac_aim_maxpitch 35 -set g_turrets_reloadcvars 0 // reload when this cfg has been exec'd -alias g_turrets_reload "set g_turrets_reloadcvars 1" +set g_turrets_unit_flac_track_type 3 +set g_turrets_unit_flac_track_accel_pitch 0.5 +set g_turrets_unit_flac_track_accel_rot 0.7 +set g_turrets_unit_flac_track_blendrate 0.2 +// }}} +// {{{ #3: Fusion Reactor +set g_turrets_unit_fusreac_health 700 +set g_turrets_unit_fusreac_respawntime 90 + +set g_turrets_unit_fusreac_shot_speed 1 +set g_turrets_unit_fusreac_shot_dmg 20 +set g_turrets_unit_fusreac_shot_refire 0.2 + +set g_turrets_unit_fusreac_target_range 1024 +set g_turrets_unit_fusreac_target_range_min 1 + +set g_turrets_unit_fusreac_ammo_max 100 +set g_turrets_unit_fusreac_ammo 0 +set g_turrets_unit_fusreac_ammo_recharge 100 + +set g_turrets_unit_fusreac_shot_radius 0 +set g_turrets_unit_fusreac_shot_spread 0 +set g_turrets_unit_fusreac_shot_force 0 +set g_turrets_unit_fusreac_shot_volly 0 +set g_turrets_unit_fusreac_shot_volly_refire 0 +set g_turrets_unit_fusreac_target_range_optimal 0 +set g_turrets_unit_fusreac_target_select_rangebias 0 +set g_turrets_unit_fusreac_target_select_samebias 0 +set g_turrets_unit_fusreac_target_select_anglebias 0 +set g_turrets_unit_fusreac_target_select_playerbias 0 +set g_turrets_unit_fusreac_aim_firetolerance_dist 0 +set g_turrets_unit_fusreac_aim_speed 0 +set g_turrets_unit_fusreac_aim_maxrot 0 +set g_turrets_unit_fusreac_aim_maxpitch 0 +set g_turrets_unit_fusreac_track_type 0 +set g_turrets_unit_fusreac_track_accel_pitch 0 +set g_turrets_unit_fusreac_track_accel_rot 0 +set g_turrets_unit_fusreac_track_blendrate 0 +// }}} +// {{{ #4: Hellion Missile Turret +set g_turrets_unit_hellion_health 500 +set g_turrets_unit_hellion_respawntime 90 + +set g_turrets_unit_hellion_shot_dmg 50 +set g_turrets_unit_hellion_shot_refire 0.2 +set g_turrets_unit_hellion_shot_radius 80 + +set g_turrets_unit_hellion_shot_speed 650 +set g_turrets_unit_hellion_shot_speed_max 4000 +set g_turrets_unit_hellion_shot_speed_gain 1.01 + +set g_turrets_unit_hellion_shot_spread 0.08 +set g_turrets_unit_hellion_shot_force 250 +set g_turrets_unit_hellion_shot_volly 2 +set g_turrets_unit_hellion_shot_volly_refire 4 + +set g_turrets_unit_hellion_target_range 6000 +set g_turrets_unit_hellion_target_range_min 150 +set g_turrets_unit_hellion_target_range_optimal 4500 + +set g_turrets_unit_hellion_target_select_rangebias 0.7 +set g_turrets_unit_hellion_target_select_samebias 0.01 +set g_turrets_unit_hellion_target_select_anglebias 0.01 +set g_turrets_unit_hellion_target_select_playerbias 1 +set g_turrets_unit_hellion_target_select_missilebias 0 + +set g_turrets_unit_hellion_ammo_max 200 +set g_turrets_unit_hellion_ammo 100 +set g_turrets_unit_hellion_ammo_recharge 50 + +set g_turrets_unit_hellion_aim_firetolerance_dist 200 +set g_turrets_unit_hellion_aim_speed 100 +set g_turrets_unit_hellion_aim_maxrot 360 +set g_turrets_unit_hellion_aim_maxpitch 20 + +set g_turrets_unit_hellion_track_type 3 +set g_turrets_unit_hellion_track_accel_pitch 0.25 +set g_turrets_unit_hellion_track_accel_rot 0.6 +set g_turrets_unit_hellion_track_blendrate 0.25 +// }}} +// {{{ #5: Hunter-Killer Turret +set g_turrets_unit_hk_health 500 +set g_turrets_unit_hk_respawntime 90 + +set g_turrets_unit_hk_shot_dmg 120 +set g_turrets_unit_hk_shot_refire 5 +set g_turrets_unit_hk_shot_radius 200 + +set g_turrets_unit_hk_shot_speed 500 +set g_turrets_unit_hk_shot_speed_max 1000 +set g_turrets_unit_hk_shot_speed_accel 1.025 +set g_turrets_unit_hk_shot_speed_accel2 1.05 +set g_turrets_unit_hk_shot_speed_decel 0.9 +set g_turrets_unit_hk_shot_speed_turnrate 0.25 + +set g_turrets_unit_hk_shot_spread 0 +set g_turrets_unit_hk_shot_force 600 +set g_turrets_unit_hk_shot_volly 0 +set g_turrets_unit_hk_shot_volly_refire 0 + +set g_turrets_unit_hk_target_range 6000 +set g_turrets_unit_hk_target_range_min 220 +set g_turrets_unit_hk_target_range_optimal 5000 + +set g_turrets_unit_hk_target_select_rangebias 0.5 +set g_turrets_unit_hk_target_select_samebias 0.01 +set g_turrets_unit_hk_target_select_anglebias 0.1 +set g_turrets_unit_hk_target_select_playerbias 1 +set g_turrets_unit_hk_target_select_missilebias 0 + +set g_turrets_unit_hk_ammo_max 240 +set g_turrets_unit_hk_ammo 120 +set g_turrets_unit_hk_ammo_recharge 16 + +set g_turrets_unit_hk_aim_firetolerance_dist 500 +set g_turrets_unit_hk_aim_speed 100 +set g_turrets_unit_hk_aim_maxrot 360 +set g_turrets_unit_hk_aim_maxpitch 20 + +set g_turrets_unit_hk_track_type 3 +set g_turrets_unit_hk_track_accel_pitch 0.25 +set g_turrets_unit_hk_track_accel_rot 0.6 +set g_turrets_unit_hk_track_blendrate 0.2 +// }}} +// {{{ #6: Machinegun Turret +set g_turrets_unit_machinegun_health 256 +set g_turrets_unit_machinegun_respawntime 60 + +set g_turrets_unit_machinegun_shot_dmg 10 +set g_turrets_unit_machinegun_shot_refire 0.1 +set g_turrets_unit_machinegun_shot_spread 0.015 +set g_turrets_unit_machinegun_shot_force 20 +set g_turrets_unit_machinegun_shot_radius 0 +set g_turrets_unit_machinegun_shot_speed 34920 + +set g_turrets_unit_machinegun_shot_volly 5 +set g_turrets_unit_machinegun_shot_volly_refire 0.5 + +set g_turrets_unit_machinegun_target_range 4500 +set g_turrets_unit_machinegun_target_range_min 2 +set g_turrets_unit_machinegun_target_range_optimal 1000 + +set g_turrets_unit_machinegun_target_select_rangebias 0.25 +set g_turrets_unit_machinegun_target_select_samebias 0.25 +set g_turrets_unit_machinegun_target_select_anglebias 0.5 +set g_turrets_unit_machinegun_target_select_playerbias 1 +set g_turrets_unit_machinegun_target_select_missilebias 0 + +set g_turrets_unit_machinegun_ammo_max 1500 +set g_turrets_unit_machinegun_ammo 300 +set g_turrets_unit_machinegun_ammo_recharge 75 + +set g_turrets_unit_machinegun_aim_firetolerance_dist 25 +set g_turrets_unit_machinegun_aim_speed 120 +set g_turrets_unit_machinegun_aim_maxrot 360 +set g_turrets_unit_machinegun_aim_maxpitch 25 + +set g_turrets_unit_machinegun_track_type 3 +set g_turrets_unit_machinegun_track_accel_pitch 0.4 +set g_turrets_unit_machinegun_track_accel_rot 0.9 +set g_turrets_unit_machinegun_track_blendrate 0.2 +// }}} +// {{{ #7: MLRS Turret +set g_turrets_unit_mlrs_health 500 +set g_turrets_unit_mlrs_respawntime 60 + +set g_turrets_unit_mlrs_shot_dmg 50 +set g_turrets_unit_mlrs_shot_refire 0.1 +set g_turrets_unit_mlrs_shot_radius 125 +set g_turrets_unit_mlrs_shot_speed 2000 +set g_turrets_unit_mlrs_shot_spread 0.05 +set g_turrets_unit_mlrs_shot_force 25 + +set g_turrets_unit_mlrs_shot_volly 6 + +set g_turrets_unit_mlrs_shot_volly_refire 4 + +set g_turrets_unit_mlrs_target_range 3000 +set g_turrets_unit_mlrs_target_range_min 500 +set g_turrets_unit_mlrs_target_range_optimal 500 + +set g_turrets_unit_mlrs_target_select_rangebias 0.25 +set g_turrets_unit_mlrs_target_select_samebias 0.5 +set g_turrets_unit_mlrs_target_select_anglebias 0.5 +set g_turrets_unit_mlrs_target_select_playerbias 1 +set g_turrets_unit_mlrs_target_select_missilebias 0 + +set g_turrets_unit_mlrs_ammo_max 300 +set g_turrets_unit_mlrs_ammo 300 +set g_turrets_unit_mlrs_ammo_recharge 75 + +set g_turrets_unit_mlrs_aim_firetolerance_dist 120 +set g_turrets_unit_mlrs_aim_speed 100 +set g_turrets_unit_mlrs_aim_maxrot 360 +set g_turrets_unit_mlrs_aim_maxpitch 20 + +set g_turrets_unit_mlrs_track_type 3 +set g_turrets_unit_mlrs_track_accel_pitch 0.5 +set g_turrets_unit_mlrs_track_accel_rot 0.7 +set g_turrets_unit_mlrs_track_blendrate 0.2 +// }}} +// {{{ #8: Phaser Cannon +set g_turrets_unit_phaser_health 500 + +set g_turrets_unit_phaser_respawntime 90 + +set g_turrets_unit_phaser_shot_dmg 100 +set g_turrets_unit_phaser_shot_refire 4 +set g_turrets_unit_phaser_shot_radius 8 +set g_turrets_unit_phaser_shot_speed 4 +set g_turrets_unit_phaser_shot_spread 0 +set g_turrets_unit_phaser_shot_force 5 +set g_turrets_unit_phaser_shot_volly 0 +set g_turrets_unit_phaser_shot_volly_refire 5 + +set g_turrets_unit_phaser_target_range 3000 +set g_turrets_unit_phaser_target_range_min 0 +set g_turrets_unit_phaser_target_range_optimal 1500 + +set g_turrets_unit_phaser_target_select_rangebias 0.85 +set g_turrets_unit_phaser_target_select_samebias 0 +set g_turrets_unit_phaser_target_select_anglebias 0.25 +set g_turrets_unit_phaser_target_select_playerbias 1 +set g_turrets_unit_phaser_target_select_missilebias 0 + +set g_turrets_unit_phaser_ammo_max 2000 +set g_turrets_unit_phaser_ammo 1000 +set g_turrets_unit_phaser_ammo_recharge 25 + +set g_turrets_unit_phaser_aim_firetolerance_dist 100 + +set g_turrets_unit_phaser_aim_speed 300 +set g_turrets_unit_phaser_aim_maxrot 360 +set g_turrets_unit_phaser_aim_maxpitch 30 + +set g_turrets_unit_phaser_track_type 3 +set g_turrets_unit_phaser_track_accel_pitch 0.5 +set g_turrets_unit_phaser_track_accel_rot 0.65 +set g_turrets_unit_phaser_track_blendrate 0.2 +// }}} +// {{{ #9: Plasma Cannon +set g_turrets_unit_plasma_health 500 +set g_turrets_unit_plasma_respawntime 60 + +set g_turrets_unit_plasma_shot_dmg 80 +set g_turrets_unit_plasma_shot_refire 0.6 +set g_turrets_unit_plasma_shot_radius 150 +set g_turrets_unit_plasma_shot_speed 2000 +set g_turrets_unit_plasma_shot_spread 0.015 +set g_turrets_unit_plasma_shot_force 100 +set g_turrets_unit_plasma_shot_volly 0 +set g_turrets_unit_plasma_shot_volly_refire 0 + +set g_turrets_unit_plasma_target_range 3500 +set g_turrets_unit_plasma_target_range_min 200 +set g_turrets_unit_plasma_target_range_optimal 500 + +set g_turrets_unit_plasma_target_select_rangebias 0.5 +set g_turrets_unit_plasma_target_select_samebias 0.01 +set g_turrets_unit_plasma_target_select_anglebias 0.25 +set g_turrets_unit_plasma_target_select_playerbias 1 +set g_turrets_unit_plasma_target_select_missilebias 0 + +set g_turrets_unit_plasma_ammo_max 640 +set g_turrets_unit_plasma_ammo 320 +set g_turrets_unit_plasma_ammo_recharge 40 + +set g_turrets_unit_plasma_aim_firetolerance_dist 120 +set g_turrets_unit_plasma_aim_speed 200 +set g_turrets_unit_plasma_aim_maxrot 360 +set g_turrets_unit_plasma_aim_maxpitch 30 + +set g_turrets_unit_plasma_track_type 3 +set g_turrets_unit_plasma_track_accel_pitch 0.5 +set g_turrets_unit_plasma_track_accel_rot 0.7 +set g_turrets_unit_plasma_track_blendrate 0.2 +// }}} +// {{{ #10: Dual Plasma Cannon +set g_turrets_unit_plasma_dual_health 500 +set g_turrets_unit_plasma_dual_respawntime 60 + +set g_turrets_unit_plasma_dual_shot_dmg 80 +set g_turrets_unit_plasma_dual_shot_refire 0.35 +set g_turrets_unit_plasma_dual_shot_radius 150 +set g_turrets_unit_plasma_dual_shot_speed 2000 +set g_turrets_unit_plasma_dual_shot_spread 0.015 +set g_turrets_unit_plasma_dual_shot_force 100 + +set g_turrets_unit_plasma_dual_shot_volly 0 +set g_turrets_unit_plasma_dual_shot_volly_refire 0 + +set g_turrets_unit_plasma_dual_target_range 3000 +set g_turrets_unit_plasma_dual_target_range_min 80 +set g_turrets_unit_plasma_dual_target_range_optimal 1000 + +set g_turrets_unit_plasma_dual_target_select_rangebias 0.2 +set g_turrets_unit_plasma_dual_target_select_samebias 0.4 +set g_turrets_unit_plasma_dual_target_select_anglebias 0.4 +set g_turrets_unit_plasma_dual_target_select_playerbias 1 +set g_turrets_unit_plasma_dual_target_select_missilebias 0 + +set g_turrets_unit_plasma_dual_ammo_max 640 +set g_turrets_unit_plasma_dual_ammo 320 +set g_turrets_unit_plasma_dual_ammo_recharge 40 + +set g_turrets_unit_plasma_dual_aim_firetolerance_dist 200 + +set g_turrets_unit_plasma_dual_aim_speed 100 +set g_turrets_unit_plasma_dual_aim_maxrot 360 +set g_turrets_unit_plasma_dual_aim_maxpitch 30 + +set g_turrets_unit_plasma_dual_track_type 3 +set g_turrets_unit_plasma_dual_track_accel_pitch 0.5 +set g_turrets_unit_plasma_dual_track_accel_rot 0.7 +set g_turrets_unit_plasma_dual_track_blendrate 0.2 +// }}} +// {{{ #11: Tesla Coil +set g_turrets_unit_tesla_health 1000 +set g_turrets_unit_tesla_respawntime 120 + +set g_turrets_unit_tesla_shot_dmg 200 +set g_turrets_unit_tesla_shot_refire 1.5 +set g_turrets_unit_tesla_shot_force 400 + +set g_turrets_unit_tesla_shot_volly 1 +set g_turrets_unit_tesla_shot_volly_refire 2.5 + +set g_turrets_unit_tesla_target_range_min 0 +set g_turrets_unit_tesla_target_range 1000 + +set g_turrets_unit_tesla_target_select_playerbias 1 +set g_turrets_unit_tesla_target_select_missilebias 1 + +set g_turrets_unit_tesla_ammo_max 1000 +set g_turrets_unit_tesla_ammo 200 +set g_turrets_unit_tesla_ammo_recharge 15 +// }}} +// {{{ #12: Walker Turret +set g_turrets_unit_walker_health 500 +set g_turrets_unit_walker_respawntime 60 + +set g_turrets_unit_walker_speed_run 300 +set g_turrets_unit_walker_speed_roam 100 +set g_turrets_unit_walker_speed_walk 200 +set g_turrets_unit_walker_speed_swim 200 +set g_turrets_unit_walker_speed_jump 800 +set g_turrets_unit_walker_speed_stop 90 + +set g_turrets_unit_walker_turn 20 +set g_turrets_unit_walker_turn_walk 15 +set g_turrets_unit_walker_turn_run 7 +set g_turrets_unit_walker_turn_swim 10 +set g_turrets_unit_walker_turn_strafe 5 + +set g_turrets_unit_walker_shot_dmg 5 +set g_turrets_unit_walker_shot_refire 0.05 +set g_turrets_unit_walker_shot_spread 0.025 +set g_turrets_unit_walker_shot_force 10 +set g_turrets_unit_walker_shot_radius 0 +set g_turrets_unit_walker_shot_speed 18000 + +set g_turrets_unit_walker_shot_volly 10 +set g_turrets_unit_walker_shot_volly_refire 1 + +set g_turrets_unit_walker_target_range 5000 +set g_turrets_unit_walker_target_range_optimal 100 +set g_turrets_unit_walker_target_range_min 0 + +set g_turrets_unit_walker_target_select_rangebias 0.25 +set g_turrets_unit_walker_target_select_samebias 0.25 +set g_turrets_unit_walker_target_select_anglebias 0.5 +set g_turrets_unit_walker_target_select_playerbias 1 +set g_turrets_unit_walker_target_select_missilebias 0 + +set g_turrets_unit_walker_ammo_max 4000 +set g_turrets_unit_walker_ammo 500 +set g_turrets_unit_walker_ammo_recharge 100 + +set g_turrets_unit_walker_aim_firetolerance_dist 100 +set g_turrets_unit_walker_aim_speed 45 +set g_turrets_unit_walker_aim_maxrot 90 +set g_turrets_unit_walker_aim_maxpitch 15 + +set g_turrets_unit_walker_track_type 1 + +set g_turrets_unit_walker_rocket_range 4000 +set g_turrets_unit_walker_rocket_range_min 500 +set g_turrets_unit_walker_rocket_refire 10 +set g_turrets_unit_walker_rocket_damage 45 +set g_turrets_unit_walker_rocket_radius 150 +set g_turrets_unit_walker_rocket_force 150 +set g_turrets_unit_walker_rocket_turnrate 0.05 +set g_turrets_unit_walker_rocket_speed 1000 + +set g_turrets_unit_walker_melee_range 100 +set g_turrets_unit_walker_melee_damage 100 +set g_turrets_unit_walker_melee_force 600 + +set g_turrets_unit_walker_track_accel_pitch 0.5 +set g_turrets_unit_walker_track_accel_rot 0.8 +set g_turrets_unit_walker_track_blendrate 0.2 +// }}} diff --git a/unit_ewheel.cfg b/unit_ewheel.cfg deleted file mode 100644 index df0562af9a..0000000000 --- a/unit_ewheel.cfg +++ /dev/null @@ -1,43 +0,0 @@ -set g_turrets_unit_ewheel_std_health 200 -set g_turrets_unit_ewheel_std_respawntime 30 - -// dgr / sec -set g_turrets_unit_ewheel_turnrate 200 - -set g_turrets_unit_ewheel_speed_fast 500 -set g_turrets_unit_ewheel_speed_slow 150 -set g_turrets_unit_ewheel_speed_slower 50 -set g_turrets_unit_ewheel_speed_stop 25 - -set g_turrets_unit_ewheel_std_shot_dmg 30 -set g_turrets_unit_ewheel_std_shot_refire 0.1 -set g_turrets_unit_ewheel_std_shot_spread 0.025 -set g_turrets_unit_ewheel_std_shot_force 125 -set g_turrets_unit_ewheel_std_shot_radius 50 -set g_turrets_unit_ewheel_std_shot_speed 9000 - -set g_turrets_unit_ewheel_std_shot_volly 2 -set g_turrets_unit_ewheel_std_shot_volly_refire 1 - -set g_turrets_unit_ewheel_std_target_range 5000 -set g_turrets_unit_ewheel_std_target_range_optimal 900 -set g_turrets_unit_ewheel_std_target_range_min 0.1 - -set g_turrets_unit_ewheel_std_target_select_rangebias 0.25 -set g_turrets_unit_ewheel_std_target_select_samebias 2 -set g_turrets_unit_ewheel_std_target_select_anglebias 0.5 -set g_turrets_unit_ewheel_std_target_select_playerbias 1 -set g_turrets_unit_ewheel_std_target_select_missilebias 0 - -set g_turrets_unit_ewheel_std_ammo_max 4000 -set g_turrets_unit_ewheel_std_ammo 500 -set g_turrets_unit_ewheel_std_ammo_recharge 50 - -set g_turrets_unit_ewheel_std_aim_firetolerance_dist 150 -set g_turrets_unit_ewheel_std_aim_speed 90 -set g_turrets_unit_ewheel_std_aim_maxrot 20 -set g_turrets_unit_ewheel_std_aim_maxpitch 45 - -set g_turrets_unit_ewheel_std_track_type 1 -set g_turrets_unit_ewheel_std_track_accel_pitch 0 -set g_turrets_unit_ewheel_std_track_accel_rot 0 diff --git a/unit_flac.cfg b/unit_flac.cfg deleted file mode 100644 index 17ba6a5aba..0000000000 --- a/unit_flac.cfg +++ /dev/null @@ -1,35 +0,0 @@ -set g_turrets_unit_flac_std_health 700 -set g_turrets_unit_flac_std_respawntime 90 - -set g_turrets_unit_flac_std_shot_dmg 20 -set g_turrets_unit_flac_std_shot_refire 0.1 -set g_turrets_unit_flac_std_shot_radius 100 -set g_turrets_unit_flac_std_shot_speed 9000 -set g_turrets_unit_flac_std_shot_spread 0.02 -set g_turrets_unit_flac_std_shot_force 25 -set g_turrets_unit_flac_std_shot_volly 0 -set g_turrets_unit_flac_std_shot_volly_refire 0 - -set g_turrets_unit_flac_std_target_range 4000 -set g_turrets_unit_flac_std_target_range_min 500 -set g_turrets_unit_flac_std_target_range_optimal 1250 - -set g_turrets_unit_flac_std_target_select_rangebias 0.25 -set g_turrets_unit_flac_std_target_select_samebias 1 -set g_turrets_unit_flac_std_target_select_anglebias 0.5 -set g_turrets_unit_flac_std_target_select_playerbias 0 -set g_turrets_unit_flac_std_target_select_missilebias 1 - -set g_turrets_unit_flac_std_ammo_max 1000 -set g_turrets_unit_flac_std_ammo 400 -set g_turrets_unit_flac_std_ammo_recharge 100 - -set g_turrets_unit_flac_std_aim_firetolerance_dist 150 -set g_turrets_unit_flac_std_aim_speed 200 -set g_turrets_unit_flac_std_aim_maxrot 360 -set g_turrets_unit_flac_std_aim_maxpitch 35 - -set g_turrets_unit_flac_std_track_type 3 -set g_turrets_unit_flac_std_track_accel_pitch 0.5 -set g_turrets_unit_flac_std_track_accel_rot 0.7 -set g_turrets_unit_flac_std_track_blendrate 0.2 diff --git a/unit_fusreac.cfg b/unit_fusreac.cfg deleted file mode 100644 index c9373f68fe..0000000000 --- a/unit_fusreac.cfg +++ /dev/null @@ -1,32 +0,0 @@ -set g_turrets_unit_fusreac_std_health 700 -set g_turrets_unit_fusreac_std_respawntime 90 - -set g_turrets_unit_fusreac_std_shot_speed 1 -set g_turrets_unit_fusreac_std_shot_dmg 20 -set g_turrets_unit_fusreac_std_shot_refire 0.2 - -set g_turrets_unit_fusreac_std_target_range 1024 -set g_turrets_unit_fusreac_std_target_range_min 1 - -set g_turrets_unit_fusreac_std_ammo_max 100 -set g_turrets_unit_fusreac_std_ammo 0 -set g_turrets_unit_fusreac_std_ammo_recharge 100 - -set g_turrets_unit_fusreac_std_shot_radius 0 -set g_turrets_unit_fusreac_std_shot_spread 0 -set g_turrets_unit_fusreac_std_shot_force 0 -set g_turrets_unit_fusreac_std_shot_volly 0 -set g_turrets_unit_fusreac_std_shot_volly_refire 0 -set g_turrets_unit_fusreac_std_target_range_optimal 0 -set g_turrets_unit_fusreac_std_target_select_rangebias 0 -set g_turrets_unit_fusreac_std_target_select_samebias 0 -set g_turrets_unit_fusreac_std_target_select_anglebias 0 -set g_turrets_unit_fusreac_std_target_select_playerbias 0 -set g_turrets_unit_fusreac_std_aim_firetolerance_dist 0 -set g_turrets_unit_fusreac_std_aim_speed 0 -set g_turrets_unit_fusreac_std_aim_maxrot 0 -set g_turrets_unit_fusreac_std_aim_maxpitch 0 -set g_turrets_unit_fusreac_std_track_type 0 -set g_turrets_unit_fusreac_std_track_accel_pitch 0 -set g_turrets_unit_fusreac_std_track_accel_rot 0 -set g_turrets_unit_fusreac_std_track_blendrate 0 \ No newline at end of file diff --git a/unit_hellion.cfg b/unit_hellion.cfg deleted file mode 100644 index cdf7546b8c..0000000000 --- a/unit_hellion.cfg +++ /dev/null @@ -1,40 +0,0 @@ -set g_turrets_unit_hellion_std_health 500 -set g_turrets_unit_hellion_std_respawntime 90 - -set g_turrets_unit_hellion_std_shot_dmg 50 -set g_turrets_unit_hellion_std_shot_refire 0.2 -set g_turrets_unit_hellion_std_shot_radius 80 - -set g_turrets_unit_hellion_std_shot_speed 650 -set g_turrets_unit_hellion_std_shot_speed_max 4000 -set g_turrets_unit_hellion_std_shot_speed_gain 1.01 - -set g_turrets_unit_hellion_std_shot_spread 0.08 -set g_turrets_unit_hellion_std_shot_force 250 -set g_turrets_unit_hellion_std_shot_volly 2 -set g_turrets_unit_hellion_std_shot_volly_refire 4 - -set g_turrets_unit_hellion_std_target_range 6000 -set g_turrets_unit_hellion_std_target_range_min 150 -set g_turrets_unit_hellion_std_target_range_optimal 4500 - -set g_turrets_unit_hellion_std_target_select_rangebias 0.7 -set g_turrets_unit_hellion_std_target_select_samebias 0.01 -set g_turrets_unit_hellion_std_target_select_anglebias 0.01 -set g_turrets_unit_hellion_std_target_select_playerbias 1 -set g_turrets_unit_hellion_std_target_select_missilebias 0 - -set g_turrets_unit_hellion_std_ammo_max 200 -set g_turrets_unit_hellion_std_ammo 100 -set g_turrets_unit_hellion_std_ammo_recharge 50 - -set g_turrets_unit_hellion_std_aim_firetolerance_dist 200 -set g_turrets_unit_hellion_std_aim_speed 100 -set g_turrets_unit_hellion_std_aim_maxrot 360 -set g_turrets_unit_hellion_std_aim_maxpitch 20 - -set g_turrets_unit_hellion_std_track_type 3 -set g_turrets_unit_hellion_std_track_accel_pitch 0.25 -set g_turrets_unit_hellion_std_track_accel_rot 0.6 -set g_turrets_unit_hellion_std_track_blendrate 0.25 - diff --git a/unit_hk.cfg b/unit_hk.cfg deleted file mode 100644 index 590181e09d..0000000000 --- a/unit_hk.cfg +++ /dev/null @@ -1,43 +0,0 @@ -set g_turrets_unit_hk_std_health 500 -set g_turrets_unit_hk_std_respawntime 90 - -set g_turrets_unit_hk_std_shot_dmg 120 -set g_turrets_unit_hk_std_shot_refire 5 -set g_turrets_unit_hk_std_shot_radius 200 - -set g_turrets_unit_hk_std_shot_speed 500 -set g_turrets_unit_hk_std_shot_speed_max 1000 -set g_turrets_unit_hk_std_shot_speed_accel 1.025 -set g_turrets_unit_hk_std_shot_speed_accel2 1.05 -set g_turrets_unit_hk_std_shot_speed_decel 0.9 -set g_turrets_unit_hk_std_shot_speed_turnrate 0.25 - -set g_turrets_unit_hk_std_shot_spread 0 -set g_turrets_unit_hk_std_shot_force 600 -set g_turrets_unit_hk_std_shot_volly 0 -set g_turrets_unit_hk_std_shot_volly_refire 0 - -set g_turrets_unit_hk_std_target_range 6000 -set g_turrets_unit_hk_std_target_range_min 220 -set g_turrets_unit_hk_std_target_range_optimal 5000 - -set g_turrets_unit_hk_std_target_select_rangebias 0.5 -set g_turrets_unit_hk_std_target_select_samebias 0.01 -set g_turrets_unit_hk_std_target_select_anglebias 0.1 -set g_turrets_unit_hk_std_target_select_playerbias 1 -set g_turrets_unit_hk_std_target_select_missilebias 0 - -set g_turrets_unit_hk_std_ammo_max 240 -set g_turrets_unit_hk_std_ammo 120 -set g_turrets_unit_hk_std_ammo_recharge 16 - -set g_turrets_unit_hk_std_aim_firetolerance_dist 500 -set g_turrets_unit_hk_std_aim_speed 100 -set g_turrets_unit_hk_std_aim_maxrot 360 -set g_turrets_unit_hk_std_aim_maxpitch 20 - -set g_turrets_unit_hk_std_track_type 3 -set g_turrets_unit_hk_std_track_accel_pitch 0.25 -set g_turrets_unit_hk_std_track_accel_rot 0.6 -set g_turrets_unit_hk_std_track_blendrate 0.2 - diff --git a/unit_machinegun.cfg b/unit_machinegun.cfg deleted file mode 100644 index 1fa1e48d5c..0000000000 --- a/unit_machinegun.cfg +++ /dev/null @@ -1,38 +0,0 @@ -set g_turrets_unit_machinegun_std_health 256 -set g_turrets_unit_machinegun_std_respawntime 60 - -set g_turrets_unit_machinegun_std_shot_dmg 10 -set g_turrets_unit_machinegun_std_shot_refire 0.1 -set g_turrets_unit_machinegun_std_shot_spread 0.015 -set g_turrets_unit_machinegun_std_shot_force 20 -set g_turrets_unit_machinegun_std_shot_radius 0 -set g_turrets_unit_machinegun_std_shot_speed 34920 - -set g_turrets_unit_machinegun_std_shot_volly 5 -set g_turrets_unit_machinegun_std_shot_volly_refire 0.5 - -set g_turrets_unit_machinegun_std_target_range 4500 -set g_turrets_unit_machinegun_std_target_range_min 2 -set g_turrets_unit_machinegun_std_target_range_optimal 1000 - -set g_turrets_unit_machinegun_std_target_select_rangebias 0.25 -set g_turrets_unit_machinegun_std_target_select_samebias 0.25 -set g_turrets_unit_machinegun_std_target_select_anglebias 0.5 -set g_turrets_unit_machinegun_std_target_select_playerbias 1 -set g_turrets_unit_machinegun_std_target_select_missilebias 0 - -set g_turrets_unit_machinegun_std_ammo_max 1500 -set g_turrets_unit_machinegun_std_ammo 300 -set g_turrets_unit_machinegun_std_ammo_recharge 75 - -set g_turrets_unit_machinegun_std_aim_firetolerance_dist 25 -set g_turrets_unit_machinegun_std_aim_speed 120 -set g_turrets_unit_machinegun_std_aim_maxrot 360 -set g_turrets_unit_machinegun_std_aim_maxpitch 25 - -set g_turrets_unit_machinegun_std_track_type 3 -set g_turrets_unit_machinegun_std_track_accel_pitch 0.4 -set g_turrets_unit_machinegun_std_track_accel_rot 0.9 -set g_turrets_unit_machinegun_std_track_blendrate 0.2 - - diff --git a/unit_mlrs.cfg b/unit_mlrs.cfg deleted file mode 100644 index c3f3f7859d..0000000000 --- a/unit_mlrs.cfg +++ /dev/null @@ -1,40 +0,0 @@ -set g_turrets_unit_mlrs_std_health 500 -set g_turrets_unit_mlrs_std_respawntime 60 - -set g_turrets_unit_mlrs_std_shot_dmg 50 -set g_turrets_unit_mlrs_std_shot_refire 0.1 -set g_turrets_unit_mlrs_std_shot_radius 125 -set g_turrets_unit_mlrs_std_shot_speed 2000 -set g_turrets_unit_mlrs_std_shot_spread 0.05 -set g_turrets_unit_mlrs_std_shot_force 25 - -set g_turrets_unit_mlrs_std_shot_volly 6 - -// !must be correctly matched with ammo_recharge as this unit use -// volly_always. (means ammo_recharge * ammo_max must be eaqual to volly_refire) -set g_turrets_unit_mlrs_std_shot_volly_refire 4 - -set g_turrets_unit_mlrs_std_target_range 3000 -set g_turrets_unit_mlrs_std_target_range_min 500 -set g_turrets_unit_mlrs_std_target_range_optimal 500 - -set g_turrets_unit_mlrs_std_target_select_rangebias 0.25 -set g_turrets_unit_mlrs_std_target_select_samebias 0.5 -set g_turrets_unit_mlrs_std_target_select_anglebias 0.5 -set g_turrets_unit_mlrs_std_target_select_playerbias 1 -set g_turrets_unit_mlrs_std_target_select_missilebias 0 - -// !must be shot_dmg * 6 as this unit uses ammo to control the animation -set g_turrets_unit_mlrs_std_ammo_max 300 -set g_turrets_unit_mlrs_std_ammo 300 -set g_turrets_unit_mlrs_std_ammo_recharge 75 - -set g_turrets_unit_mlrs_std_aim_firetolerance_dist 120 -set g_turrets_unit_mlrs_std_aim_speed 100 -set g_turrets_unit_mlrs_std_aim_maxrot 360 -set g_turrets_unit_mlrs_std_aim_maxpitch 20 - -set g_turrets_unit_mlrs_std_track_type 3 -set g_turrets_unit_mlrs_std_track_accel_pitch 0.5 -set g_turrets_unit_mlrs_std_track_accel_rot 0.7 -set g_turrets_unit_mlrs_std_track_blendrate 0.2 diff --git a/unit_phaser.cfg b/unit_phaser.cfg deleted file mode 100644 index 31de904894..0000000000 --- a/unit_phaser.cfg +++ /dev/null @@ -1,38 +0,0 @@ -set g_turrets_unit_phaser_std_health 500 - -set g_turrets_unit_phaser_std_respawntime 90 - -set g_turrets_unit_phaser_std_shot_dmg 100 -set g_turrets_unit_phaser_std_shot_refire 4 -set g_turrets_unit_phaser_std_shot_radius 8 -set g_turrets_unit_phaser_std_shot_speed 4 // Used for how long to sustain the beam for this turret (seconds) -set g_turrets_unit_phaser_std_shot_spread 0 -set g_turrets_unit_phaser_std_shot_force 5 -set g_turrets_unit_phaser_std_shot_volly 0 -set g_turrets_unit_phaser_std_shot_volly_refire 5 - -set g_turrets_unit_phaser_std_target_range 3000 -set g_turrets_unit_phaser_std_target_range_min 0 -set g_turrets_unit_phaser_std_target_range_optimal 1500 - -set g_turrets_unit_phaser_std_target_select_rangebias 0.85 -set g_turrets_unit_phaser_std_target_select_samebias 0 -set g_turrets_unit_phaser_std_target_select_anglebias 0.25 -set g_turrets_unit_phaser_std_target_select_playerbias 1 -set g_turrets_unit_phaser_std_target_select_missilebias 0 - -set g_turrets_unit_phaser_std_ammo_max 2000 -set g_turrets_unit_phaser_std_ammo 1000 -set g_turrets_unit_phaser_std_ammo_recharge 25 - -set g_turrets_unit_phaser_std_aim_firetolerance_dist 100 - -set g_turrets_unit_phaser_std_aim_speed 300 -set g_turrets_unit_phaser_std_aim_maxrot 360 -set g_turrets_unit_phaser_std_aim_maxpitch 30 - -set g_turrets_unit_phaser_std_track_type 3 -set g_turrets_unit_phaser_std_track_accel_pitch 0.5 -set g_turrets_unit_phaser_std_track_accel_rot 0.65 -set g_turrets_unit_phaser_std_track_blendrate 0.2 - diff --git a/unit_plasma.cfg b/unit_plasma.cfg deleted file mode 100644 index 949a3e84bd..0000000000 --- a/unit_plasma.cfg +++ /dev/null @@ -1,64 +0,0 @@ -set g_turrets_unit_plasma_std_health 500 -set g_turrets_unit_plasma_std_respawntime 60 - -// Do this mutch damage -set g_turrets_unit_plasma_std_shot_dmg 80 -//This often -set g_turrets_unit_plasma_std_shot_refire 0.6 -//Over this mutch area -set g_turrets_unit_plasma_std_shot_radius 150 -//Traveling at this speed -set g_turrets_unit_plasma_std_shot_speed 2000 -//With a random spread of -set g_turrets_unit_plasma_std_shot_spread 0.015 -//Pushing things this hard -set g_turrets_unit_plasma_std_shot_force 100 -//Each volly is this many shots (0=1) -set g_turrets_unit_plasma_std_shot_volly 0 -// Refire time upon compleated volly -set g_turrets_unit_plasma_std_shot_volly_refire 0 - -// Scan for targets within this range -set g_turrets_unit_plasma_std_target_range 3500 -// But no close then this -set g_turrets_unit_plasma_std_target_range_min 200 -// If we have a choise, prefer the ones closer to this distance -set g_turrets_unit_plasma_std_target_range_optimal 500 - - -// Targetselect is made for each turret based on range, angle (turrets needs to turn to aim at), if its a player / missile -// scale range score this mucth -set g_turrets_unit_plasma_std_target_select_rangebias 0.5 -// scale 'same' score this mutch (stick with same target) -set g_turrets_unit_plasma_std_target_select_samebias 0.01 -// and so on -set g_turrets_unit_plasma_std_target_select_anglebias 0.25 -set g_turrets_unit_plasma_std_target_select_playerbias 1 -set g_turrets_unit_plasma_std_target_select_missilebias 0 - -// Can carry this mutch ammo. one dmg = one ammo -set g_turrets_unit_plasma_std_ammo_max 640 -// Start with this mutch ammo -set g_turrets_unit_plasma_std_ammo 320 -// Regain ammo this fast (per sec) -set g_turrets_unit_plasma_std_ammo_recharge 40 - -// If predicted emeypos is this or closer to predicted impact, fire is ok -set g_turrets_unit_plasma_std_aim_firetolerance_dist 120 -// Aim how fast. for track_type 1 this is dgr/sec, for 2 & 3 its the maximum angle speed added each second -set g_turrets_unit_plasma_std_aim_speed 200 -// Max rottation of head -set g_turrets_unit_plasma_std_aim_maxrot 360 -// Max pitch of head -set g_turrets_unit_plasma_std_aim_maxpitch 30 - -// How the head turns. -// 1 = hard steps, good for aiming preformace, bad for visuals. -// 2 = smooth w/o inertia -// 3 = smmoth with simulated inertia -set g_turrets_unit_plasma_std_track_type 3 -// Following controls how _track_type = 3 works. -set g_turrets_unit_plasma_std_track_accel_pitch 0.5 -set g_turrets_unit_plasma_std_track_accel_rot 0.7 -set g_turrets_unit_plasma_std_track_blendrate 0.2 - diff --git a/unit_plasma2.cfg b/unit_plasma2.cfg deleted file mode 100644 index 723f6441ae..0000000000 --- a/unit_plasma2.cfg +++ /dev/null @@ -1,38 +0,0 @@ -set g_turrets_unit_plasma_dual_health 500 -set g_turrets_unit_plasma_dual_respawntime 60 - -set g_turrets_unit_plasma_dual_shot_dmg 80 -set g_turrets_unit_plasma_dual_shot_refire 0.35 -set g_turrets_unit_plasma_dual_shot_radius 150 -set g_turrets_unit_plasma_dual_shot_speed 2000 -set g_turrets_unit_plasma_dual_shot_spread 0.015 -set g_turrets_unit_plasma_dual_shot_force 100 - -set g_turrets_unit_plasma_dual_shot_volly 0 -set g_turrets_unit_plasma_dual_shot_volly_refire 0 - -set g_turrets_unit_plasma_dual_target_range 3000 -set g_turrets_unit_plasma_dual_target_range_min 80 -set g_turrets_unit_plasma_dual_target_range_optimal 1000 - -set g_turrets_unit_plasma_dual_target_select_rangebias 0.2 -set g_turrets_unit_plasma_dual_target_select_samebias 0.4 -set g_turrets_unit_plasma_dual_target_select_anglebias 0.4 -set g_turrets_unit_plasma_dual_target_select_playerbias 1 -set g_turrets_unit_plasma_dual_target_select_missilebias 0 - -set g_turrets_unit_plasma_dual_ammo_max 640 -set g_turrets_unit_plasma_dual_ammo 320 -set g_turrets_unit_plasma_dual_ammo_recharge 40 - -set g_turrets_unit_plasma_dual_aim_firetolerance_dist 200 - -set g_turrets_unit_plasma_dual_aim_speed 100 -set g_turrets_unit_plasma_dual_aim_maxrot 360 -set g_turrets_unit_plasma_dual_aim_maxpitch 30 - -set g_turrets_unit_plasma_dual_track_type 3 -set g_turrets_unit_plasma_dual_track_accel_pitch 0.5 -set g_turrets_unit_plasma_dual_track_accel_rot 0.7 -set g_turrets_unit_plasma_dual_track_blendrate 0.2 - diff --git a/unit_tesla.cfg b/unit_tesla.cfg deleted file mode 100644 index 3a66b5f968..0000000000 --- a/unit_tesla.cfg +++ /dev/null @@ -1,19 +0,0 @@ -set g_turrets_unit_tesla_std_health 1000 -set g_turrets_unit_tesla_std_respawntime 120 - -set g_turrets_unit_tesla_std_shot_dmg 200 -set g_turrets_unit_tesla_std_shot_refire 1.5 -set g_turrets_unit_tesla_std_shot_force 400 - -set g_turrets_unit_tesla_std_shot_volly 1 -set g_turrets_unit_tesla_std_shot_volly_refire 2.5 - -set g_turrets_unit_tesla_std_target_range_min 0 -set g_turrets_unit_tesla_std_target_range 1000 - -set g_turrets_unit_tesla_std_target_select_playerbias 1 -set g_turrets_unit_tesla_std_target_select_missilebias 1 - -set g_turrets_unit_tesla_std_ammo_max 1000 -set g_turrets_unit_tesla_std_ammo 200 -set g_turrets_unit_tesla_std_ammo_recharge 15 diff --git a/unit_walker.cfg b/unit_walker.cfg deleted file mode 100644 index e08374945e..0000000000 --- a/unit_walker.cfg +++ /dev/null @@ -1,67 +0,0 @@ -set g_turrets_unit_walker_std_health 500 -set g_turrets_unit_walker_std_respawntime 60 - -set g_turrets_unit_walker_speed_run 300 -set g_turrets_unit_walker_speed_roam 100 -set g_turrets_unit_walker_speed_walk 200 -set g_turrets_unit_walker_speed_swim 200 -set g_turrets_unit_walker_speed_jump 800 -set g_turrets_unit_walker_speed_stop 90 - -set g_turrets_unit_walker_turn 20 -set g_turrets_unit_walker_turn_walk 15 -set g_turrets_unit_walker_turn_run 7 -set g_turrets_unit_walker_turn_swim 10 -set g_turrets_unit_walker_turn_strafe 5 - -// Main machineguns prop's -set g_turrets_unit_walker_std_shot_dmg 5 -set g_turrets_unit_walker_std_shot_refire 0.05 -set g_turrets_unit_walker_std_shot_spread 0.025 -set g_turrets_unit_walker_std_shot_force 10 -set g_turrets_unit_walker_std_shot_radius 0 -set g_turrets_unit_walker_std_shot_speed 18000 - -set g_turrets_unit_walker_std_shot_volly 10 -set g_turrets_unit_walker_std_shot_volly_refire 1 - -set g_turrets_unit_walker_std_target_range 5000 -set g_turrets_unit_walker_std_target_range_optimal 100 -set g_turrets_unit_walker_std_target_range_min 0 - -set g_turrets_unit_walker_std_target_select_rangebias 0.25 -set g_turrets_unit_walker_std_target_select_samebias 0.25 -set g_turrets_unit_walker_std_target_select_anglebias 0.5 -set g_turrets_unit_walker_std_target_select_playerbias 1 -set g_turrets_unit_walker_std_target_select_missilebias 0 - -set g_turrets_unit_walker_std_ammo_max 4000 -set g_turrets_unit_walker_std_ammo 500 -set g_turrets_unit_walker_std_ammo_recharge 100 - -set g_turrets_unit_walker_std_aim_firetolerance_dist 100 -set g_turrets_unit_walker_std_aim_speed 45 -set g_turrets_unit_walker_std_aim_maxrot 90 -set g_turrets_unit_walker_std_aim_maxpitch 15 - -// Head (minigun) is attached. must use tractype 1 -set g_turrets_unit_walker_std_track_type 1 - -// "Wobbly" homing rockets that sometimes loop -set g_turrets_unit_walker_std_rockets_range 4000 -set g_turrets_unit_walker_std_rockets_range_min 500 -set g_turrets_unit_walker_std_rocket_refire 10 -set g_turrets_unit_walker_std_rocket_dmg 45 -set g_turrets_unit_walker_std_rocket_radius 150 -set g_turrets_unit_walker_std_rocket_force 150 -set g_turrets_unit_walker_std_rocket_turnrate 0.05 -set g_turrets_unit_walker_std_rocket_speed 1000 - -// Meele attack. Only happens when theres a target directly in front -set g_turrets_unit_walker_std_meele_range 100 -set g_turrets_unit_walker_std_meele_dmg 100 -set g_turrets_unit_walker_std_meele_force 600 - -set g_turrets_unit_walker_std_track_accel_pitch 0.5 -set g_turrets_unit_walker_std_track_accel_rot 0.8 -set g_turrets_unit_walker_std_track_blendrate 0.2