]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/common/triggers/func/ladder.qc
Merge branch 'master' into terencehill/bot_waypoints
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / triggers / func / ladder.qc
index c27dd2ce08604e576c642d855d03fbbc2af67a67..92f361a145c098c56efa037cc3b9ede05b3a9a4f 100644 (file)
-void func_ladder_touch()
-{SELFPARAM();
+#include "ladder.qh"
+REGISTER_NET_LINKED(ENT_CLIENT_LADDER)
+
+void func_ladder_touch(entity this, entity toucher)
+{
 #ifdef SVQC
-       if (!other.iscreature)
+       if (!toucher.iscreature)
                return;
-       if(IS_VEHICLE(other))
+       if(IS_VEHICLE(toucher))
                return;
-#endif
-#ifdef CSQC
-       if(other.classname != "csqcmodel")
+#elif defined(CSQC)
+       if(!toucher.isplayermodel)
                return;
 #endif
 
-       EXACTTRIGGER_TOUCH;
+       EXACTTRIGGER_TOUCH(this, toucher);
 
-       other.ladder_time = time + 0.1;
-       other.ladder_entity = self;
+       toucher.ladder_time = time + 0.1;
+       toucher.ladder_entity = this;
 }
 
 #ifdef SVQC
-bool func_ladder_send(entity this, entity to, float sf)
+bool func_ladder_send(entity this, entity to, int sf)
 {
-       WriteByte(MSG_ENTITY, ENT_CLIENT_LADDER);
+       WriteHeader(MSG_ENTITY, ENT_CLIENT_LADDER);
 
-       WriteString(MSG_ENTITY, self.classname);
-       WriteByte(MSG_ENTITY, self.skin);
-       WriteByte(MSG_ENTITY, self.speed);
-       WriteString(MSG_ENTITY, self.mdl);
+       WriteString(MSG_ENTITY, this.classname);
+       WriteByte(MSG_ENTITY, this.skin);
+       WriteCoord(MSG_ENTITY, this.speed);
 
-       trigger_common_write(false);
+       trigger_common_write(this, false);
 
        return true;
 }
 
-void func_ladder_link()
+void func_ladder_link(entity this)
 {
-       //self.SendEntity = func_ladder_send;
-       //self.SendFlags = 0xFFFFFF;
-       //self.model = "null";
+       trigger_link(this, func_ladder_send);
+       //this.model = "null";
+}
+
+void func_ladder_init(entity this)
+{
+       settouch(this, func_ladder_touch);
+       trigger_init(this);
+       func_ladder_link(this);
+
+       if(min(this.absmax.x - this.absmin.x, this.absmax.y - this.absmin.y) > 100)
+               return;
+
+       entity tracetest_ent = spawn();
+       setsize(tracetest_ent, PL_MIN_CONST, PL_MAX_CONST);
+       tracetest_ent.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP;
+
+       vector top_min = (this.absmin + this.absmax) / 2;
+       top_min.z = this.absmax.z;
+       vector top_max = top_min;
+       top_max.z += PL_MAX_CONST.z - PL_MIN_CONST.z;
+       tracebox(top_max + jumpstepheightvec, PL_MIN_CONST, PL_MAX_CONST, top_min, MOVE_NOMONSTERS, tracetest_ent);
+       if(trace_startsolid)
+       {
+               tracebox(top_max + stepheightvec, PL_MIN_CONST, PL_MAX_CONST, top_min, MOVE_NOMONSTERS, tracetest_ent);
+               if(trace_startsolid)
+               {
+                       tracebox(top_max, PL_MIN_CONST, PL_MAX_CONST, top_min, MOVE_NOMONSTERS, tracetest_ent);
+                       if(trace_startsolid)
+                       {
+                               if(this.absmax.x - this.absmin.x > PL_MAX_CONST.x - PL_MIN_CONST.x
+                                       && this.absmax.y - this.absmin.y < this.absmax.x - this.absmin.x)
+                               {
+                                       // move top on one side
+                                       top_max.y = top_min.y = this.absmin.y + (PL_MAX_CONST.y - PL_MIN_CONST.y) * 0.75;
+                               }
+                               else if(this.absmax.y - this.absmin.y > PL_MAX_CONST.y - PL_MIN_CONST.y
+                                       && this.absmax.x - this.absmin.x < this.absmax.y - this.absmin.y)
+                               {
+                                       // move top on one side
+                                       top_max.x = top_min.x = this.absmin.x + (PL_MAX_CONST.x - PL_MIN_CONST.x) * 0.75;
+                               }
+                               tracebox(top_max, PL_MIN_CONST, PL_MAX_CONST, top_min, MOVE_NOMONSTERS, tracetest_ent);
+                               if(trace_startsolid)
+                               {
+                                       if(this.absmax.x - this.absmin.x > PL_MAX_CONST.x - PL_MIN_CONST.x
+                                               && this.absmax.y - this.absmin.y < this.absmax.x - this.absmin.x)
+                                       {
+                                               // alternatively on the other side
+                                               top_max.y = top_min.y = this.absmax.y - (PL_MAX_CONST.y - PL_MIN_CONST.y) * 0.75;
+                                       }
+                                       else if(this.absmax.y - this.absmin.y > PL_MAX_CONST.y - PL_MIN_CONST.y
+                                               && this.absmax.x - this.absmin.x < this.absmax.y - this.absmin.y)
+                                       {
+                                               // alternatively on the other side
+                                               top_max.x = top_min.x = this.absmax.x - (PL_MAX_CONST.x - PL_MIN_CONST.x) * 0.75;
+                                       }
+                                       tracebox(top_max, PL_MIN_CONST, PL_MAX_CONST, top_min, MOVE_NOMONSTERS, tracetest_ent);
+                               }
+                       }
+               }
+       }
+       if(trace_startsolid || trace_endpos.z < this.absmax.z)
+       {
+               delete(tracetest_ent);
+               return;
+       }
+
+       this.bot_pickup = true; // allow bots to make use of this ladder
+       float cost = waypoint_getlinearcost(trace_endpos.z - this.absmin.z);
+       top_min = trace_endpos;
+       waypoint_spawnforteleporter_boxes(this, WAYPOINTFLAG_LADDER, this.absmin, this.absmax, top_min, top_min, cost);
 }
 
 spawnfunc(func_ladder)
 {
-       self.mdl = self.model;
-       EXACTTRIGGER_INIT;
-       self.touch = func_ladder_touch;
+       IL_PUSH(g_ladders, this); // TODO: also func_water? bots currently loop through func_ladder only
 
-       func_ladder_link();
+       func_ladder_init(this);
 }
 
 spawnfunc(func_water)
 {
-       self.mdl = self.model;
-       EXACTTRIGGER_INIT;
-       self.touch = func_ladder_touch;
-
-       func_ladder_link();
+       func_ladder_init(this);
 }
 
 #elif defined(CSQC)
 .float speed;
 
-void ent_func_ladder()
-{SELFPARAM();
-       self.classname = strzone(ReadString());
-       self.skin = ReadByte();
-       self.speed = ReadByte();
-       self.model = strzone(ReadString());
-
-       trigger_common_read(false);
-       self.mins = self.maxs = '0 0 0';
-
-       self.solid = SOLID_TRIGGER;
-       self.draw = trigger_draw_generic;
-       self.trigger_touch = func_ladder_touch;
-       self.drawmask = MASK_NORMAL;
-       self.move_time = time;
-       self.entremove = trigger_remove_generic;
-
-       //precache_model(self.mdl);
-       EXACTTRIGGER_INIT;
+void func_ladder_remove(entity this)
+{
+       if(this.classname) { strunzone(this.classname); }
+       this.classname = string_null;
+}
+
+NET_HANDLE(ENT_CLIENT_LADDER, bool isnew)
+{
+       this.classname = strzone(ReadString());
+       this.skin = ReadByte();
+       this.speed = ReadCoord();
+
+       trigger_common_read(this, false);
+
+       this.solid = SOLID_TRIGGER;
+       settouch(this, func_ladder_touch);
+       this.drawmask = MASK_NORMAL;
+       this.move_time = time;
+       this.entremove = func_ladder_remove;
+
+       return true;
 }
 #endif