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