#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);
-
+
+ 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)
{
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);
** 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.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:
{
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;
}
}
{
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;
+ }
+ }
}
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 not (self.spawnflags & TSF_NO_AMMO_REGEN)
if (self.ammo < self.ammo_max)
self.ammo = min(self.ammo + self.ammo_recharge, self.ammo_max);
-
- if (self.health < (self.tur_health * 0.5))
- if(random() < 0.25)
- te_spark(self.origin + '0 0 40', randomvec() * 256 + '0 0 256', 16);
// Inactive turrets needs to run the think loop,
// So they can handle animation and wake up if need be.
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()
* (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 (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.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;
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 (autocvar_g_assault != 0)
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;
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;
}