]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/pathlib/movenode.qc
Merge branch 'master' into terencehill/lms_updates
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / pathlib / movenode.qc
1 #include "movenode.qh"
2
3 #include <common/mapobjects/triggers.qh>
4 #include <common/stats.qh>
5 #include <common/weapons/_all.qh>
6 #include <server/pathlib/pathlib.qh>
7 #include <server/pathlib/utility.qh>
8
9 .vector pos1, pos2;
10
11 vector pathlib_wateroutnode(entity this, vector start, vector end, float doedge)
12 {
13     vector surface;
14
15     pathlib_movenode_goodnode = false;
16
17     end.x = fsnap(end.x, pathlib_gridsize);
18     end.y = fsnap(end.y, pathlib_gridsize);
19
20     traceline(end + ('0 0 0.25' * pathlib_gridsize),end - ('0 0 1' * pathlib_gridsize),MOVE_WORLDONLY,this);
21     end = trace_endpos;
22
23     if (!(pointcontents(end - '0 0 1') == CONTENT_SOLID))
24         return end;
25
26     for(surface = start ; surface.z < (end.z + 32); ++surface.z)
27     {
28         if(pointcontents(surface) == CONTENT_EMPTY)
29             break;
30     }
31
32     if(pointcontents(surface + '0 0 1') != CONTENT_EMPTY)
33         return end;
34
35     tracebox(start + '0 0 64', movenode_boxmin,movenode_boxmax, end + '0 0 64', MOVE_WORLDONLY, this);
36     if(trace_fraction == 1)
37         pathlib_movenode_goodnode = true;
38
39     if(fabs(surface.z - end.z) > 32)
40         pathlib_movenode_goodnode = false;
41
42     return end;
43 }
44
45 vector pathlib_swimnode(entity this, vector start, vector end, float doedge)
46 {
47     pathlib_movenode_goodnode = false;
48
49     if(pointcontents(start) != CONTENT_WATER)
50         return end;
51
52     end.x = fsnap(end.x, pathlib_gridsize);
53     end.y = fsnap(end.y, pathlib_gridsize);
54
55     if(pointcontents(end) == CONTENT_EMPTY)
56         return pathlib_wateroutnode(this, start, end, doedge);
57
58     tracebox(start, movenode_boxmin,movenode_boxmax, end, MOVE_WORLDONLY, this);
59     if(trace_fraction == 1)
60         pathlib_movenode_goodnode = true;
61
62     return end;
63 }
64
65 vector pathlib_flynode(entity this, vector start, vector end, float doedge)
66 {
67     pathlib_movenode_goodnode = false;
68
69     end.x = fsnap(end.x, pathlib_gridsize);
70     end.y = fsnap(end.y, pathlib_gridsize);
71
72     tracebox(start, movenode_boxmin,movenode_boxmax, end, MOVE_WORLDONLY, this);
73     if(trace_fraction == 1)
74         pathlib_movenode_goodnode = true;
75
76     return end;
77 }
78
79 void a_think(entity this)
80 {
81     te_lightning1(this,this.origin, this.pos1);
82     if(this.cnt < time)
83         delete(this);
84     else
85         this.nextthink = time + 0.2;
86 }
87
88 vector pathlib_walknode(entity this, vector start, vector end, float doedge)
89 {
90     vector point;
91
92     LOG_DEBUG("Walking node from ", vtos(start), " to ", vtos(end));
93
94     pathlib_movenode_goodnode = false;
95
96     end.x = fsnap(end.x,pathlib_gridsize);
97     end.y = fsnap(end.y,pathlib_gridsize);
98     start.x = fsnap(start.x,pathlib_gridsize);
99     start.y = fsnap(start.y,pathlib_gridsize);
100
101     // Find the floor
102     traceline(start + movenode_stepup, start - movenode_maxdrop, MOVE_WORLDONLY, this);
103     if(trace_fraction == 1.0)
104     {
105         entity a;
106         a = spawn();
107         setthink(a, a_think);
108         a.nextthink = time;
109         setorigin(a, start + movenode_stepup);
110         a.pos1 = trace_endpos;
111         //start - movenode_maxdrop
112         a.cnt = time + 10;
113
114         LOG_TRACE("I cant walk on air!");
115         return trace_endpos;
116     }
117
118     start = trace_endpos;
119
120     // Find the direcion, without Z
121     vector s   = start;
122     vector e   = end;
123     //e_z = 0; s_z = 0;
124     vector direction = normalize(e - s);
125
126     float distance  = vlen(start - end);
127     int steps     = rint(distance / movenode_stepsize);
128
129     vector last_point = start;
130     for(int i = 1; i < steps; ++i)
131     {
132         point = last_point + (direction * movenode_stepsize);
133         traceline(point + movenode_stepup,point - movenode_maxdrop,MOVE_WORLDONLY,this);
134         if(trace_fraction == 1.0)
135             return trace_endpos;
136
137         last_point = trace_endpos;
138     }
139
140     point = last_point + (direction * movenode_stepsize);
141     point.x = fsnap(point.x,pathlib_gridsize);
142     point.y = fsnap(point.y,pathlib_gridsize);
143
144     //dprint("end_x:  ",ftos(end_x),  "  end_y:  ",ftos(end_y),"\n");
145     //dprint("point_x:",ftos(point_x),"  point_y:",ftos(point_y),"\n\n");
146
147     traceline(point + movenode_stepup, point - movenode_maxdrop,MOVE_WORLDONLY,this);
148     if(trace_fraction == 1.0)
149         return trace_endpos;
150
151     last_point = trace_endpos;
152
153     tracebox(start + movenode_boxup, movenode_boxmin,movenode_boxmax, last_point + movenode_boxup, MOVE_WORLDONLY, this);
154     if(trace_fraction != 1.0)
155         return trace_endpos;
156
157     pathlib_movenode_goodnode = true;
158     return last_point;
159 }