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