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