case ENT_CLIENT_CONVEYOR: ent_conveyor(); break;
case ENT_CLIENT_DOOR: ent_door(); break;
case ENT_CLIENT_PLAT: ent_plat(); break;
- case ENT_CLIENT_PLAT_TRIGGER: ent_plat_trigger(); break;
case ENT_CLIENT_SWAMP: ent_swamp(); break;
case ENT_CLIENT_CORNER: ent_corner(); break;
case ENT_CLIENT_KEYLOCK: ent_keylock(); break;
+ case ENT_CLIENT_TRAIN: ent_train(); break;
default:
//error(strcat(_("unknown entity type in CSQC_Ent_Update: %d\n"), self.enttype));
{
float angle, sr, sp, sy, cr, cp, cy;
+ v_forward = v_right = v_up = '0 0 0';
+
angle = myangles_y * (M_PI*2 / 360);
sy = sin(angle);
cy = cos(angle);
void _Movetype_PushMove(float dt) // SV_PushMove
{
- float pushltime;
- //int pusherowner;
- //int i;
- //int num_moved;
- //int numcheckentities;
- int savesolid;
bool rotated;
- vector move1, moveangle;
+ int savesolid;
+ float movetime2, pushltime;
+ vector move, move1, moveangle, pushorig, pushang;
vector a;
- vector pushorig, pushang;
- vector org;
- vector move;
+ vector pivot;
entity oldself;
+ entity check;
- if(!vlen(self.move_velocity) && !vlen(self.move_avelocity))
+ if(self.move_velocity == '0 0 0' && self.move_avelocity == '0 0 0')
{
- self.ltime += dt;
+ self.move_ltime += dt;
return;
}
// LordHavoc: no collisions
case SOLID_NOT:
case SOLID_TRIGGER:
-
- self.move_origin = self.move_origin + self.move_velocity * dt;
+ self.move_origin = self.move_origin + dt * self.move_velocity;
+ self.move_angles = self.move_angles + dt * self.move_avelocity;
self.move_angles_x -= 360.0 * floor(self.move_angles_x * (1.0 / 360.0));
self.move_angles_y -= 360.0 * floor(self.move_angles_y * (1.0 / 360.0));
self.move_angles_z -= 360.0 * floor(self.move_angles_z * (1.0 / 360.0));
- self.ltime += dt;
+ self.move_ltime += dt;
_Movetype_LinkEdict(true);
return;
default:
- printf("_Movetype_PushMove: entity %e with classname %s, unrecognized solid type %d\n", num_for_edict(self), self.classname, self.solid);
- return;
- }
- if(!self.modelindex || self.model == "null")
- {
- printf("_Movetype_PushMove: entity %e with classname %s, unusable modelindex %f\n", num_for_edict(self), self.classname, self.modelindex);
+ dprintf("_Movetype_PushMove: entity %e, unrecognized solid type %d\n", self, self.solid);
return;
}
- //pusherowner = self.owner;
- rotated = (self.move_angles * self.move_avelocity) > 0;
+ rotated = dotproduct(self.move_angles, self.move_angles) + dotproduct(self.move_avelocity, self.move_avelocity) > 0;
- move1 = self.move_velocity * dt;
- moveangle = self.move_avelocity * dt;
+ movetime2 = dt;
- a = -moveangle;
+ move1 = self.move_velocity * movetime2;
+ moveangle = self.move_avelocity * movetime2;
+ a = -moveangle;
// sets v_forward, v_right and v_up
_Movetype_AngleVectorsFLU(a);
pushorig = self.move_origin;
pushang = self.move_angles;
- pushltime = self.ltime;
+ pushltime = self.move_ltime;
// move the pusher to its final position
- self.move_origin = self.move_origin + self.move_velocity * dt;
- self.move_angles = self.move_angles + self.move_avelocity * dt;
- self.ltime += dt;
+ self.move_origin = self.move_origin + dt * self.move_velocity;
+ self.move_angles = self.move_angles + dt * self.move_avelocity;
+
+ self.move_ltime += dt;
_Movetype_LinkEdict(true);
- //pushermodel = SV_GetModelFromEdict(pusher);
- //Matrix4x4_CreateFromQuakeEntity(&pusherfinalmatrix, PRVM_serveredictvector(pusher, origin)[0], PRVM_serveredictvector(pusher, origin)[1], PRVM_serveredictvector(pusher, origin)[2],
- //PRVM_serveredictvector(pusher, angles)[0], PRVM_serveredictvector(pusher, angles)[1], PRVM_serveredictvector(pusher, angles)[2], 1);
- //Matrix4x4_Invert_Simple(&pusherfinalimatrix, &pusherfinalmatrix);
-
savesolid = self.solid;
-// see if any solid entities are inside the final position
- //num_moved = 0;
-
- entity e;
- if(self.move_movetype != MOVETYPE_FAKEPUSH) // Tenebrae's MOVETYPE_PUSH variant that doesn't push...
- for(e = findradius((self.absmin + self.absmax) * 0.5, vlen(self.absmax - self.absmin) * 0.5 + 1); e; e = e.chain)
+ if(self.move_movetype != MOVETYPE_FAKEPUSH)
+ for(check = findradius(0.5 * (self.absmin + self.absmax), 0.5 * vlen(self.absmax - self.absmin)); check; check = check.chain)
{
- if(e.owner == self)
+ switch(check.move_movetype)
+ {
+ case MOVETYPE_NONE:
+ case MOVETYPE_PUSH:
+ case MOVETYPE_FOLLOW:
+ case MOVETYPE_NOCLIP:
+ case MOVETYPE_FLY_WORLDONLY:
continue;
+ default:
+ break;
+ }
- if(self.owner == e)
+ if(check.owner == self)
continue;
- //Con_Printf("%i %s ", PRVM_NUM_FOR_EDICT(check), PRVM_GetString(PRVM_serveredictstring(check, classname)));
-
- // tell any MOVETYPE_STEP entity that it may need to check for water transitions
- //check->priv.server->waterposition_forceupdate = true;
-
- //int checkcontents = pointcontents(e.move_origin);
+ if(self.owner == check)
+ continue;
- // if the entity is standing on the pusher, it will definitely be moved
- // if the entity is not standing on the pusher, but is in the pusher's
- // final position, move it
- if(!(e.move_flags & FL_ONGROUND) || e.move_groundentity != self)
- {
- //vector pushermins = self.mins;
- //vector pushermaxs = self.maxs;
- //vector checkorigin = e.origin;
- //vector checkmins = e.mins;
- //vector checkmaxs = e.maxs;
- //Collision_ClipToGenericEntity(&trace, pushermodel, pusher->priv.server->frameblend, &pusher->priv.server->skeleton, pushermins, pushermaxs, SUPERCONTENTS_BODY, &pusherfinalmatrix,
- //&pusherfinalimatrix, checkorigin, checkmins, checkmaxs, checkorigin, checkcontents, collision_extendmovelength.value);
- tracebox(e.move_origin, e.mins, e.maxs, self.move_origin, MOVE_NOMONSTERS, e);
- if(!trace_startsolid)
- {
- //Con_Printf("- not in solid\n");
- continue;
- }
- }
- vector pivot = e.mins + 0.5 * (e.maxs - e.mins);
+ pivot = check.mins + 0.5 * (check.maxs - check.mins);
//VectorClear(pivot);
- if(rotated)
+ if (rotated)
{
vector org2;
- org = e.move_origin - self.move_origin;
- org += pivot;
- org2_x = (org * v_forward);
- org2_y = (org * v_right);
- org2_z = (org * v_up);
+ vector org = check.move_origin - self.move_origin;
+ org = org + pivot;
+ org2_x = dotproduct(org, v_forward);
+ org2_y = dotproduct(org, v_right);
+ org2_z = dotproduct(org, v_up);
move = org2 - org;
- move += move1;
+ move = move + move1;
}
else
move = move1;
- //Con_Printf("- pushing %f %f %f\n", move[0], move[1], move[2]);
-
- //VectorCopy (PRVM_serveredictvector(check, origin), check->priv.server->moved_from);
- //VectorCopy (PRVM_serveredictvector(check, angles), check->priv.server->moved_fromangles);
- //moved_edicts[num_moved++] = PRVM_NUM_FOR_EDICT(check);
-
// physics objects need better collisions than this code can do
- /*if(e.move_movetype == MOVETYPE_PHYSICS)
+ if(check.move_movetype == 32) // MOVETYPE_PHYSICS
{
- e.move_origin += move;
+ check.move_origin = check.move_origin + move;
oldself = self;
- self = e;
- _Movetype_LinkEdict(false);
- _Movetype_LinkEdict_TouchAreaGrid();
+ self = check;
+ _Movetype_LinkEdict(true);
self = oldself;
continue;
- }*/
+ }
// try moving the contacted entity
self.solid = SOLID_NOT;
oldself = self;
- self = e;
+ self = check;
if(!_Movetype_PushEntity(move, true))
{
+ self = oldself;
// entity "check" got teleported
- self.angles_y += trace_fraction * moveangle_y;
- oldself.solid = savesolid;
+ check.move_angles_y += trace_fraction * moveangle_y;
+ self.solid = savesolid;
continue; // pushed enough
}
self = oldself;
// FIXME: turn players specially
- e.angles_y += trace_fraction * moveangle_y;
+ check.move_angles_y += trace_fraction * moveangle_y;
self.solid = savesolid;
- //Con_Printf("%s:%d frac %f startsolid %d bmodelstartsolid %d allsolid %d\n", __FILE__, __LINE__, trace.fraction, trace.startsolid, trace.bmodelstartsolid, trace.allsolid);
// this trace.fraction < 1 check causes items to fall off of pushers
// if they pass under or through a wall
// the groundentity check causes items to fall off of ledges
- if(e.move_movetype != MOVETYPE_WALK && (trace_fraction < 1 || e.move_groundentity != self))
- e.move_flags &= ~FL_ONGROUND;
-
- // if it is still inside the pusher, block
- //vector pushermins = self.mins;
- //vector pushermaxs = self.maxs;
- //vector checkorigin = e.move_origin;
- //vector checkmins = e.mins;
- //vector checkmaxs = e.maxs;
- //Collision_ClipToGenericEntity(&trace, pushermodel, pusher->priv.server->frameblend, &pusher->priv.server->skeleton, pushermins, pushermaxs, SUPERCONTENTS_BODY,
- //&pusherfinalmatrix, &pusherfinalimatrix, checkorigin, checkmins, checkmaxs, checkorigin, checkcontents, collision_extendmovelength.value);
- tracebox(e.move_origin, e.mins, e.maxs, self.move_origin, MOVE_NOMONSTERS, e);
- if(trace_startsolid)
- {
- /*vector move2;
- if(SV_NudgeOutOfSolid_PivotIsKnownGood(check, pivot))
- {
- // hack to invoke all necessary movement triggers
- move2 = '0 0 0';
- if(!_Movetype_PushEntity(move2, true))
- {
- // entity "check" got teleported
- continue;
- }
- // we could fix it
- continue;
- }*/
-
- // still inside pusher, so it's really blocked
-
- // fail the move
- if(e.mins_x == e.maxs_x)
- continue;
- if(e.solid == SOLID_NOT || e.solid == SOLID_TRIGGER)
- {
- // corpse
- e.mins_x = e.mins_y = 0;
- e.maxs = e.mins;
- continue;
- }
-
- self.move_origin = pushorig;
- self.move_angles = pushang;
- self.ltime = pushltime;
- _Movetype_LinkEdict(true);
-
- // move back any entities we already moved
- /*for (i = 0;i < num_moved;i++)
- {
- prvm_edict_t *ed = PRVM_EDICT_NUM(moved_edicts[i]);
- VectorCopy (ed->priv.server->moved_from, PRVM_serveredictvector(ed, origin));
- VectorCopy (ed->priv.server->moved_fromangles, PRVM_serveredictvector(ed, angles));
- SV_LinkEdict(ed);
- }*/
-
- // if the pusher has a "blocked" function, call it, otherwise just stay in place until the obstacle is gone
- if(self.blocked)
- {
- self.move_time = time;
- other = e;
- self.blocked();
- }
- break;
- }
+ if(check.move_movetype != MOVETYPE_WALK && (trace_fraction < 1 || check.move_groundentity != self))
+ check.move_flags &= ~FL_ONGROUND;
}
+
self.move_angles_x -= 360.0 * floor(self.move_angles_x * (1.0 / 360.0));
self.move_angles_y -= 360.0 * floor(self.move_angles_y * (1.0 / 360.0));
self.move_angles_z -= 360.0 * floor(self.move_angles_z * (1.0 / 360.0));
void _Movetype_Physics_Pusher(float dt) // SV_Physics_Pusher
{
- float oldltime, movetime;
+ float thinktime, oldltime, movetime;
- oldltime = self.ltime;
+ oldltime = self.move_ltime;
- if (self.nextthink < self.ltime + dt)
+ thinktime = self.move_nextthink;
+ if(thinktime < self.move_ltime + dt)
{
- movetime = self.nextthink - self.ltime;
- if (movetime < 0)
+ movetime = thinktime - self.move_ltime;
+ if(movetime < 0)
movetime = 0;
}
else
movetime = dt;
- if (movetime)
- // advances PRVM_serveredictfloat(ent, ltime) if not blocked
+ if(movetime)
+ // advances self.move_ltime if not blocked
_Movetype_PushMove(movetime);
- if (self.nextthink > oldltime && self.nextthink <= self.ltime)
+ if(thinktime > oldltime && thinktime <= self.move_ltime)
{
- self.nextthink = 0;
- //time = dt;
+ self.move_nextthink = 0;
self.move_time = time;
other = world;
- if(self.think)
- self.think();
+ if(self.move_think)
+ self.move_think();
}
}
#ifndef MOVETYPES_H
#define MOVETYPES_H
+.float move_ltime;
+.void(void) move_think;
+.float move_nextthink;
+.void(void) move_blocked;
+
.float move_movetype;
.float move_time;
.vector move_origin;
if(!is_dead)
{
+ if(self == csqcplayer)
+ self.v_angle_x = input_angles_x;
int i;
for(i = 0; i < MAX_AIM_BONES; ++i)
{
const int ENT_CLIENT_TARGET_PUSH = 63;
const int ENT_CLIENT_CONVEYOR = 64;
const int ENT_CLIENT_DOOR = 65;
-// 66
+const int ENT_CLIENT_TRAIN = 66;
const int ENT_CLIENT_PLAT = 67;
-const int ENT_CLIENT_PLAT_TRIGGER = 68;
+// 68
const int ENT_CLIENT_SWAMP = 69;
const int ENT_CLIENT_CORNER = 70;
const int ENT_CLIENT_KEYLOCK = 71;
v = self.owner.destvec + self.owner.movedir * v_forward_y;
if(self.owner.classname == "func_bobbing") // don't brake stuff if the func_bobbing was killtarget'ed
// * 10 so it will arrive in 0.1 sec
- self.owner.velocity = (v - self.owner.origin) * 10;
+ self.owner.velocity = (v - self.owner.SUB_ORIGIN) * 10;
}
/*QUAKED spawnfunc_func_bobbing (0 .5 .8) ? X_AXIS Y_AXIS
controller.owner = self;
controller.nextthink = time + 1;
controller.think = func_bobbing_controller_think;
- trigger_setnextthink(self, self.ltime + 999999999);
- self.think = SUB_NullThink; // for PushMove
+ self.SUB_NEXTTHINK = self.SUB_LTIME + 999999999;
+ self.SUB_THINK = SUB_NullThink;
// Savage: Reduce bandwith, critical on e.g. nexdm02
self.effects |= EF_LOWPRECISION;
void button_wait()
{
self.state = STATE_TOP;
- trigger_setnextthink(self, self.ltime + self.wait);
- self.think = button_return;
+ self.SUB_NEXTTHINK = self.SUB_LTIME + self.wait;
+ self.SUB_THINK = button_return;
activator = self.enemy;
SUB_UseTargets();
self.frame = 1; // use alternate textures
return; // don't come down automatically
if (self.classname == "door")
{
- self.think = door_go_down;
+ self.SUB_THINK = door_go_down;
} else
{
- self.think = door_rotating_go_down;
+ self.SUB_THINK = door_rotating_go_down;
}
- trigger_setnextthink(self, self.ltime + self.wait);
+ self.SUB_NEXTTHINK = self.SUB_LTIME + self.wait;
}
void door_hit_bottom()
if (self.state == STATE_TOP)
{ // reset top wait time
- trigger_setnextthink(self, self.ltime + self.wait);
+ self.SUB_NEXTTHINK = self.SUB_LTIME + self.wait;
return;
}
self.state = STATE_TOP;
if (self.spawnflags & DOOR_TOGGLE)
return; // don't come down automatically
- self.think = door_rotating_go_down;
- self.nextthink = self.ltime + self.wait;
+ self.SUB_THINK = door_rotating_go_down;
+ self.SUB_NEXTTHINK = self.SUB_LTIME + self.wait;
}
void door_rotating_hit_bottom()
if (self.state == STATE_TOP)
{ // reset top wait time
- trigger_setnextthink(self, self.ltime + self.wait);
+ self.SUB_NEXTTHINK = self.SUB_LTIME + self.wait;
return;
}
if (self.noise2 != "")
WriteString(MSG_ENTITY, self.classname);
WriteByte(MSG_ENTITY, self.spawnflags);
- WriteByte(MSG_ENTITY, self.scale);
-
- 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.movedir_x);
- WriteCoord(MSG_ENTITY, self.movedir_y);
- WriteCoord(MSG_ENTITY, self.movedir_z);
-
- WriteAngle(MSG_ENTITY, self.angles_x);
- WriteAngle(MSG_ENTITY, self.angles_y);
- WriteAngle(MSG_ENTITY, self.angles_z);
+ trigger_common_write(true);
WriteCoord(MSG_ENTITY, self.pos1_x);
WriteCoord(MSG_ENTITY, self.pos1_y);
WriteShort(MSG_ENTITY, self.speed);
WriteByte(MSG_ENTITY, self.lip);
WriteByte(MSG_ENTITY, self.state);
- WriteCoord(MSG_ENTITY, self.ltime);
+ WriteCoord(MSG_ENTITY, self.SUB_LTIME);
}
if(sf & SF_TRIGGER_RESET)
void door_init_startopen()
{
- setorigin (self, self.pos2);
+ SUB_SETORIGIN(self, self.pos2);
self.pos2 = self.pos1;
self.pos1 = self.origin;
void door_reset()
{
- setorigin(self, self.pos1);
- self.velocity = '0 0 0';
+ SUB_SETORIGIN(self, self.pos1);
+ self.SUB_VELOCITY = '0 0 0';
self.state = STATE_BOTTOM;
- self.think = func_null;
- self.nextthink = 0;
+ self.SUB_THINK = func_null;
+ self.SUB_NEXTTHINK = 0;
#ifdef SVQC
self.SendFlags |= SF_TRIGGER_RESET;
if (!self.lip)
self.lip = 8;
- self.pos1 = self.origin;
+ self.pos1 = self.SUB_ORIGIN;
self.pos2 = self.pos1 + self.movedir*(fabs(self.movedir*self.size) - self.lip);
// DOOR_START_OPEN is to allow an entity to be lighted in the closed position
#elif defined(CSQC)
+void door_draw()
+{
+ Movetype_Physics_NoMatchServer();
+
+ trigger_draw_generic();
+}
+
void ent_door()
{
float sf = ReadByte();
self.classname = strzone(ReadString());
self.spawnflags = ReadByte();
- self.scale = ReadByte();
-
- self.origin_x = ReadCoord();
- self.origin_y = ReadCoord();
- self.origin_z = ReadCoord();
- setorigin(self, self.origin);
-
self.mdl = strzone(ReadString());
setmodel(self, self.mdl);
- 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.movedir_x = ReadCoord();
- self.movedir_y = ReadCoord();
- self.movedir_z = ReadCoord();
-
- self.angles_x = ReadAngle();
- self.angles_y = ReadAngle();
- self.angles_z = ReadAngle();
+ trigger_common_read(true);
self.pos1_x = ReadCoord();
self.pos1_y = ReadCoord();
self.speed = ReadShort();
self.lip = ReadByte();
self.state = ReadByte();
- self.ltime = ReadCoord();
+ self.SUB_LTIME = ReadCoord();
- self.movetype = MOVETYPE_PUSH;
self.solid = SOLID_BSP;
+ self.movetype = MOVETYPE_PUSH;
self.trigger_touch = door_touch;
- self.draw = trigger_draw_generic;
+ self.draw = door_draw;
self.drawmask = MASK_NORMAL;
- self.move_time = time;
self.use = door_use;
- self.blocked = door_blocked;
LinkDoors();
if(self.spawnflags & DOOR_START_OPEN)
door_init_startopen();
+
+ self.move_time = time;
+ self.move_origin = self.origin;
+ self.move_movetype = MOVETYPE_PUSH;
+ self.move_angles = self.angles;
+ self.move_blocked = door_blocked;
}
if(sf & SF_TRIGGER_RESET)
self.origin_y = ReadCoord();
self.origin_z = ReadCoord();
setorigin(self, self.origin);
+ self.move_origin = self.origin;
self.pos1_x = ReadCoord();
self.pos1_y = ReadCoord();
if (self.noise1 != "")
sound(self, CH_TRIGGER_SINGLE, self.noise1, VOL_BASE, ATTEN_NORM);
- trigger_setnextthink(self, self.ltime + 0.1);
+ self.SUB_NEXTTHINK = self.SUB_LTIME + 0.1;
temp = 1 - (self.spawnflags & SECRET_1ST_LEFT); // 1 or -1
makevectors(self.mangle);
// Wait after first movement...
void fd_secret_move1()
{
- trigger_setnextthink(self, self.ltime + 1.0);
+ self.SUB_NEXTTHINK = self.SUB_LTIME + 1.0;
self.think = fd_secret_move2;
if (self.noise3 != "")
sound(self, CH_TRIGGER_SINGLE, self.noise3, VOL_BASE, ATTEN_NORM);
sound(self, CH_TRIGGER_SINGLE, self.noise3, VOL_BASE, ATTEN_NORM);
if (!(self.spawnflags & SECRET_OPEN_ONCE))
{
- trigger_setnextthink(self, self.ltime + self.wait);
+ self.SUB_NEXTTHINK = self.SUB_LTIME + self.wait;
self.think = fd_secret_move4;
}
}
// Wait 1 second...
void fd_secret_move5()
{
- trigger_setnextthink(self, self.ltime + 1.0);
+ self.SUB_NEXTTHINK = self.SUB_LTIME + 1.0;
self.think = fd_secret_move6;
if (self.noise3 != "")
sound(self, CH_TRIGGER_SINGLE, self.noise3, VOL_BASE, ATTEN_NORM);
}
setorigin(self, self.oldorigin);
self.think = func_null;
- self.nextthink = 0;
+ self.SUB_NEXTTHINK = 0;
}
/*QUAKED spawnfunc_func_door_secret (0 .5 .8) ? open_once 1st_left 1st_down no_shoot always_shoot
controller.owner = self;
controller.nextthink = time + 1;
controller.think = func_fourier_controller_think;
- trigger_setnextthink(self, self.ltime + 999999999);
- self.think = SUB_NullThink; // for PushMove
+ self.SUB_NEXTTHINK = self.SUB_LTIME + 999999999;
+ self.SUB_THINK = SUB_NullThink; // for PushMove
// Savage: Reduce bandwith, critical on e.g. nexdm02
self.effects |= EF_LOWPRECISION;
#include "plat.qh"
#include "rainsnow.qh"
#include "pointparticles.qh"
+#include "train.qh"
#endif
controller.owner = self;
controller.nextthink = time + 1;
controller.think = func_pendulum_controller_think;
- trigger_setnextthink(self, self.ltime + 999999999);
- self.think = SUB_NullThink; // for PushMove
+ self.nextthink = self.SUB_LTIME + 999999999;
+ self.SUB_THINK = SUB_NullThink; // for PushMove
//self.effects |= EF_LOWPRECISION;
#ifdef SVQC
+void plat_link();
+
void plat_delayedinit()
{
+ plat_link();
plat_spawn_inside_trigger(); // the "start moving" trigger
}
if(sf & SF_TRIGGER_INIT)
{
- WriteShort(MSG_ENTITY, num_for_edict(self));
-
WriteByte(MSG_ENTITY, self.platmovetype_start);
WriteByte(MSG_ENTITY, self.platmovetype_turn);
WriteByte(MSG_ENTITY, self.platmovetype_end);
+ WriteByte(MSG_ENTITY, self.spawnflags);
WriteString(MSG_ENTITY, self.model);
self.reset = plat_reset;
plat_reset();
- plat_link();
-
InitializeEntity(self, plat_delayedinit, INITPRIO_FINDTARGET);
}
#elif defined(CSQC)
void plat_draw()
{
Movetype_Physics_NoMatchServer();
+ //Movetype_Physics_MatchServer(autocvar_cl_projectiles_sloppy);
}
void ent_plat()
if(sf & SF_TRIGGER_INIT)
{
- self.sv_entnum = ReadShort();
-
self.platmovetype_start = ReadByte();
self.platmovetype_turn = ReadByte();
self.platmovetype_end = ReadByte();
+ self.spawnflags = ReadByte();
self.model = strzone(ReadString());
setmodel(self, self.model);
self.dmg = ReadShort();
+ self.classname = "plat";
self.solid = SOLID_BSP;
self.movetype = MOVETYPE_PUSH;
self.drawmask = MASK_NORMAL;
plat_reset(); // also called here
+ self.move_movetype = MOVETYPE_PUSH;
self.move_origin = self.origin;
self.move_angles = self.angles;
self.move_time = time;
+
+ plat_spawn_inside_trigger();
}
if(sf & SF_TRIGGER_RESET)
self.blocked = generic_plat_blocked;
// wait for targets to spawn
- trigger_setnextthink(self, self.ltime + 999999999);
- self.think = SUB_NullThink; // for PushMove
+ self.SUB_NEXTTHINK = self.SUB_LTIME + 999999999;
+ self.SUB_THINK = SUB_NullThink; // for PushMove
// TODO make a reset function for this one
}
-#ifdef SVQC
.float train_wait_turning;
void() train_next;
void train_wait()
ang_x = -ang_x; // flip up / down orientation
if(self.wait > 0) // slow turning
- SUB_CalcAngleMove(ang, TSPEED_TIME, self.ltime - time + self.wait, train_wait);
+ SUB_CalcAngleMove(ang, TSPEED_TIME, self.SUB_LTIME - time + self.wait, train_wait);
else // instant turning
SUB_CalcAngleMove(ang, TSPEED_TIME, 0.0000001, train_wait);
self.train_wait_turning = true;
return;
}
+#ifdef SVQC
if(self.noise != "")
stopsoundto(MSG_BROADCAST, self, CH_TRIGGER_SINGLE); // send this as unreliable only, as the train will resume operation shortly anyway
+#endif
if(self.wait < 0 || self.train_wait_turning) // no waiting or we already waited while turning
{
}
else
{
- self.think = train_next;
- trigger_setnextthink(self, self.ltime + self.wait);
+ self.SUB_THINK = train_next;
+ self.SUB_NEXTTHINK = self.SUB_LTIME + self.wait;
}
}
sound(self, CH_TRIGGER_SINGLE, self.noise, VOL_BASE, ATTEN_IDLE);
}
+#ifdef SVQC
+float train_send(entity to, float sf)
+{
+ WriteByte(MSG_ENTITY, ENT_CLIENT_TRAIN);
+ WriteByte(MSG_ENTITY, sf);
+
+ if(sf & SF_TRIGGER_INIT)
+ {
+ WriteString(MSG_ENTITY, self.platmovetype);
+ WriteByte(MSG_ENTITY, self.platmovetype_turn);
+ WriteByte(MSG_ENTITY, self.spawnflags);
+
+ WriteString(MSG_ENTITY, self.model);
+
+ trigger_common_write(true);
+
+ WriteString(MSG_ENTITY, self.curvetarget);
+
+ 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);
+
+ WriteCoord(MSG_ENTITY, self.view_ofs_x);
+ WriteCoord(MSG_ENTITY, self.view_ofs_y);
+ WriteCoord(MSG_ENTITY, self.view_ofs_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);
+ WriteByte(MSG_ENTITY, self.wait);
+
+ WriteShort(MSG_ENTITY, self.dmg);
+ WriteByte(MSG_ENTITY, self.dmgtime);
+ }
+
+ if(sf & SF_TRIGGER_RESET)
+ {
+ // used on client
+ }
+
+ return true;
+}
+
+void train_link()
+{
+ Net_LinkEntity(self, 0, false, train_send);
+}
+
void func_train_find()
{
entity targ;
self.target = targ.target;
if (self.target == "")
objerror("func_train_find: no next target");
- setorigin(self, targ.origin - self.view_ofs);
- trigger_setnextthink(self, self.ltime + 1);
- self.think = train_next;
+ SUB_SETORIGIN(self, targ.origin - self.view_ofs);
+ self.SUB_NEXTTHINK = self.SUB_LTIME + 1;
+ self.SUB_THINK = train_next;
+
+ train_link();
}
+#endif
+
/*QUAKED spawnfunc_func_train (0 .5 .8) ?
Ridable platform, targets spawnfunc_path_corner path to follow.
speed : speed the train moves (can be overridden by each spawnfunc_path_corner)
target : targetname of first spawnfunc_path_corner (starts here)
*/
+#ifdef SVQC
void spawnfunc_func_train()
{
if (self.noise != "")
// TODO make a reset function for this one
}
+#elif defined(CSQC)
+void train_draw()
+{
+ //Movetype_Physics_NoMatchServer();
+ Movetype_Physics_MatchServer(autocvar_cl_projectiles_sloppy);
+}
+
+void ent_train()
+{
+ float sf = ReadByte();
+
+ if(sf & SF_TRIGGER_INIT)
+ {
+ self.platmovetype = strzone(ReadString());
+ self.platmovetype_turn = ReadByte();
+ self.spawnflags = ReadByte();
+
+ self.model = strzone(ReadString());
+ setmodel(self, self.model);
+
+ trigger_common_read(true);
+
+ self.curvetarget = strzone(ReadString());
+
+ 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.view_ofs_x = ReadCoord();
+ self.view_ofs_y = ReadCoord();
+ self.view_ofs_z = ReadCoord();
+
+ 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.wait = ReadByte();
+
+ self.dmg = ReadShort();
+ self.dmgtime = ReadByte();
+
+ self.classname = "func_train";
+ self.solid = SOLID_BSP;
+ self.movetype = MOVETYPE_PUSH;
+ self.drawmask = MASK_NORMAL;
+ self.draw = train_draw;
+ self.entremove = trigger_remove_generic;
+
+ if(set_platmovetype(self, self.platmovetype))
+ {
+ self.platmovetype_start_default = self.platmovetype_start;
+ self.platmovetype_end_default = self.platmovetype_end;
+ }
+
+ // everything is set up by the time the train is linked, we shouldn't need this
+ //func_train_find();
+
+ // but we will need these
+ self.move_nextthink = self.move_ltime + 0.1;
+ self.move_think = train_next;
+
+ self.move_movetype = MOVETYPE_PUSH;
+ self.move_origin = self.origin;
+ self.move_angles = self.angles;
+ self.move_time = time;
+ }
+
+ if(sf & SF_TRIGGER_RESET)
+ {
+ // TODO: make a reset function for trains
+ }
+}
+
#endif
--- /dev/null
+#ifdef CSQC
+.float dmgtime;
+void ent_train();
+#endif
return;
// wait for targets to spawn
- trigger_setnextthink(self, self.ltime + 999999999);
- self.think = SUB_NullThink; // for PushMove
+ self.SUB_NEXTTHINK = self.SUB_LTIME + 999999999;
+ self.SUB_THINK = SUB_NullThink; // for PushMove
// Savage: Reduce bandwith, critical on e.g. nexdm02
self.effects |= EF_LOWPRECISION;
WriteString(MSG_ENTITY, self.target3);
WriteString(MSG_ENTITY, self.target4);
WriteString(MSG_ENTITY, self.targetname);
+ WriteByte(MSG_ENTITY, self.target_random);
+
+ WriteByte(MSG_ENTITY, self.wait);
return true;
}
void spawnfunc_path_corner()
{
- corner_link();
-
// setup values for overriding train movement
// if a second value does not exist, both start and end speeds are the single value specified
set_platmovetype(self, self.platmovetype);
+
+ corner_link();
}
#elif defined(CSQC)
self.targetname = string_null;
if(self.platmovetype) { strunzone(self.platmovetype); }
- self.targetname = string_null;
+ self.platmovetype = string_null;
}
void ent_corner()
self.origin_x = ReadCoord();
self.origin_y = ReadCoord();
self.origin_z = ReadCoord();
+ setorigin(self, self.origin);
self.target = strzone(ReadString());
self.target2 = strzone(ReadString());
self.target3 = strzone(ReadString());
self.target4 = strzone(ReadString());
self.targetname = strzone(ReadString());
+ self.target_random = ReadByte();
+
+ self.wait = ReadByte();
self.classname = "path_corner";
self.drawmask = MASK_NORMAL;
#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()
{
entity trigger;
trigger.solid = SOLID_TRIGGER;
trigger.enemy = self;
+#ifdef CSQC
+ trigger.drawmask = MASK_NORMAL;
+ trigger.trigger_touch = plat_center_touch;
+ trigger.draw = trigger_draw_generic;
+#endif
+
tmin = self.absmin + '25 25 0';
tmax = self.absmax - '25 25 -8';
tmin_z = tmax_z - (self.pos1_z - self.pos2_z + 8);
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()
{
sound (self, CH_TRIGGER_SINGLE, self.noise1, VOL_BASE, ATTEN_NORM);
self.state = 1;
- self.think = plat_go_down;
- trigger_setnextthink(self, self.ltime + 3);
+
+ self.SUB_THINK = plat_go_down;
+ self.SUB_NEXTTHINK = self.SUB_LTIME + 3;
}
void plat_hit_bottom()
#elif defined(CSQC)
if (!IS_PLAYER(other))
return;
+ if(PHYS_DEAD(other))
+ return;
#endif
self = self.enemy;
if (self.state == 2)
plat_go_up ();
else if (self.state == 1)
- trigger_setnextthink(self, self.ltime + 1);
+ self.SUB_NEXTTHINK = self.SUB_LTIME + 1;
}
void plat_outside_touch()
void plat_trigger_use()
{
+#ifdef SVQC
if (self.think)
return; // already activated
+#elif defined(CSQC)
+ if(self.move_think)
+ return;
+#endif
plat_go_down();
}
.float dmg;
-#ifdef CSQC
-void ent_plat_trigger();
-#endif
-
#endif
.float friction;
void SUB_Friction (void)
{
- self.nextthink = time;
- if(self.flags & FL_ONGROUND)
- self.velocity = self.velocity * (1 - frametime * self.friction);
+ self.SUB_NEXTTHINK = time;
+ if(self.SUB_FLAGS & FL_ONGROUND)
+ self.SUB_VELOCITY = self.SUB_VELOCITY * (1 - frametime * self.friction);
}
/*
{
if(self.alpha == 0)
self.alpha = 1;
- self.think = SUB_SetFade_Think;
- self.nextthink = time;
+ self.SUB_THINK = SUB_SetFade_Think;
+ self.SUB_NEXTTHINK = time;
self.alpha -= frametime * self.fade_rate;
if (self.alpha < 0.01)
SUB_VanishOrRemove(self);
else
- self.nextthink = time;
+ self.SUB_NEXTTHINK = time;
}
/*
void SUB_SetFade (entity ent, float when, float fading_time)
{
ent.fade_rate = 1/fading_time;
- ent.think = SUB_SetFade_Think;
- ent.nextthink = when;
+ ent.SUB_THINK = SUB_SetFade_Think;
+ ent.SUB_NEXTTHINK = when;
}
/*
=============
SUB_CalcMove
-calculate self.velocity and self.nextthink to reach dest from
-self.origin traveling at speed
+calculate self.SUB_VELOCITY and self.SUB_NEXTTHINK to reach dest from
+self.SUB_ORIGIN traveling at speed
===============
*/
void SUB_CalcMoveDone (void)
{
// After moving, set origin to exact final destination
- setorigin (self, self.finaldest);
- self.velocity = '0 0 0';
- self.nextthink = -1;
+ SUB_SETORIGIN (self, self.finaldest);
+ self.SUB_VELOCITY = '0 0 0';
+ self.SUB_NEXTTHINK = -1;
if (self.think1)
self.think1 ();
}
destangle_x = -destangle_x; // flip up / down orientation
// take the shortest distance for the angles
- self.owner.angles_x -= 360 * floor((self.owner.angles_x - destangle_x) / 360 + 0.5);
- self.owner.angles_y -= 360 * floor((self.owner.angles_y - destangle_y) / 360 + 0.5);
- self.owner.angles_z -= 360 * floor((self.owner.angles_z - destangle_z) / 360 + 0.5);
- angloc = destangle - self.owner.angles;
+ SUB_ANGLES(self.owner)_x -= 360 * floor((SUB_ANGLES(self.owner)_x - destangle_x) / 360 + 0.5);
+ SUB_ANGLES(self.owner)_y -= 360 * floor((SUB_ANGLES(self.owner)_y - destangle_y) / 360 + 0.5);
+ SUB_ANGLES(self.owner)_z -= 360 * floor((SUB_ANGLES(self.owner)_z - destangle_z) / 360 + 0.5);
+ angloc = destangle - SUB_ANGLES(self.owner);
angloc = angloc * (1 / PHYS_INPUT_FRAMETIME); // so it arrives for the next frame
- self.owner.avelocity = angloc;
+ self.owner.SUB_AVELOCITY = angloc;
}
if(nexttick < self.animstate_endtime)
- veloc = nextpos - self.owner.origin;
+ veloc = nextpos - self.owner.SUB_ORIGIN;
else
- veloc = self.finaldest - self.owner.origin;
+ veloc = self.finaldest - self.owner.SUB_ORIGIN;
veloc = veloc * (1 / PHYS_INPUT_FRAMETIME); // so it arrives for the next frame
- self.owner.velocity = veloc;
+ self.owner.SUB_VELOCITY = veloc;
self.nextthink = nexttick;
}
else
{
// derivative: delta + 2 * delta2 (e.g. for angle positioning)
oldself = self;
- self.owner.think = self.think1;
+ self.owner.SUB_THINK = self.think1;
self = self.owner;
remove(oldself);
- self.think();
+ self.SUB_THINK();
}
}
// 2 * control * t - 2 * control * t * t + destin * t * t
// 2 * control * t + (destin - 2 * control) * t * t
- controller.origin = org; // starting point
+ setorigin(controller, org);
control -= org;
destin -= org;
// 2 * control * t - 2 * control * t * t + destin * t * t
// 2 * control * t + (destin - 2 * control) * t * t
- controller.origin = org; // starting point
+ setorigin(controller, org);
destin -= org;
controller.destvec = destin; // end point
self.think1 = func;
self.finaldest = tdest;
- self.think = SUB_CalcMoveDone;
+ self.SUB_THINK = SUB_CalcMoveDone;
switch(tspeedtype)
{
default:
case TSPEED_START:
- traveltime = 2 * vlen(tcontrol - self.origin) / tspeed;
+ traveltime = 2 * vlen(tcontrol - self.SUB_ORIGIN) / tspeed;
break;
case TSPEED_END:
traveltime = 2 * vlen(tcontrol - tdest) / tspeed;
break;
case TSPEED_LINEAR:
- traveltime = vlen(tdest - self.origin) / tspeed;
+ traveltime = vlen(tdest - self.SUB_ORIGIN) / tspeed;
break;
case TSPEED_TIME:
traveltime = tspeed;
if (traveltime < 0.1) // useless anim
{
- self.velocity = '0 0 0';
- trigger_setnextthink(self, self.ltime + 0.1);
+ self.SUB_VELOCITY = '0 0 0';
+ self.SUB_NEXTTHINK = self.SUB_LTIME + 0.1;
return;
}
controller.platmovetype = self.platmovetype;
controller.platmovetype_start = self.platmovetype_start;
controller.platmovetype_end = self.platmovetype_end;
- SUB_CalcMove_controller_setbezier(controller, self.origin, tcontrol, tdest);
+ SUB_CalcMove_controller_setbezier(controller, self.SUB_ORIGIN, tcontrol, tdest);
controller.finaldest = (tdest + '0 0 0.125'); // where do we want to end? Offset to overshoot a bit.
controller.animstate_starttime = time;
controller.animstate_endtime = time + traveltime;
controller.think = SUB_CalcMove_controller_think;
- controller.think1 = self.think;
+ controller.think1 = self.SUB_THINK;
// the thinking is now done by the controller
- self.think = SUB_NullThink; // for PushMove
- trigger_setnextthink(self, self.ltime + traveltime);
+ self.SUB_THINK = SUB_NullThink; // for PushMove
+ self.SUB_NEXTTHINK = self.SUB_LTIME + traveltime;
// invoke controller
self = controller;
self.think1 = func;
self.finaldest = tdest;
- self.think = SUB_CalcMoveDone;
+ self.SUB_THINK = SUB_CalcMoveDone;
- if (tdest == self.origin)
+ if (tdest == self.SUB_ORIGIN)
{
- self.velocity = '0 0 0';
- trigger_setnextthink(self, self.ltime + 0.1);
+ self.SUB_VELOCITY = '0 0 0';
+ self.SUB_NEXTTHINK = self.SUB_LTIME + 0.1;
return;
}
- delta = tdest - self.origin;
+ delta = tdest - self.SUB_ORIGIN;
switch(tspeedtype)
{
// The only currently implemented alternative movement is linear (value 1)
if (traveltime < 0.15 || (self.platmovetype_start == 1 && self.platmovetype_end == 1)) // is this correct?
{
- self.velocity = delta * (1/traveltime); // QuakeC doesn't allow vector/float division
- trigger_setnextthink(self, self.ltime + traveltime);
+ self.SUB_VELOCITY = delta * (1/traveltime); // QuakeC doesn't allow vector/float division
+ self.SUB_NEXTTHINK = self.SUB_LTIME + traveltime;
return;
}
// now just run like a bezier curve...
- SUB_CalcMove_Bezier((self.origin + tdest) * 0.5, tdest, tspeedtype, tspeed, func);
+ SUB_CalcMove_Bezier((self.SUB_ORIGIN + tdest) * 0.5, tdest, tspeedtype, tspeed, func);
}
void SUB_CalcMoveEnt (entity ent, vector tdest, float tspeedtype, float tspeed, void() func)
=============
SUB_CalcAngleMove
-calculate self.avelocity and self.nextthink to reach destangle from
+calculate self.SUB_AVELOCITY and self.SUB_NEXTTHINK to reach destangle from
self.angles rotating
-The calling function should make sure self.think is valid
+The calling function should make sure self.SUB_THINK is valid
===============
*/
void SUB_CalcAngleMoveDone (void)
{
// After rotating, set angle to exact final angle
self.angles = self.finalangle;
- self.avelocity = '0 0 0';
- self.nextthink = -1;
+ self.SUB_AVELOCITY = '0 0 0';
+ self.SUB_NEXTTHINK = -1;
if (self.think1)
self.think1 ();
}
self.think1 = func;
self.finalangle = destangle;
- self.think = SUB_CalcAngleMoveDone;
+ self.SUB_THINK = SUB_CalcAngleMoveDone;
if (traveltime < 0.1)
{
- self.avelocity = '0 0 0';
- trigger_setnextthink(self, self.ltime + 0.1);
+ self.SUB_AVELOCITY = '0 0 0';
+ self.SUB_NEXTTHINK = self.SUB_LTIME + 0.1;
return;
}
- self.avelocity = delta * (1 / traveltime);
- trigger_setnextthink(self, self.ltime + traveltime);
+ self.SUB_AVELOCITY = delta * (1 / traveltime);
+ self.SUB_NEXTTHINK = self.SUB_LTIME + traveltime;
}
void SUB_CalcAngleMoveEnt (entity ent, vector destangle, float tspeedtype, float tspeed, void() func)
#ifndef SUBS_H
#define SUBS_H
+#ifdef SVQC
+
+ #define SUB_ANGLES(s) (s).angles
+ #define SUB_VELOCITY velocity
+ #define SUB_AVELOCITY avelocity
+ #define SUB_ORIGIN origin
+ #define SUB_SETORIGIN(s,v) setorigin((s), (v))
+ #define SUB_NEXTTHINK nextthink
+ #define SUB_THINK think
+ #define SUB_LTIME ltime
+ #define SUB_FLAGS flags
+
+#elif defined(CSQC)
+
+ void _Movetype_LinkEdict(float touch_triggers);
+
+ #define SUB_ANGLES(s) (s).move_angles
+ #define SUB_VELOCITY move_velocity
+ #define SUB_AVELOCITY move_avelocity
+ #define SUB_ORIGIN move_origin
+ #define SUB_NEXTTHINK move_nextthink
+ #define SUB_THINK move_think
+ #define SUB_LTIME move_ltime
+ #define SUB_FLAGS move_flags
+
+ void SUB_SETORIGIN(entity s, vector v)
+ {
+ s.move_origin = v;
+ entity oldself = self;
+ self = s;
+ _Movetype_LinkEdict(true);
+ self = oldself;
+ }
+
+#endif
+
void SUB_Remove();
void SUB_SetFade (entity ent, float when, float fading_time);
void SUB_VanishOrRemove (entity ent);
void delay_use()
{
self.think = SUB_UseTargets;
- trigger_setnextthink(self, self.wait);
+ self.nextthink = self.wait;
}
void delay_reset()
e.maxs_z = rint(e.maxs_z);
}
-void trigger_setnextthink(entity e, float dtime)
-{
-#ifdef CSQC
- e.nextthink = time + dtime;
-#else
- e.nextthink = dtime;
-#endif
-}
-
#ifdef SVQC
void trigger_common_write(bool withtarget)
{
self.move_time = time;
if(dt <= 0) { return; }
- setorigin(self, self.origin + self.velocity * frametime);
-
if(self.trigger_touch) { trigger_touch_generic(self.trigger_touch); }
}
#endif
.float lip;
-void trigger_setnextthink(entity e, float dtime);
-
// used elsewhere (will fix)
#ifdef SVQC
void trigger_common_write(bool withtarget);