X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Ftturrets%2Fsystem%2Fsystem_main.qc;h=fb79f5442fffd036ba08b56425209ffc9f57e6e8;hb=9f4c9acd38081d1bbfa6eec9d22044143abea28f;hp=1b2fcd7723b8089c7fb5102dbb44f424eb4c7e66;hpb=d2509861580bce6e6f1ffc9e9a26aea2d70b6756;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..fb79f5442 100644 --- a/qcsrc/server/tturrets/system/system_main.qc +++ b/qcsrc/server/tturrets/system/system_main.qc @@ -1,23 +1,42 @@ #define cvar_base "g_turrets_unit_" -/* -float turret_customizeentityforclient() -{ -} - -float Turret_SendEntity(entity to, float sf) +float turret_send(entity to, float sf) { - - 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); - + dprint("Sending update\n"); + 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_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 +135,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 +216,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 +273,10 @@ void turret_stdproc_track() 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: @@ -278,12 +302,16 @@ void turret_stdproc_track() { 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; } } @@ -296,14 +324,28 @@ void turret_stdproc_track() { 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; + } } @@ -340,8 +382,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,7 +649,8 @@ 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) { @@ -635,7 +679,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 +761,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 +772,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 +796,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 +820,7 @@ void turret_think() void turret_fire() { - if (cvar("g_turrets_nofire") != 0) + if (autocvar_g_turrets_nofire != 0) return; self.turret_firefunc(); @@ -825,9 +869,10 @@ 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; + self.tur_head.effects = EF_NODRAW; } void turrets_manager_think() @@ -835,7 +880,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 +903,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, 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 +934,27 @@ 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; } + /* 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,12 +963,13 @@ 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 @@ -1100,7 +1157,6 @@ float turret_stdproc_init (string cvar_base_name, float csqc_shared, string base self.target_validate_flags = self.target_select_flags; - // Ammo stuff if not (self.ammo_max) self.ammo_max = self.shot_dmg * 10; @@ -1127,6 +1183,13 @@ 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'; + + if (!self.health) + self.health = 150; + +// Game hooks + if(MUTATOR_CALLHOOK(TurretSpawn)) + return 0; // End of default & sanety checks, start building the turret. @@ -1145,9 +1208,6 @@ float turret_stdproc_init (string cvar_base_name, float csqc_shared, string base setorigin(self.tur_head, '0 0 0'); setattachment(self.tur_head, self, "tag_head"); - if (!self.health) - self.health = 150; - self.tur_health = self.health; self.solid = SOLID_BBOX; self.tur_head.solid = SOLID_NOT; @@ -1174,35 +1234,19 @@ float turret_stdproc_init (string cvar_base_name, float csqc_shared, string base else self.idle_aim = '0 0 0'; - // Team color - if (self.team == COLOR_TEAM1) self.colormod = '1.4 0.8 0.8'; - if (self.team == COLOR_TEAM2) self.colormod = '0.8 0.8 1.4'; - // 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; - self.turret_firecheckfunc = turret_stdproc_firecheck; - self.turret_firefunc = turret_stdproc_fire; - self.event_damage = turret_stdproc_damage; - } else - { self.turret_score_target = turret_stdproc_targetscore_generic; - self.turret_firecheckfunc = turret_stdproc_firecheck; - self.turret_firefunc = turret_stdproc_fire; - self.event_damage = turret_stdproc_damage; - } 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 +1277,12 @@ float turret_stdproc_init (string cvar_base_name, float csqc_shared, string base activator = ee; self.use(); } - + + turret_stdproc_respawn(); + + if (!turret_tag_fire_update()) + dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n"); + return 1; }