// --------------------------------------------------------------------------
// BEGIN OPTIONAL CSQC FUNCTIONS
-void trigger_touch_generic(void() touchfunc)
-{
- entity e;
- for(e = findradius((self.absmin + self.absmax) * 0.5, vlen(self.absmax - self.absmin) * 0.5 + 1); e; e = e.chain)
- if(e.isplayermodel)
- {
- vector emin = e.absmin, emax = e.absmax;
- if(self.solid == SOLID_BSP)
- {
- emin -= '1 1 1';
- emax += '1 1 1';
- }
- if(boxesoverlap(emin, emax, self.absmin, self.absmax)) // quick
- if(WarpZoneLib_BoxTouchesBrush(emin, emax, self, e)) // accurate
- {
- other = e;
- touchfunc();
- }
- }
-}
-void trigger_draw_generic()
-{
- float dt = time - self.move_time;
- self.move_time = time;
- if(dt <= 0) { return; }
-
- if(self.trigger_touch) { trigger_touch_generic(self.trigger_touch); }
-}
void Ent_RemoveEntCS()
{
void Ent_RadarLink();
void Ent_Init();
void Ent_ScoresInfo();
-void ent_func_ladder();
-void ent_trigger_push();
-void ent_target_push();
-void ent_conveyor();
void CSQC_Ent_Update(float bIsNewEntity)
{
float t;
case ENT_CLIENT_CONVEYOR: ent_conveyor(); break;
case ENT_CLIENT_DOOR: ent_door(); break;
case ENT_CLIENT_DOOR_TRIGGER: ent_door_trigger(); break;
+ case ENT_CLIENT_PLAT: ent_plat(); break;
+ case ENT_CLIENT_PLAT_TRIGGER: ent_plat_trigger(); break;
default:
//error(strcat(_("unknown entity type in CSQC_Ent_Update: %d\n"), self.enttype));
pointparticles(self.team, org, '0 0 0', 1);
}
-void DamageEffect(vector hitorg, float dmg, float type, float specnum)
+void DamageEffect(vector hitorg, float thedamage, float type, float specnum)
{
// particle effects for players and objects damaged by weapons (eg: flames coming out of victims shot with rockets)
return; // allow a single damage on non-skeletal models
}
- life = bound(autocvar_cl_damageeffect_lifetime_min, dmg * autocvar_cl_damageeffect_lifetime, autocvar_cl_damageeffect_lifetime_max);
+ life = bound(autocvar_cl_damageeffect_lifetime_min, thedamage * autocvar_cl_damageeffect_lifetime, autocvar_cl_damageeffect_lifetime_max);
effectname = get_weaponinfo(DEATH_WEAPONOF(type)).netname;
void Ent_DamageInfo(float isNew)
{
- float dmg, rad, edge, thisdmg, forcemul, species, hitplayer = FALSE;
+ float thedamage, rad, edge, thisdmg, forcemul, species, hitplayer = FALSE;
vector force, thisforce;
entity oldself;
w_org_y = ReadCoord();
w_org_z = ReadCoord();
- dmg = ReadByte();
+ thedamage = ReadByte();
rad = ReadByte();
edge = ReadByte();
force = decompressShortVector(ReadShort());
continue;
if(thisdmg < 0)
thisdmg = 0;
- if(dmg)
+ if(thedamage)
{
- thisdmg = dmg + (edge - dmg) * thisdmg;
- thisforce = forcemul * vlen(force) * (thisdmg / dmg) * normalize(self.origin - w_org);
+ thisdmg = thedamage + (edge - thedamage) * thisdmg;
+ thisforce = forcemul * vlen(force) * (thisdmg / thedamage) * normalize(self.origin - w_org);
}
else
{
if(vlen(nearest - w_org) > bound(MIN_DAMAGEEXTRARADIUS, self.damageextraradius, MAX_DAMAGEEXTRARADIUS))
continue;
- thisdmg = dmg;
+ thisdmg = thedamage;
thisforce = forcemul * force;
}
R_EndPolygon();
}
-void drawhealthbar(vector org, float rot, float h, vector sz, vector hotspot, float width, float height, float margin, float border, float align, vector rgb, float a, vector hrgb, float ha, float f)
+void drawhealthbar(vector org, float rot, float h, vector sz, vector hotspot, float width, float theheight, float margin, float border, float align, vector rgb, float a, vector hrgb, float ha, float f)
{
vector o, ri, up;
float owidth; // outer width
up = rotate(up, rot);
owidth = width + 2 * border;
- o = o - up * (margin + border + height) + ri * (sz_x - owidth) * 0.5;
+ o = o - up * (margin + border + theheight) + ri * (sz_x - owidth) * 0.5;
drawquad(o - up * border, ri * owidth, up * border, "", rgb, a, f);
- drawquad(o + up * height, ri * owidth, up * border, "", rgb, a, f);
- drawquad(o, ri * border, up * height, "", rgb, a, f);
- drawquad(o + ri * (owidth - border), ri * border, up * height, "", rgb, a, f);
- drawquad(o + ri * (border + align * ((1 - h) * width)), ri * width * h, up * height, "", hrgb, ha, f);
+ drawquad(o + up * theheight, ri * owidth, up * border, "", rgb, a, f);
+ drawquad(o, ri * border, up * theheight, "", rgb, a, f);
+ drawquad(o + ri * (owidth - border), ri * border, up * theheight, "", rgb, a, f);
+ drawquad(o + ri * (border + align * ((1 - h) * width)), ri * width * h, up * theheight, "", hrgb, ha, f);
}
// returns location of sprite text
const float ENT_CLIENT_CONVEYOR = 64;
const float ENT_CLIENT_DOOR = 65;
const float ENT_CLIENT_DOOR_TRIGGER = 66;
+const float ENT_CLIENT_PLAT = 67;
+const float ENT_CLIENT_PLAT_TRIGGER = 68;
const float ENT_CLIENT_HEALING_ORB = 80;
--- /dev/null
+#ifdef CSQC
+void ent_conveyor();
+#endif
+#include "conveyor.qh"
#include "door.qh"
#include "ladder.qh"
+#include "plat.qh"
#elif defined(CSQC)
.float speed;
-void func_ladder_draw()
-{
- float dt = time - self.move_time;
- self.move_time = time;
- if(dt <= 0) { return; }
-
- trigger_touch_generic(func_ladder_touch);
-}
-
void ent_func_ladder()
{
self.classname = strzone(ReadString());
self.angles_z = ReadCoord();
self.solid = SOLID_TRIGGER;
- self.draw = func_ladder_draw;
+ self.draw = trigger_draw_generic;
+ self.trigger_touch = func_ladder_touch;
self.drawmask = MASK_NORMAL;
self.move_time = time;
}
.float ladder_time;
.entity ladder_entity;
+
+#ifdef CSQC
+void ent_func_ladder();
+#endif
#ifdef SVQC
+void plat_delayedinit()
+{
+ plat_spawn_inside_trigger (); // the "start moving" trigger
+}
+
+float plat_send(entity to, float sf)
+{
+ WriteByte(MSG_ENTITY, ENT_CLIENT_PLAT);
+ WriteByte(MSG_ENTITY, sf);
+
+ if(sf & SF_TRIGGER_INIT)
+ {
+ WriteShort(MSG_ENTITY, num_for_edict(self));
+ WriteString(MSG_ENTITY, self.target);
+ WriteString(MSG_ENTITY, self.target2);
+ WriteString(MSG_ENTITY, self.target3);
+ WriteString(MSG_ENTITY, self.target4);
+ WriteString(MSG_ENTITY, self.targetname);
+
+ WriteByte(MSG_ENTITY, self.platmovetype_start);
+ WriteByte(MSG_ENTITY, self.platmovetype_turn);
+ WriteByte(MSG_ENTITY, self.platmovetype_end);
+
+ WriteCoord(MSG_ENTITY, self.origin_x);
+ WriteCoord(MSG_ENTITY, self.origin_y);
+ WriteCoord(MSG_ENTITY, self.origin_z);
+
+ WriteString(MSG_ENTITY, self.model);
+
+ WriteCoord(MSG_ENTITY, self.mins_x);
+ WriteCoord(MSG_ENTITY, self.mins_y);
+ WriteCoord(MSG_ENTITY, self.mins_z);
+ WriteCoord(MSG_ENTITY, self.maxs_x);
+ WriteCoord(MSG_ENTITY, self.maxs_y);
+ WriteCoord(MSG_ENTITY, self.maxs_z);
+
+ WriteCoord(MSG_ENTITY, self.pos1_x);
+ WriteCoord(MSG_ENTITY, self.pos1_y);
+ WriteCoord(MSG_ENTITY, self.pos1_z);
+ WriteCoord(MSG_ENTITY, self.pos2_x);
+ WriteCoord(MSG_ENTITY, self.pos2_y);
+ WriteCoord(MSG_ENTITY, self.pos2_z);
+
+ WriteCoord(MSG_ENTITY, self.size_x);
+ WriteCoord(MSG_ENTITY, self.size_y);
+ WriteCoord(MSG_ENTITY, self.size_z);
+
+ WriteAngle(MSG_ENTITY, self.angles_x);
+ WriteAngle(MSG_ENTITY, self.angles_y);
+ WriteAngle(MSG_ENTITY, self.angles_z);
+
+ WriteAngle(MSG_ENTITY, self.mangle_x);
+ WriteAngle(MSG_ENTITY, self.mangle_y);
+ WriteAngle(MSG_ENTITY, self.mangle_z);
+
+ WriteShort(MSG_ENTITY, self.speed);
+ WriteShort(MSG_ENTITY, self.height);
+ WriteByte(MSG_ENTITY, self.lip);
+ WriteByte(MSG_ENTITY, self.state);
+
+ WriteShort(MSG_ENTITY, self.dmg);
+ }
+
+ if(sf & SF_TRIGGER_RESET)
+ {
+ // used on client
+ }
+
+ return TRUE;
+}
+
+void plat_link()
+{
+ Net_LinkEntity(self, 0, FALSE, plat_send);
+}
+
void spawnfunc_func_plat()
{
if (self.sounds == 0)
self.reset = plat_reset;
plat_reset();
- plat_spawn_inside_trigger (); // the "start moving" trigger
+ plat_link();
+
+ InitializeEntity(self, plat_delayedinit, INITPRIO_FINDTARGET);
+}
+#elif defined(CSQC)
+void plat_draw()
+{
+
+}
+
+void ent_plat()
+{
+ float sf = ReadByte();
+
+ if(sf & SF_TRIGGER_INIT)
+ {
+ self.sv_entnum = ReadShort();
+ self.target = strzone(ReadString());
+ self.target2 = strzone(ReadString());
+ self.target3 = strzone(ReadString());
+ self.target4 = strzone(ReadString());
+ self.targetname = strzone(ReadString());
+
+ self.platmovetype_start = ReadByte();
+ self.platmovetype_turn = ReadByte();
+ self.platmovetype_end = ReadByte();
+
+ self.origin_x = ReadCoord();
+ self.origin_y = ReadCoord();
+ self.origin_z = ReadCoord();
+ setorigin(self, self.origin);
+
+ self.model = strzone(ReadString());
+ setmodel(self, self.model);
+
+ self.mins_x = ReadCoord();
+ self.mins_y = ReadCoord();
+ self.mins_z = ReadCoord();
+ self.maxs_x = ReadCoord();
+ self.maxs_y = ReadCoord();
+ self.maxs_z = ReadCoord();
+ setsize(self, self.mins, self.maxs);
+
+ self.pos1_x = ReadCoord();
+ self.pos1_y = ReadCoord();
+ self.pos1_z = ReadCoord();
+ self.pos2_x = ReadCoord();
+ self.pos2_y = ReadCoord();
+ self.pos2_z = ReadCoord();
+
+ self.size_x = ReadCoord();
+ self.size_y = ReadCoord();
+ self.size_z = ReadCoord();
+
+ self.angles_x = ReadAngle();
+ self.angles_y = ReadAngle();
+ self.angles_z = ReadAngle();
+
+ self.mangle_x = ReadAngle();
+ self.mangle_y = ReadAngle();
+ self.mangle_z = ReadAngle();
+
+ self.speed = ReadShort();
+ self.height = ReadShort();
+ self.lip = ReadByte();
+ self.state = ReadByte();
+
+ self.dmg = ReadShort();
+
+ self.solid = SOLID_BSP;
+ self.movetype = MOVETYPE_PUSH;
+ self.drawmask = MASK_NORMAL;
+ self.draw = plat_draw;
+ self.use = plat_use;
+
+ plat_reset(); // also called here
+ }
+
+ if(sf & SF_TRIGGER_RESET)
+ {
+ plat_reset();
+ }
}
#endif
--- /dev/null
+#ifdef CSQC
+void ent_plat();
+#endif
-#ifdef SVQC
void generic_plat_blocked()
{
- if(self.dmg && other.takedamage != DAMAGE_NO) {
- if(self.dmgtime2 < time) {
- Damage (other, self, self, self.dmg, DEATH_HURTTRIGGER, other.origin, '0 0 0');
- self.dmgtime2 = time + self.dmgtime;
- }
-
- // Gib dead/dying stuff
- if(other.deadflag != DEAD_NO)
- Damage (other, self, self, 10000, DEATH_HURTTRIGGER, other.origin, '0 0 0');
- }
+#ifdef SVQC
+ if(self.dmg && other.takedamage != DAMAGE_NO)
+ {
+ if(self.dmgtime2 < time)
+ {
+ Damage (other, self, self, self.dmg, DEATH_HURTTRIGGER, other.origin, '0 0 0');
+ self.dmgtime2 = time + self.dmgtime;
+ }
+
+ // Gib dead/dying stuff
+ if(other.deadflag != DEAD_NO)
+ Damage (other, self, self, 10000, DEATH_HURTTRIGGER, other.origin, '0 0 0');
+ }
+#endif
+}
+
+#ifdef SVQC
+float plat_trigger_send(entity to, float sf)
+{
+ WriteByte(MSG_ENTITY, ENT_CLIENT_PLAT_TRIGGER);
+ WriteShort(MSG_ENTITY, num_for_edict(self.enemy));
+
+ WriteCoord(MSG_ENTITY, self.origin_x);
+ WriteCoord(MSG_ENTITY, self.origin_y);
+ WriteCoord(MSG_ENTITY, self.origin_z);
+
+ WriteCoord(MSG_ENTITY, self.mins_x);
+ WriteCoord(MSG_ENTITY, self.mins_y);
+ WriteCoord(MSG_ENTITY, self.mins_z);
+ WriteCoord(MSG_ENTITY, self.maxs_x);
+ WriteCoord(MSG_ENTITY, self.maxs_y);
+ WriteCoord(MSG_ENTITY, self.maxs_z);
+ return TRUE;
}
void plat_spawn_inside_trigger()
if(tmin_z < tmax_z)
{
setsize (trigger, tmin, tmax);
+ Net_LinkEntity(trigger, FALSE, 0, plat_trigger_send);
return;
}
remove(trigger);
objerror("plat_spawn_inside_trigger: platform has odd size or lip, can't spawn");
}
+#elif defined(CSQC)
+void ent_plat_trigger()
+{
+ float myenemy = ReadShort();
+ self.origin_x = ReadCoord();
+ self.origin_y = ReadCoord();
+ self.origin_z = ReadCoord();
+ setorigin(self, self.origin);
+
+ self.mins_x = ReadCoord();
+ self.mins_y = ReadCoord();
+ self.mins_z = ReadCoord();
+ self.maxs_x = ReadCoord();
+ self.maxs_y = ReadCoord();
+ self.maxs_z = ReadCoord();
+ setsize(self, self.mins, self.maxs);
+
+ self.enemy = findfloat(world, sv_entnum, myenemy);
+ if(!self.enemy) { print("^1BAD BAD BAD!!!\n"); }
+ self.drawmask = MASK_NORMAL;
+ self.draw = trigger_draw_generic;
+ self.trigger_touch = plat_center_touch;
+ self.solid = SOLID_TRIGGER;
+}
+#endif
void plat_hit_top()
{
void plat_center_touch()
{
+#ifdef SVQC
if (!other.iscreature)
return;
if (other.health <= 0)
return;
+#elif defined(CSQC)
+ if (!IS_PLAYER(other))
+ return;
+#endif
+
+#ifdef CSQC
+ print("Got this far\n");
+#endif
self = self.enemy;
if (self.state == 2)
void plat_outside_touch()
{
+#ifdef SVQC
if (!other.iscreature)
return;
if (other.health <= 0)
return;
+#elif defined(CSQC)
+ if (!IS_PLAYER(other))
+ return;
+#endif
self = self.enemy;
if (self.state == 1)
void plat_crush()
{
- if((self.spawnflags & 4) && (other.takedamage != DAMAGE_NO)) { // KIll Kill Kill!!
- Damage (other, self, self, 10000, DEATH_HURTTRIGGER, other.origin, '0 0 0');
- } else {
- if((self.dmg) && (other.takedamage != DAMAGE_NO)) { // Shall we bite?
- Damage (other, self, self, self.dmg, DEATH_HURTTRIGGER, other.origin, '0 0 0');
- // Gib dead/dying stuff
- if(other.deadflag != DEAD_NO)
- Damage (other, self, self, 10000, DEATH_HURTTRIGGER, other.origin, '0 0 0');
- }
-
- if (self.state == 4)
- plat_go_down ();
- else if (self.state == 3)
- plat_go_up ();
+ if((self.spawnflags & 4) && (other.takedamage != DAMAGE_NO))
+ { // KIll Kill Kill!!
+#ifdef SVQC
+ Damage (other, self, self, 10000, DEATH_HURTTRIGGER, other.origin, '0 0 0');
+#endif
+ }
+ else
+ {
+#ifdef SVQC
+ if((self.dmg) && (other.takedamage != DAMAGE_NO))
+ { // Shall we bite?
+ Damage (other, self, self, self.dmg, DEATH_HURTTRIGGER, other.origin, '0 0 0');
+ // Gib dead/dying stuff
+ if(other.deadflag != DEAD_NO)
+ Damage (other, self, self, 10000, DEATH_HURTTRIGGER, other.origin, '0 0 0');
+ }
+#endif
+
+ if (self.state == 4)
+ plat_go_down ();
+ else if (self.state == 3)
+ plat_go_up ();
// when in other states, then the plat_crush event came delayed after
// plat state already had changed
// this isn't a bug per se!
- }
+ }
}
void plat_use()
self.state = 2;
self.use = plat_trigger_use;
}
+
+#ifdef SVQC
+ self.SendFlags |= SF_TRIGGER_RESET;
+#endif
}
+#ifdef SVQC
.float platmovetype_start_default, platmovetype_end_default;
float set_platmovetype(entity e, string s)
{
.float dmgtime2;
-#ifdef SVQC
void() plat_center_touch;
void() plat_outside_touch;
void() plat_trigger_use;
void() plat_go_up;
void() plat_go_down;
void() plat_crush;
-#endif
const float PLAT_LOW_TRIGGER = 1;
+
+.float dmg;
+
+#ifdef CSQC
+void ent_plat_trigger();
+#endif
vector nextpos;
delta = self.destvec;
delta2 = self.destvec2;
- if(time < self.animstate_endtime) {
+ if(time < self.animstate_endtime)
+ {
nexttick = time + PHYS_INPUT_FRAMETIME;
traveltime = self.animstate_endtime - self.animstate_starttime;
self.owner.velocity = veloc;
self.nextthink = nexttick;
- } else {
+ }
+ else
+ {
// derivative: delta + 2 * delta2 (e.g. for angle positioning)
oldself = self;
self.owner.think = self.think1;
#include "multi.qh"
+#include "jumppads.qh"
// TODO: split target_push and put it in the target folder
-.float height;
-
#ifdef SVQC
const float PUSH_ONCE = 1;
--- /dev/null
+#ifdef CSQC
+void ent_trigger_push();
+void ent_target_push();
+#endif
self = stemp;
other = otemp;
}
+
+#ifdef CSQC
+void trigger_touch_generic(void() touchfunc)
+{
+ entity e;
+ for(e = findradius((self.absmin + self.absmax) * 0.5, vlen(self.absmax - self.absmin) * 0.5 + 1); e; e = e.chain)
+ if(e.isplayermodel)
+ {
+ vector emin = e.absmin, emax = e.absmax;
+ if(self.solid == SOLID_BSP)
+ {
+ emin -= '1 1 1';
+ emax += '1 1 1';
+ }
+ if(boxesoverlap(emin, emax, self.absmin, self.absmax)) // quick
+ if(WarpZoneLib_BoxTouchesBrush(emin, emax, self, e)) // accurate
+ {
+ other = e;
+ touchfunc();
+ }
+ }
+}
+void trigger_draw_generic()
+{
+ float dt = time - self.move_time;
+ self.move_time = time;
+ if(dt <= 0) { return; }
+
+ if(self.trigger_touch) { trigger_touch_generic(self.trigger_touch); }
+}
+#endif
.void() trigger_touch;
+.float height;
+
+.float nottargeted;
+#define IFTARGETED if(!self.nottargeted && self.targetname != "")
+
.string bgmscript;
.float bgmscriptattack;
.float bgmscriptdecay;
e.uncustomizeentityforclient_set = !!uncustomizer;
}
-.float nottargeted;
-#define IFTARGETED if(!self.nottargeted && self.targetname != "")
-
void Net_LinkEntity(entity e, float docull, float dt, float(entity, float) sendfunc)
{
vector mi, ma;