vector planes[MAX_CLIP_PLANES];
int _Movetype_FlyMove(float dt, bool applygravity, vector stepnormal, float stepheight) // SV_FlyMove
-{
+{SELFPARAM();
int blocked = 0, bumpcount;
int i, j, numplanes = 0;
float time_left = dt, grav = 0;
vector push;
- vector primal_velocity, original_velocity, new_velocity = '0 0 0', restore_velocity;
+ vector primal_velocity, original_velocity, restore_velocity;
- for(i = 0; i <= MAX_CLIP_PLANES; ++i)
+ for(i = 0; i < MAX_CLIP_PLANES; ++i)
planes[i] = '0 0 0';
- grav = 0;
-
- restore_velocity = self.move_velocity;
-
if(applygravity)
{
self.move_didgravity = 1;
}
}
- original_velocity = primal_velocity = self.move_velocity;
+ original_velocity = primal_velocity = restore_velocity = self.move_velocity;
for(bumpcount = 0;bumpcount < MAX_CLIP_PLANES;bumpcount++)
{
- if(!self.move_velocity_x && !self.move_velocity_y && !self.move_velocity_z)
+ if(self.move_velocity == '0 0 0')
break;
push = self.move_velocity * time_left;
- if(!_Movetype_PushEntity(push, false))
+ vector prev_origin = self.move_origin;
+ _Movetype_PushEntity(push, true);
+ if(trace_startsolid && self.move_origin != prev_origin)
{
// we got teleported by a touch function
// let's abort the move
if(trace_fraction == 1)
break;
+
+ float my_trace_fraction = trace_fraction;
+ vector my_trace_plane_normal = trace_plane_normal;
+
if(trace_plane_normal_z)
{
if(trace_plane_normal_z > 0.7)
else if(stepheight)
{
// step - handle it immediately
- vector org;
- vector steppush;
- //Con_Printf("step %f %f %f : ", self.move_origin_x, PRVM_serveredictvector(ent, origin)[1], PRVM_serveredictvector(ent, origin)[2]);
- steppush = '0 0 1' * stepheight;
- org = self.move_origin;
- if(!_Movetype_PushEntity(steppush, false))
+ vector org = self.move_origin;
+ vector steppush = '0 0 1' * stepheight;
+
+ _Movetype_PushEntity(steppush, true);
+ if(trace_startsolid && self.move_origin != org)
{
blocked |= 8;
break;
}
- //Con_Printf("%f %f %f : ", self.move_origin_x, PRVM_serveredictvector(ent, origin)[1], PRVM_serveredictvector(ent, origin)[2]);
- if(!_Movetype_PushEntity(push, false))
+ _Movetype_PushEntity(push, true);
+ if(trace_startsolid && self.move_origin != org)
{
blocked |= 8;
break;
}
float trace2_fraction = trace_fraction;
- //Con_Printf("%f %f %f : ", self.move_origin_x, PRVM_serveredictvector(ent, origin)[1], PRVM_serveredictvector(ent, origin)[2]);
steppush = '0 0 1' * (org_z - self.move_origin_z);
- if(!_Movetype_PushEntity(steppush, false))
+ _Movetype_PushEntity(steppush, true);
+ if(trace_startsolid && self.move_origin != org)
{
blocked |= 8;
break;
}
- //Con_Printf("%f %f %f : ", self.move_origin_x, PRVM_serveredictvector(ent, origin)[1], PRVM_serveredictvector(ent, origin)[2]);
+
// accept the new position if it made some progress...
if(fabs(self.move_origin_x - org_x) >= 0.03125 || fabs(self.move_origin_y - org_y) >= 0.03125)
{
- //Con_Printf("accepted (delta %f %f %f)\n", self.move_origin_x - org_x, PRVM_serveredictvector(ent, origin)[1] - org[1], PRVM_serveredictvector(ent, origin)[2] - org[2]);
trace_endpos = self.move_origin;
time_left *= 1 - trace2_fraction;
numplanes = 0;
continue;
}
else
- {
- //Con_Printf("REJECTED (delta %f %f %f)\n", self.move_origin_x - org_x, PRVM_serveredictvector(ent, origin)[1] - org[1], PRVM_serveredictvector(ent, origin)[2] - org[2]);
self.move_origin = org;
- }
}
else
{
if(stepnormal)
stepnormal = trace_plane_normal;
}
- if(trace_fraction >= 0.001)
+
+ if(my_trace_fraction >= 0.001)
{
// actually covered some distance
original_velocity = self.move_velocity;
numplanes = 0;
}
- time_left *= 1 - trace_fraction;
+ time_left *= 1 - my_trace_fraction;
// clipped to another plane
if(numplanes >= MAX_CLIP_PLANES)
break;
}
- planes[numplanes] = trace_plane_normal;
+ planes[numplanes] = my_trace_plane_normal;
numplanes++;
// modify original_velocity so it parallels all of the clip planes
+ vector new_velocity = '0 0 0';
for (i = 0;i < numplanes;i++)
{
new_velocity = _Movetype_ClipVelocity(original_velocity, planes[i], 1);
blocked = 7;
break;
}
- vector dir;
- dir.x = planes[0].y * planes[1].z - planes[0].z * planes[1].y;
- dir.y = planes[0].z * planes[1].x - planes[0].x * planes[1].z;
- dir.z = planes[0].x * planes[1].y - planes[0].y * planes[1].x;
+ vector dir = cross(planes[0], planes[1]);
// LordHavoc: thanks to taniwha of QuakeForge for pointing out this fix for slowed falling in corners
float ilength = sqrt((dir * dir));
if(ilength)
}
void _Movetype_Impact(entity oth) // SV_Impact
-{
- entity oldself = self;
+{SELFPARAM();
entity oldother = other;
if(self.move_touch)
if(oth.move_touch)
{
other = self;
- self = oth;
- self.move_touch();
+ WITH(entity, self, oth, oth.move_touch());
- self = oldself;
other = oldother;
}
}
void _Movetype_LinkEdict_TouchAreaGrid() // SV_LinkEdict_TouchAreaGrid
-{
- entity oldself = self;
+{SELFPARAM();
entity oldother = other;
for (entity e = findradius(0.5 * (self.absmin + self.absmax), 0.5 * vlen(self.absmax - self.absmin)); e; e = e.chain)
{
- if(e.move_touch && boxesoverlap(e.absmin, e.absmax, oldself.absmin, oldself.absmax))
+ if(e.move_touch && boxesoverlap(e.absmin, e.absmax, this.absmin, this.absmax))
{
- self = e;
- other = oldself;
+ setself(e);
+ other = this;
trace_allsolid = false;
trace_startsolid = false;
trace_endpos = e.origin;
trace_plane_normal = '0 0 1';
trace_plane_dist = 0;
- trace_ent = oldself;
+ trace_ent = this;
e.move_touch();
}
}
other = oldother;
- self = oldself;
+ setself(this);
}
void _Movetype_LinkEdict(bool touch_triggers) // SV_LinkEdict
-{
+{SELFPARAM();
vector mi, ma;
if(self.solid == SOLID_BSP)
{
}
bool _Movetype_TestEntityPosition(vector ofs) // SV_TestEntityPosition
-{
+{SELFPARAM();
// vector org = self.move_origin + ofs;
int cont = self.dphitcontentsmask;
}
bool _Movetype_UnstickEntity() // SV_UnstickEntity
-{
+{SELFPARAM();
if(!_Movetype_TestEntityPosition('0 0 0')) return true;
if(!_Movetype_TestEntityPosition('-1 0 0')) goto success;
if(!_Movetype_TestEntityPosition('1 0 0')) goto success;
}
void _Movetype_PushEntityTrace(vector push)
-{
+{SELFPARAM();
vector end = self.move_origin + push;
int type;
if(self.move_nomonsters)
}
float _Movetype_PushEntity(vector push, bool failonstartsolid) // SV_PushEntity
-{
+{SELFPARAM();
_Movetype_PushEntityTrace(push);
if(trace_startsolid && failonstartsolid)
}
void _Movetype_Physics_Frame(float movedt)
-{
+{SELFPARAM();
self.move_didgravity = -1;
switch (self.move_movetype)
{
}
void Movetype_Physics_NoMatchServer() // optimized
-{
+{SELFPARAM();
float movedt = time - self.move_time;
self.move_time = time;
}
void Movetype_Physics_MatchTicrate(float tr, bool sloppy) // SV_Physics_Entity
-{
+{SELFPARAM();
if(tr <= 0)
{
Movetype_Physics_NoMatchServer();
void _Movetype_Physics_Walk(float dt) // SV_WalkMove
-{
+{SELFPARAM();
vector stepnormal = '0 0 0';
// if frametime is 0 (due to client sending the same timestamp twice), don't move
// move up
vector upmove = '0 0 1' * PHYS_STEPHEIGHT;
- if (!_Movetype_PushEntity(upmove, true))
+ vector prev_origin = self.move_origin;
+ _Movetype_PushEntity(upmove, true);
+ if(wasfreed(self))
+ return;
+ if(trace_startsolid && self.move_origin != prev_origin)
{
// we got teleported when upstepping... must abort the move
return;
// Con_Printf("step - ");
// extra friction based on view angle
- if (clip & 2 && PHYS_WALLFRICTION)
+ if ((clip & 2) && PHYS_WALLFRICTION)
_Movetype_WallFriction(stepnormal);
}
// don't do the down move if stepdown is disabled, moving upward, not in water, or the move started offground or ended onground
// move down
vector downmove = '0 0 1' * (-PHYS_STEPHEIGHT + start_velocity.z * dt);
- if (!_Movetype_PushEntity(downmove, true))
+ vector prev_origin = self.move_origin;
+ _Movetype_PushEntity(downmove, true);
+ if(wasfreed(self))
+ return;
+
+ if(trace_startsolid && self.move_origin != prev_origin)
{
// we got teleported when downstepping... must abort the move
return;
#ifdef SVQC
/** flags origin [team displayrule] [spritename] [spritename2] [spritename3] [lifetime maxdistance hideable] */
float WaypointSprite_SendEntity(entity to, float sendflags)
-{
+{SELFPARAM();
WriteMutator(MSG_ENTITY, waypointsprites);
sendflags = sendflags & 0x7F;
}
void Ent_RemoveWaypointSprite()
-{
+{SELFPARAM();
if (self.netname) strunzone(self.netname);
if (self.netname2) strunzone(self.netname2);
if (self.netname3) strunzone(self.netname3);
/** flags origin [team displayrule] [spritename] [spritename2] [spritename3] [lifetime maxdistance hideable] */
void Ent_WaypointSprite()
-{
+{SELFPARAM();
int sendflags = ReadByte();
self.wp_extra = ReadByte();
#ifdef CSQC
float spritelookupblinkvalue(string s)
-{
+{SELFPARAM();
if (s == WP_Weapon.netname) {
if (get_weaponinfo(self.wp_extra).spawnflags & WEP_FLAG_SUPERWEAPON)
return 2;
}
if (s == WP_Item.netname) return ITEMS[self.wp_extra].m_waypointblink;
- switch (s)
- {
- case "item-invis": return 2;
- case "item-extralife": return 2;
- case "item-speed": return 2;
- default: return 1;
- }
+ return 1;
}
vector spritelookupcolor(string s, vector def)
-{
+{SELFPARAM();
if (s == WP_Weapon.netname) return get_weaponinfo(self.wp_extra).wpcolor;
if (s == WP_Item.netname) return ITEMS[self.wp_extra].m_color;
if (s == WP_Buff.netname) return BUFFS[self.wp_extra].m_color;
}
string spritelookuptext(string s)
-{
+{SELFPARAM();
if (s == WP_RaceStartFinish.netname) return (race_checkpointtime || race_mycheckpointtime) ? _("Finish") : _("Start");
if (s == WP_Weapon.netname) return get_weaponinfo(self.wp_extra).message;
if (s == WP_Item.netname) return ITEMS[self.wp_extra].m_waypoint;
return it.m_name;
));
- switch (s)
- {
- case "item-invis": return _("Invisibility");
- case "item-extralife": return _("Extra life");
- case "item-speed": return _("Speed");
- default: return s;
- }
+ return s;
}
#endif
}
void Draw_WaypointSprite()
-{
+{SELFPARAM();
if (self.lifetime)
self.alpha = pow(bound(0, (self.fadetime - time) / self.lifetime, 1), waypointsprite_timealphaexponent);
else
}
void WaypointSprite_Think()
-{
+{SELFPARAM();
bool doremove = false;
if (self.fade_time && time >= self.teleport_time)
}
float WaypointSprite_visible_for_player(entity e)
-{
+{SELFPARAM();
// personal waypoints
if (self.enemy && self.enemy != e)
return false;
}
float WaypointSprite_Customize()
-{
+{SELFPARAM();
// this is not in SendEntity because it shall run every frame, not just every update
// make spectators see what the player would see
float WaypointSprite_SendEntity(entity to, float sendflags);
void WaypointSprite_Reset()
-{
+{SELFPARAM();
// if a WP wants to time out, let it time out immediately; other WPs ought to be reset/killed by their owners
if (self.fade_time) // there was there before: || g_keyhunt, do we really need this?
vector ofs,
float icon // initial icon
)
-{
+{SELFPARAM();
float t;
if (teamplay)
t = self.team;
vector ofs,
float icon // initial icon
)
-{
+{SELFPARAM();
return WaypointSprite_Spawn(spr, 0, 0, world, ofs, world, 0, self, waypointsprite_deployed_personal, false, icon);
}
float limited_range,
float icon // initial icon
)
-{
+{SELFPARAM();
float t;
if (self.waypointsprite_attachedforcarrier)
return world; // can't attach to FC
}
void WaypointSprite_ClearPersonal()
-{
+{SELFPARAM();
WaypointSprite_Kill(self.waypointsprite_deployed_personal);
}
void WaypointSprite_ClearOwned()
-{
+{SELFPARAM();
WaypointSprite_Kill(self.waypointsprite_deployed_fixed);
WaypointSprite_Kill(self.waypointsprite_deployed_personal);
WaypointSprite_Kill(self.waypointsprite_attached);
}
void WaypointSprite_PlayerDead()
-{
+{SELFPARAM();
WaypointSprite_Disown(self.waypointsprite_attached, waypointsprite_deadlifetime);
WaypointSprite_DetachCarrier(self);
}
void WaypointSprite_PlayerGone()
-{
+{SELFPARAM();
WaypointSprite_Disown(self.waypointsprite_deployed_fixed, waypointsprite_deadlifetime);
WaypointSprite_Kill(self.waypointsprite_deployed_personal);
WaypointSprite_Disown(self.waypointsprite_attached, waypointsprite_deadlifetime);
#include "../../common/items/all.qc"
- void spawnfunc_item_minst_cells (void)
+ void spawnfunc_item_minst_cells()
-{
+{SELFPARAM();
if (!g_instagib) { remove(self); return; }
- if (!self.ammo_cells)
- self.ammo_cells = autocvar_g_instagib_ammo_drop;
+ if (!self.ammo_cells) self.ammo_cells = autocvar_g_instagib_ammo_drop;
+ StartItemA(ITEM_VaporizerCells);
+ }
- StartItemA (ITEM_VaporizerCells);
+ void instagib_invisibility()
+ {
+ self.strength_finished = autocvar_g_balance_powerup_strength_time;
+ StartItemA(ITEM_Invisibility);
}
- void instagib_health_mega()
+ void instagib_extralife()
-{
+{SELFPARAM();
self.max_health = 1;
- StartItemA (ITEM_ExtraLife);
+ StartItemA(ITEM_ExtraLife);
+ }
+
+ void instagib_speed()
+ {
+ self.invincible_finished = autocvar_g_balance_powerup_invincible_time;
+ StartItemA(ITEM_Speed);
}
.float instagib_nextthink;
e.instagib_needammo = false;
}
void instagib_ammocheck()
-{
+{SELFPARAM();
if(time < self.instagib_nextthink)
return;
if(!IS_PLAYER(self))
}
MUTATOR_HOOKFUNCTION(instagib_MonsterSpawn)
-{
+{SELFPARAM();
// always refill ammo
if(self.monsterid == MON_MAGE.monsterid)
self.skin = 1;
MUTATOR_HOOKFUNCTION(instagib_BotShouldAttack)
{
- if(checkentity.items & ITEM_Strength.m_itemid)
+ if (checkentity.items & ITEM_Invisibility.m_itemid)
return true;
return false;
}
MUTATOR_HOOKFUNCTION(instagib_MakePlayerObserver)
-{
+{SELFPARAM();
instagib_stop_countdown(self);
return false;
}
MUTATOR_HOOKFUNCTION(instagib_PlayerSpawn)
-{
+{SELFPARAM();
self.effects |= EF_FULLBRIGHT;
return false;
}
}
MUTATOR_HOOKFUNCTION(instagib_PlayerPowerups)
-{
+{SELFPARAM();
if (!(self.effects & EF_FULLBRIGHT))
self.effects |= EF_FULLBRIGHT;
- if (self.items & ITEM_Strength.m_itemid)
+ if (self.items & ITEM_Invisibility.m_itemid)
{
play_countdown(self.strength_finished, "misc/poweroff.wav");
if (time > self.strength_finished)
{
self.alpha = default_player_alpha;
self.exteriorweaponentity.alpha = default_weapon_alpha;
- self.items &= ~ITEM_Strength.m_itemid;
+ self.items &= ~ITEM_Invisibility.m_itemid;
Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERDOWN_INVISIBILITY);
}
}
{
self.alpha = autocvar_g_instagib_invis_alpha;
self.exteriorweaponentity.alpha = autocvar_g_instagib_invis_alpha;
- self.items |= ITEM_Strength.m_itemid;
+ self.items |= ITEM_Invisibility.m_itemid;
Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERUP_INVISIBILITY, self.netname);
Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERUP_INVISIBILITY);
}
}
- if (self.items & ITEM_Shield.m_itemid)
+ if (self.items & ITEM_Speed.m_itemid)
{
play_countdown(self.invincible_finished, "misc/poweroff.wav");
if (time > self.invincible_finished)
{
- self.items &= ~ITEM_Shield.m_itemid;
+ self.items &= ~ITEM_Speed.m_itemid;
Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERDOWN_SPEED);
}
}
{
if (time < self.invincible_finished)
{
- self.items |= ITEM_Shield.m_itemid;
+ self.items |= ITEM_Speed.m_itemid;
Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERUP_SPEED, self.netname);
Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERUP_SPEED);
}
}
MUTATOR_HOOKFUNCTION(instagib_PlayerPhysics)
-{
+{SELFPARAM();
- if(self.items & ITEM_Shield.m_itemid)
+ if(self.items & ITEM_Speed.m_itemid)
self.stat_sv_maxspeed = self.stat_sv_maxspeed * autocvar_g_instagib_speed_highspeed;
return false;
frag_mirrordamage = 0;
}
- if((frag_target.buffs & BUFF_INVISIBLE.m_itemid) || (frag_target.items & ITEM_Strength.m_itemid))
+ if((frag_target.buffs & BUFF_INVISIBLE.m_itemid) || (frag_target.items & ITEM_Invisibility.m_itemid))
yoda = 1;
return false;
}
MUTATOR_HOOKFUNCTION(instagib_FilterItem)
-{
+{SELFPARAM();
if(self.classname == "item_cells")
return true; // no normal cells?
if(self.weapon == WEP_DEVASTATOR.m_id || self.weapon == WEP_VORTEX.m_id)
{
- entity e = spawn(), oldself;
+ entity e = spawn();
setorigin(e, self.origin);
- oldself = self;
- self = e;
- self.noalign = oldself.noalign;
- self.cnt = oldself.cnt;
- self.team = oldself.team;
- spawnfunc_item_minst_cells();
- self = oldself;
+ e.noalign = self.noalign;
+ e.cnt = self.cnt;
+ e.team = self.team;
+ WITH(entity, self, e, spawnfunc_item_minst_cells());
return true;
}
}
MUTATOR_HOOKFUNCTION(instagib_CustomizeWaypoint)
-{
+{SELFPARAM();
entity e = WaypointSprite_getviewentity(other);
// if you have the invisibility powerup, sprites ALWAYS are restricted to your team
// but only apply this to real players, not to spectators
- if((self.owner.flags & FL_CLIENT) && (self.owner.items & ITEM_Strength.m_itemid) && (e == other))
+ if((self.owner.flags & FL_CLIENT) && (self.owner.items & ITEM_Invisibility.m_itemid) && (e == other))
if(DIFF_TEAM(self.owner, e))
return true;
return false;
}
- MUTATOR_HOOKFUNCTION(instagib_ItemCountdown)
- {SELFPARAM();
- switch (self.items)
- {
- case ITEM_Strength.m_itemid: item_name = "item-invis"; item_color = '0 0 1'; break;
- case ITEM_ExtraLife.m_itemid: item_name = "item-extralife"; item_color = '1 0 0'; break;
- case ITEM_Shield.m_itemid: item_name = "item-speed"; item_color = '1 0 1'; break;
- }
- return false;
- }
-
MUTATOR_HOOKFUNCTION(instagib_PlayerDies)
{
if(DEATH_ISWEAPON(frag_deathtype, WEP_VAPORIZER.m_id))
}
MUTATOR_HOOKFUNCTION(instagib_ItemTouch)
-{
+{SELFPARAM();
if(self.ammo_cells)
{
// play some cool sounds ;)
}
MUTATOR_HOOKFUNCTION(instagib_OnEntityPreSpawn)
-{
+{SELFPARAM();
if (!autocvar_g_powerups) { return false; }
- if (!(self.classname == "item_strength" || self.classname == "item_invincible" || self.itemdef == ITEM_HealthMega))
+ // Can't use .itemdef here
+ if (!(self.classname == "item_strength" || self.classname == "item_invincible" || self.classname == "item_health_mega"))
return false;
entity e = spawn();
- if(random() < 0.3)
- e.think = spawnfunc_item_strength;
- else if(random() < 0.6)
- e.think = instagib_health_mega;
+ float r = random();
+ if (r < 0.3)
+ e.think = instagib_invisibility;
+ else if (r < 0.6)
+ e.think = instagib_extralife;
else
- e.think = spawnfunc_item_invincible;
+ e.think = instagib_speed;
e.nextthink = time + 0.1;
e.spawnflags = self.spawnflags;
MUTATOR_HOOK(ItemTouch, instagib_ItemTouch, CBC_ORDER_ANY);
MUTATOR_HOOK(FilterItem, instagib_FilterItem, CBC_ORDER_ANY);
MUTATOR_HOOK(CustomizeWaypoint, instagib_CustomizeWaypoint, CBC_ORDER_ANY);
- MUTATOR_HOOK(Item_RespawnCountdown, instagib_ItemCountdown, CBC_ORDER_ANY);
MUTATOR_HOOK(PlayerDies, instagib_PlayerDies, CBC_ORDER_ANY);
MUTATOR_HOOK(PlayerDamage_SplitHealthArmor, instagib_SplitHealthArmor, CBC_ORDER_ANY);
MUTATOR_HOOK(PlayerPowerups, instagib_PlayerPowerups, CBC_ORDER_ANY);