]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/triggers/trigger/viewloc.qc
Merge branch 'master' into Mario/triggers
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / triggers / trigger / viewloc.qc
1 #if defined(CSQC)
2 #elif defined(MENUQC)
3 #elif defined(SVQC)
4         #include "../../../dpdefs/progsdefs.qh"
5     #include "../../../warpzonelib/util_server.qh"
6     #include "../../../server/defs.qh"
7 #endif
8
9 #ifdef SVQC
10
11 void viewloc_think()
12 {
13         entity e;
14
15         // set myself as current viewloc where possible
16         for(e = world; (e = findentity(e, viewloc, self)); )
17                 e.viewloc = world;
18
19                 for(e = findradius((self.absmin + self.absmax) * 0.5, vlen(self.absmax - self.absmin) * 0.5 + 1); e; e = e.chain)
20                         if(!e.viewloc)
21                                 if(IS_PLAYER(e)) // should we support non-player entities with this?
22                                 //if(e.deadflag == DEAD_NO) // death view is handled separately, we can't override this just yet
23                                 {
24                                         vector emin = e.absmin;
25                                         vector emax = e.absmax;
26                                         if(self.solid == SOLID_BSP)
27                                         {
28                                                 emin -= '1 1 1';
29                                                 emax += '1 1 1';
30                                         }
31                                         if(boxesoverlap(emin, emax, self.absmin, self.absmax)) // quick
32                                                 if(WarpZoneLib_BoxTouchesBrush(emin, emax, self, e)) // accurate
33                                                         e.viewloc = self;
34                                 }
35
36         self.nextthink = time;
37 }
38
39 bool trigger_viewloc_send(entity to, int sf)
40 {
41         // CSQC doesn't need to know our origin (yet), as we're only available for referencing
42         WriteByte(MSG_ENTITY, ENT_CLIENT_VIEWLOC_TRIGGER);
43
44         WriteEntity(MSG_ENTITY, self.enemy);
45         WriteEntity(MSG_ENTITY, self.goalentity);
46
47         WriteCoord(MSG_ENTITY, self.origin_x);
48         WriteCoord(MSG_ENTITY, self.origin_y);
49         WriteCoord(MSG_ENTITY, self.origin_z);
50
51         return true;
52 }
53
54 void viewloc_init()
55 {
56         entity e;
57         for(e = world; (e = find(e, targetname, self.target)); )
58                 if(e.classname == "target_viewlocation_start")
59                 {
60                         self.enemy = e;
61                         break;
62                 }
63         for(e = world; (e = find(e, targetname, self.target2)); )
64                 if(e.classname == "target_viewlocation_end")
65                 {
66                         self.goalentity = e;
67                         break;
68                 }
69
70         if(!self.enemy) { print("^1FAIL!\n"); remove(self); return; }
71
72         if(!self.goalentity)
73                 self.goalentity = self.enemy; // make them match so CSQC knows what to do
74
75         Net_LinkEntity(self, false, 0, trigger_viewloc_send);
76
77         self.think = viewloc_think;
78         self.nextthink = time;
79 }
80
81 void spawnfunc_trigger_viewlocation()
82 {
83         // we won't check target2 here yet, as it may not even need to exist
84         if(self.target == "") { print("^1FAIL!\n"); remove(self); return; }
85
86         EXACTTRIGGER_INIT;
87         InitializeEntity(self, viewloc_init, INITPRIO_FINDTARGET);
88 }
89
90 bool viewloc_send(entity to, int sf)
91 {
92         WriteByte(MSG_ENTITY, ENT_CLIENT_VIEWLOC);
93
94         WriteByte(MSG_ENTITY, self.cnt);
95
96         WriteCoord(MSG_ENTITY, self.origin_x);
97         WriteCoord(MSG_ENTITY, self.origin_y);
98         WriteCoord(MSG_ENTITY, self.origin_z);
99
100         WriteCoord(MSG_ENTITY, self.angles_x);
101         WriteCoord(MSG_ENTITY, self.angles_y);
102         WriteCoord(MSG_ENTITY, self.angles_z);
103
104         return true;
105 }
106
107 .float angle;
108 void viewloc_link()
109 {
110         if(self.angle)
111                 self.angles_y = self.angle;
112         Net_LinkEntity(self, false, 0, viewloc_send);
113 }
114
115 void spawnfunc_target_viewlocation_start()
116 {
117         self.classname = "target_viewlocation_start";
118         self.cnt = 1;
119         viewloc_link();
120 }
121 void spawnfunc_target_viewlocation_end()
122 {
123         self.classname = "target_viewlocation_end";
124         self.cnt = 2;
125         viewloc_link();
126 }
127
128 // compatibility
129 void spawnfunc_target_viewlocation() { spawnfunc_target_viewlocation_start(); }
130
131 #elif defined(CSQC)
132
133 void trigger_viewloc_updatelink()
134 {
135         self.enemy = findfloat(world, entnum, self.cnt);
136         self.goalentity = findfloat(world, entnum, self.count);
137 }
138
139 void ent_viewloc_trigger()
140 {
141         float point1 = ReadShort();
142         float point2 = ReadShort();
143
144         self.enemy = findfloat(world, entnum, point1);
145         self.goalentity = findfloat(world, entnum, point2);
146
147         self.origin_x = ReadCoord();
148         self.origin_y = ReadCoord();
149         self.origin_z = ReadCoord();
150         setorigin(self, self.origin);
151
152         self.cnt = point1;
153         self.count = point2;
154
155         self.think = trigger_viewloc_updatelink;
156         self.nextthink = time + 1; // we need to delay this or else
157
158         self.classname = "trigger_viewlocation";
159         self.drawmask = MASK_NORMAL; // not so concerned, but better keep it alive
160 }
161
162 void ent_viewloc()
163 {
164         self.cnt = ReadByte();
165
166         self.origin_x = ReadCoord();
167         self.origin_y = ReadCoord();
168         self.origin_z = ReadCoord();
169         setorigin(self, self.origin);
170
171         self.movedir_x = ReadCoord();
172         self.movedir_y = ReadCoord();
173         self.movedir_z = ReadCoord();
174
175         self.classname = ((self.cnt == 2) ? "target_viewlocation_end" : "target_viewlocation_start");
176         self.drawmask = MASK_NORMAL; // don't cull it
177 }
178
179 #endif