X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Ftturrets%2Fsystem%2Fsystem_main.qc;h=eb9c05dfe09e4833df259adc572219b4c8c0f10b;hb=3306ec6d79f926dcb2e888adbc68f119770facb5;hp=1b2fcd7723b8089c7fb5102dbb44f424eb4c7e66;hpb=116d76158f4f21b2fb10734e7a03cd7f2bd01838;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/tturrets/system/system_main.qc b/qcsrc/server/tturrets/system/system_main.qc index 1b2fcd772..eb9c05dfe 100644 --- a/qcsrc/server/tturrets/system/system_main.qc +++ b/qcsrc/server/tturrets/system/system_main.qc @@ -1,23 +1,63 @@ #define cvar_base "g_turrets_unit_" -/* -float turret_customizeentityforclient() +float turret_send(entity to, float sf) { -} - -float Turret_SendEntity(entity to, float sf) -{ - + float dist; + dist = vlen(self.origin - to.origin); + if(dist > 1024) // When far away, write angles/avelocity as short insted of angle. + sf |= TNSF_FAR; + WriteByte(MSG_ENTITY, ENT_CLIENT_TURRET); - WriteCoord(MSG_ENTITY, self.tur_head.angles_x); - WriteCoord(MSG_ENTITY, self.tur_head.angles_y); - WriteByte(MSG_ENTITY, self.tur_head.frame); - - //WriteCoord(MSG_ENTITY, self.tur_head.angles_z); - + + 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) + { + if(sf & TNSF_FAR) + { + WriteShort(MSG_ENTITY, rint(self.tur_head.angles_x)); + WriteShort(MSG_ENTITY, rint(self.tur_head.angles_y)); + } + else + { + WriteAngle(MSG_ENTITY, self.tur_head.angles_x); + WriteAngle(MSG_ENTITY, self.tur_head.angles_y); + } + } + + if(sf & TNSF_AVEL) + { + if(sf & TNSF_FAR) + { + WriteShort(MSG_ENTITY, rint(self.tur_head.avelocity_x)); + WriteShort(MSG_ENTITY, rint(self.tur_head.avelocity_y)); + } + else + { + WriteAngle(MSG_ENTITY, self.tur_head.avelocity_x); + WriteAngle(MSG_ENTITY, self.tur_head.avelocity_y); + } + } + + if(sf & TNSF_STATUS) + { + WriteByte(MSG_ENTITY, self.team); + WriteByte(MSG_ENTITY, rint((self.health / self.tur_health) * 255)); // Send health as 0-255 insted of real value, where 255 = 100% + } + return TRUE; } -*/ void load_unit_settings(entity ent, string unitname, float is_reload) { @@ -116,8 +156,6 @@ void turret_do_updates(entity t_turret) 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); @@ -199,12 +237,16 @@ vector turret_fovsearch_random() ** 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; @@ -252,7 +294,11 @@ void turret_stdproc_track() if(self.tur_head.angles_y < -self.aim_maxrot) self.tur_head.angles_y = self.aim_maxrot; } - + + // CSQC + if(self.SendEntity) + self.SendFlags = TNSF_ANG; + return; case TFL_TRACKTYPE_FLUIDINERTIA: @@ -278,12 +324,18 @@ void turret_stdproc_track() { self.tur_head.avelocity_x = 0; self.tur_head.angles_x = self.aim_maxpitch; + + if(self.SendEntity) + 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; + + if(self.SendEntity) + self.SendFlags |= TNSF_ANG; } } @@ -296,14 +348,33 @@ void turret_stdproc_track() { self.tur_head.avelocity_y = 0; self.tur_head.angles_y = self.aim_maxrot; + + if(self.SendEntity) + 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; + + if(self.SendEntity) + self.SendFlags |= TNSF_ANG; } } + + if(self.SendEntity) + { + self.SendFlags |= TNSF_AVEL; + + // Push a angle update every 10'th frame + self.turret_framecounter += 1; + if(self.turret_framecounter >= 10) + { + self.SendFlags |= TNSF_ANG; + self.turret_framecounter = 0; + } + } } @@ -340,8 +411,9 @@ float turret_stdproc_firecheck() // 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 not (self.volly_counter == self.shot_volly) - return 1; + 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) @@ -606,9 +678,10 @@ void turret_think() entity e; self.nextthink = time + self.ticrate; - + //self.SendFlags = TNSF_UPDATE | TNSF_STATUS | TNSF_ANG | TNSF_AVEL; + // ONS uses somewhat backwards linking. - if (teamplay) + if (teams_matter) { if not (g_onslaught) if (self.target) @@ -635,7 +708,7 @@ void turret_think() if not (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 not (self.tur_active) @@ -717,7 +790,7 @@ void turret_think() // g_turrets_targetscan_maxdelay forces a target re-scan at least this often float do_target_scan; - if((self.target_select_time + cvar("g_turrets_targetscan_maxdelay")) < time) + if((self.target_select_time + autocvar_g_turrets_targetscan_maxdelay) < time) do_target_scan = 1; // Old target (if any) invalid? @@ -728,7 +801,7 @@ void turret_think() } // But never more often then g_turrets_targetscan_mindelay! - if (self.target_select_time + cvar("g_turrets_targetscan_mindelay") > time) + if (self.target_select_time + autocvar_g_turrets_targetscan_mindelay > time) do_target_scan = 0; if(do_target_scan) @@ -752,7 +825,7 @@ void turret_think() return; } else - self.lip = time + cvar("g_turrets_aimidle_delay"); // Keep track of the last time we had a target. + self.lip = time + autocvar_g_turrets_aimidle_delay; // Keep track of the last time we had a target. // Predict? if not(self.aim_flags & TFL_AIM_NO) @@ -776,7 +849,7 @@ void turret_think() void turret_fire() { - if (cvar("g_turrets_nofire") != 0) + if (autocvar_g_turrets_nofire != 0) return; self.turret_firefunc(); @@ -825,7 +898,7 @@ void turret_stdproc_use() void turret_link() { - //Net_LinkEntity(self, FALSE, 0, Turret_SendEntity); + Net_LinkEntity(self, TRUE, 0, turret_send); self.think = turret_think; self.nextthink = time; } @@ -835,7 +908,7 @@ void turrets_manager_think() self.nextthink = time + 1; entity e; - if (cvar("g_turrets_reloadcvars") == 1) + if (autocvar_g_turrets_reloadcvars == 1) { e = nextent(world); while (e) @@ -858,20 +931,27 @@ void turrets_manager_think() * (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, float csqc_shared, string base, string head) +float turret_stdproc_init (string cvar_base_name, float csqc_shared, string base, string head, float _turret_type) { entity e, ee; // Are turrets allowed? - if (cvar("g_turrets") == 0) + 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 not (e) { e = spawn(); + /* setorigin(e,'0 0 0'); setmodel(e,"models/turrets/plasma.md3"); vector v; @@ -882,23 +962,29 @@ float turret_stdproc_init (string cvar_base_name, float csqc_shared, string base //crash(); } setmodel(e,""); + */ e.classname = "turret_manager"; e.think = turrets_manager_think; e.nextthink = time + 2; } - +#ifndef TTURRETS_CSQC + csqc_shared = 0; +#endif + /* if(csqc_shared) { dprint("WARNING: turret requested csqc_shared but this is not implemented. Expect strange things to happen.\n"); csqc_shared = 0; } - + */ + if not (self.spawnflags & TSF_SUSPENDED) droptofloor_builtin(); // Terrainbase spawnflag. This puts a enlongated model // under the turret, so it looks ok on uneaven surfaces. + /* TODO: Handle this with CSQC if (self.spawnflags & TSF_TERRAINBASE) { entity tb; @@ -907,17 +993,18 @@ float turret_stdproc_init (string cvar_base_name, float csqc_shared, string base setorigin(tb,self.origin); tb.solid = SOLID_BBOX; } + */ self.cvar_basename = cvar_base_name; - load_unit_settings(self,self.cvar_basename, 0); + load_unit_settings(self, self.cvar_basename, 0); // Handle turret teams. - if (cvar("g_assault") != 0) + if (autocvar_g_assault != 0) { if not (self.team) self.team = 14; // Assume turrets are on the defending side if not explicitly set otehrwize } - else if not (teamplay) + else if not (teams_matter) self.team = MAX_SHOT_DISTANCE; // Group all turrets into the same team, so they dont kill eachother. else if(g_onslaught && self.targetname) { @@ -1128,6 +1215,10 @@ float turret_stdproc_init (string cvar_base_name, float csqc_shared, string base // Offsets & origins if (!self.tur_shotorg) self.tur_shotorg = '50 0 50'; +// Gane hooks + if(MUTATOR_CALLHOOK(TurretSpawn)) + return 0; + // End of default & sanety checks, start building the turret. // Spawn extra bits @@ -1197,12 +1288,6 @@ float turret_stdproc_init (string cvar_base_name, float csqc_shared, string base self.use = turret_stdproc_use; self.bot_attack = TRUE; - // Initiate the main AI loop - if(csqc_shared) - self.think = turret_link; - else - self.think = turret_think; - ++turret_count; self.nextthink = time + 1; self.nextthink += turret_count * sys_frametime; @@ -1233,7 +1318,17 @@ float turret_stdproc_init (string cvar_base_name, float csqc_shared, string base activator = ee; self.use(); } - + + Net_LinkEntity(self, TRUE, 0, turret_send); + turret_stdproc_respawn(); + + // Initiate the main AI loop + /*self.nextthink = time; + if(csqc_shared) + self.think = turret_link; + else + self.think = turret_think; + */ return 1; }