2 REGISTER_NET_LINKED(ENT_CLIENT_LADDER)
4 void func_ladder_touch(entity this, entity toucher)
7 if (!toucher.iscreature)
9 if(IS_VEHICLE(toucher))
12 if(!toucher.isplayermodel)
16 EXACTTRIGGER_TOUCH(this, toucher);
18 toucher.ladder_time = time + 0.1;
19 toucher.ladder_entity = this;
23 bool func_ladder_send(entity this, entity to, int sf)
25 WriteHeader(MSG_ENTITY, ENT_CLIENT_LADDER);
27 WriteString(MSG_ENTITY, this.classname);
28 WriteByte(MSG_ENTITY, this.skin);
29 WriteCoord(MSG_ENTITY, this.speed);
31 trigger_common_write(this, false);
36 void func_ladder_link(entity this)
38 trigger_link(this, func_ladder_send);
39 //this.model = "null";
42 void func_ladder_init(entity this)
44 settouch(this, func_ladder_touch);
46 func_ladder_link(this);
48 if(min(this.absmax.x - this.absmin.x, this.absmax.y - this.absmin.y) > 100)
51 entity tracetest_ent = spawn();
52 setsize(tracetest_ent, PL_MIN_CONST, PL_MAX_CONST);
53 tracetest_ent.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP;
55 vector top_min = (this.absmin + this.absmax) / 2;
56 top_min.z = this.absmax.z;
57 vector top_max = top_min;
58 top_max.z += PL_MAX_CONST.z - PL_MIN_CONST.z;
59 tracebox(top_max + jumpstepheightvec, PL_MIN_CONST, PL_MAX_CONST, top_min, MOVE_NOMONSTERS, tracetest_ent);
62 tracebox(top_max + stepheightvec, PL_MIN_CONST, PL_MAX_CONST, top_min, MOVE_NOMONSTERS, tracetest_ent);
65 tracebox(top_max, PL_MIN_CONST, PL_MAX_CONST, top_min, MOVE_NOMONSTERS, tracetest_ent);
68 if(this.absmax.x - this.absmin.x > PL_MAX_CONST.x - PL_MIN_CONST.x
69 && this.absmax.y - this.absmin.y < this.absmax.x - this.absmin.x)
71 // move top on one side
72 top_max.y = top_min.y = this.absmin.y + (PL_MAX_CONST.y - PL_MIN_CONST.y) * 0.75;
74 else if(this.absmax.y - this.absmin.y > PL_MAX_CONST.y - PL_MIN_CONST.y
75 && this.absmax.x - this.absmin.x < this.absmax.y - this.absmin.y)
77 // move top on one side
78 top_max.x = top_min.x = this.absmin.x + (PL_MAX_CONST.x - PL_MIN_CONST.x) * 0.75;
80 tracebox(top_max, PL_MIN_CONST, PL_MAX_CONST, top_min, MOVE_NOMONSTERS, tracetest_ent);
83 if(this.absmax.x - this.absmin.x > PL_MAX_CONST.x - PL_MIN_CONST.x
84 && this.absmax.y - this.absmin.y < this.absmax.x - this.absmin.x)
86 // alternatively on the other side
87 top_max.y = top_min.y = this.absmax.y - (PL_MAX_CONST.y - PL_MIN_CONST.y) * 0.75;
89 else if(this.absmax.y - this.absmin.y > PL_MAX_CONST.y - PL_MIN_CONST.y
90 && this.absmax.x - this.absmin.x < this.absmax.y - this.absmin.y)
92 // alternatively on the other side
93 top_max.x = top_min.x = this.absmax.x - (PL_MAX_CONST.x - PL_MIN_CONST.x) * 0.75;
95 tracebox(top_max, PL_MIN_CONST, PL_MAX_CONST, top_min, MOVE_NOMONSTERS, tracetest_ent);
100 if(trace_startsolid || trace_endpos.z < this.absmax.z)
102 delete(tracetest_ent);
106 this.bot_pickup = true; // allow bots to make use of this ladder
107 float cost = waypoint_getlinearcost(trace_endpos.z - this.absmin.z);
108 top_min = trace_endpos;
109 waypoint_spawnforteleporter_boxes(this, WAYPOINTFLAG_LADDER, this.absmin, this.absmax, top_min, top_min, cost);
112 spawnfunc(func_ladder)
114 IL_PUSH(g_ladders, this); // TODO: also func_water? bots currently loop through func_ladder only
116 func_ladder_init(this);
119 spawnfunc(func_water)
121 func_ladder_init(this);
127 void func_ladder_remove(entity this)
129 strfree(this.classname);
132 NET_HANDLE(ENT_CLIENT_LADDER, bool isnew)
134 this.classname = strzone(ReadString());
135 this.skin = ReadByte();
136 this.speed = ReadCoord();
138 trigger_common_read(this, false);
140 this.solid = SOLID_TRIGGER;
141 settouch(this, func_ladder_touch);
142 this.drawmask = MASK_NORMAL;
143 this.move_time = time;
144 this.entremove = func_ladder_remove;