#include "ladder.qh"
REGISTER_NET_LINKED(ENT_CLIENT_LADDER)
-void func_ladder_touch(entity this, entity toucher)
+void func_ladder_think(entity this)
{
-#ifdef SVQC
- if (!toucher.iscreature)
- return;
- if(IS_VEHICLE(toucher))
- return;
-#elif defined(CSQC)
- if(!IS_PLAYER(toucher)) // don't allow non-player predicted entities!
- return;
+#ifdef CSQC
+ // TODO: check if this is what is causing the glitchiness when switching between them
+ float dt = time - this.move_time;
+ this.move_time = time;
+ if(dt <= 0) { return; }
#endif
- EXACTTRIGGER_TOUCH(this, toucher);
+ // set myself as current ladders where possible
+ IL_EACH(g_ladderents, it.ladder_entity == this,
+ {
+ it.ladder_entity = NULL;
+ IL_REMOVE(g_ladderents, it);
+ });
- toucher.ladder_time = time + 0.1;
- toucher.ladder_entity = this;
+ FOREACH_ENTITY_RADIUS((this.absmin + this.absmax) * 0.5, vlen(this.absmax - this.absmin) * 0.5 + 1, !it.ladder_entity && IS_PLAYER(it) && it.move_movetype != MOVETYPE_NOCLIP && !IS_DEAD(it),
+ {
+ vector emin = it.absmin;
+ vector emax = it.absmax;
+ if(this.solid == SOLID_BSP || (IS_CSQC && this.solid == SOLID_TRIGGER)) // CSQC doesn't expand properly
+ {
+ emin -= '1 1 1';
+ emax += '1 1 1';
+ }
+ if(boxesoverlap(emin, emax, this.absmin, this.absmax)) // quick
+ {
+ if(WarpZoneLib_BoxTouchesBrush(emin, emax, this, it)) // accurate
+ {
+ if(!it.ladder_entity)
+ IL_PUSH(g_ladderents, it);
+ it.ladder_entity = this;
+ }
+ }
+ });
+
+#ifdef SVQC
+ this.nextthink = time;
+#endif
}
#ifdef SVQC
void func_ladder_init(entity this)
{
- settouch(this, func_ladder_touch);
trigger_init(this);
func_ladder_link(this);
+ setthink(this, func_ladder_think);
+ this.nextthink = time;
if(min(this.absmax.x - this.absmin.x, this.absmax.y - this.absmin.y) > 100)
return;
#elif defined(CSQC)
.float speed;
+void func_ladder_draw(entity this) { func_ladder_think(this); }
+
void func_ladder_remove(entity this)
{
+ IL_EACH(g_ladderents, it.ladder_entity == this,
+ {
+ it.ladder_entity = NULL;
+ IL_REMOVE(g_ladderents, it);
+ });
strfree(this.classname);
}
this.classname = strzone(ReadString());
this.skin = ReadByte();
this.speed = ReadCoord();
+ this.solid = SOLID_TRIGGER;
trigger_common_read(this, false);
- this.solid = SOLID_TRIGGER;
- settouch(this, func_ladder_touch);
+ if(isnew)
+ IL_PUSH(g_drawables, this);
+ this.draw = func_ladder_draw;
this.drawmask = MASK_NORMAL;
+
this.move_time = time;
this.entremove = func_ladder_remove;
+ // NOTE: CSQC's version of setorigin doesn't expand
+ this.absmin -= '1 1 1';
+ this.absmax += '1 1 1';
+
return true;
}
#endif
vector old_movement = PHYS_CS(this).movement;
PHYS_CS(this).movement_x = old_movement_y;
- if((this.viewloc.spawnflags & VIEWLOC_FREEMOVE) && !(time < this.ladder_time))
+ if((this.viewloc.spawnflags & VIEWLOC_FREEMOVE) && !this.ladder_entity)
PHYS_CS(this).movement_y = old_movement_x;
else
PHYS_CS(this).movement_y = 0;
vector forward = vectoangles(normalize(level_end - level_start));
vector backward = vectoangles(normalize(level_start - level_end));
- if((this.viewloc.spawnflags & VIEWLOC_FREEMOVE) && this.angles_y < 0 && !(time < this.ladder_time))
+ if((this.viewloc.spawnflags & VIEWLOC_FREEMOVE) && this.angles_y < 0 && !this.ladder_entity)
PHYS_CS(this).movement_y = -PHYS_CS(this).movement_y;
if(this.viewloc.spawnflags & VIEWLOC_FREEAIM)
#include <common/effects/qc/globalsound.qh>
#include "../common/mapobjects/func/conveyor.qh"
+#include <common/mapobjects/func/ladder.qh>
#include "../common/mapobjects/teleporters.qh"
#include "../common/mapobjects/target/spawnpoint.qh"
#include <common/mapobjects/trigger/counter.qh>
IL_REMOVE(g_swamped, this);
this.swampslug = NULL;
this.swamp_interval = 0;
+ if(this.ladder_entity)
+ IL_REMOVE(g_ladderents, this);
+ this.ladder_entity = NULL;
IL_EACH(g_counters, it.realowner == this,
{
delete(it);