1 float waypointsprite_normdistance;
2 float waypointsprite_minscale;
3 float waypointsprite_fadedistance;
4 float waypointsprite_minalpha;
5 float waypointsprite_distancealphaexponent;
6 float waypointsprite_timealphaexponent;
7 float waypointsprite_deployed_lifetime;
8 float waypointsprite_deadlifetime;
9 float waypointsprite_limitedrange;
11 ..entity owned_by_field;
12 .float(entity) waypointsprite_for_player; // returns a model index or 0 for hide
13 float waypointsprite_for_player_default(entity e)
17 if(self.enemy != other)
23 if(self.team != other.team)
25 if(other.classname != "player")
30 if(self.currentammo) // hidable?
31 if(other.cvar_cl_hidewaypoints) // wants to hide;
34 // otherwise, accept the model
35 return self.modelindex;
38 void WaypointSprite_Init()
40 waypointsprite_fadedistance = vlen(world.maxs - world.mins);
41 waypointsprite_normdistance = cvar("g_waypointsprite_normdistance");
42 waypointsprite_minscale = cvar("g_waypointsprite_minscale");
43 waypointsprite_minalpha = cvar("g_waypointsprite_minalpha");
44 waypointsprite_distancealphaexponent = cvar("g_waypointsprite_distancealphaexponent");
45 waypointsprite_timealphaexponent = cvar("g_waypointsprite_timealphaexponent");
46 waypointsprite_deployed_lifetime = cvar("g_waypointsprite_deployed_lifetime");
47 waypointsprite_deadlifetime = cvar("g_waypointsprite_deadlifetime");
48 waypointsprite_limitedrange = cvar("g_waypointsprite_limitedrange");
50 precache_model("models/sprites/bluebase.sp2");
51 precache_model("models/sprites/flagcarrier.sp2");
52 precache_model("models/sprites/here.sp2");
53 precache_model("models/sprites/helpme.sp2");
54 precache_model("models/sprites/redbase.sp2");
55 precache_model("models/sprites/waypoint.sp2");
56 precache_model("models/sprites/danger.sp2");
59 void WaypointSprite_InitClient(entity e)
61 stuffcmd(e, "\nalias \"g_waypointsprite_personal\" \"impulse 30\"\n alias \"g_waypointsprite_personal_p\" \"impulse 31\"\n alias \"g_waypointsprite_personal_d\" \"impulse 32\"\n alias \"g_waypointsprite_team_helpme\" \"impulse 33\"\n alias \"g_waypointsprite_team_here\" \"impulse 34\"\n alias \"g_waypointsprite_team_here_p\" \"impulse 35\"\n alias \"g_waypointsprite_team_here_d\" \"impulse 36\"\n alias \"g_waypointsprite_team_danger\" \"impulse 37\"\n alias \"g_waypointsprite_team_danger_p\" \"impulse 38\"\n alias \"g_waypointsprite_team_danger_d\" \"impulse 39\"\n alias \"g_waypointsprite_clear_personal\" \"impulse 47\"\n alias \"g_waypointsprite_clear\" \"impulse 48\"\n alias \"g_waypointsprite_toggle\" \"impulse 49\"\n");
64 void WaypointSprite_Kill(entity wp)
69 wp.owner.(wp.owned_by_field) = world;
73 void WaypointSprite_Disown(entity wp, float fadetime)
79 if(wp.exteriormodeltoclient == wp.owner)
81 setattachment(wp, world, "");
82 #ifdef ATTACHMENT_WORKS_WITH_EF_NODEPTHTEST
83 setorigin(wp, wp.origin + wp.exteriormodeltoclient.origin);
85 setorigin(wp, wp.view_ofs + wp.exteriormodeltoclient.origin);
87 wp.exteriormodeltoclient = world;
89 wp.owner.(wp.owned_by_field) = world;
95 wp.teleport_time = time + fadetime;
97 else if(fadetime < (wp.teleport_time - time))
99 // accelerate the spawnfunc_waypoint's dying
101 // (wp.teleport_time - time) / wp.health stays
102 // wp.teleport_time = time + fadetime
103 float current_fadetime;
104 current_fadetime = wp.teleport_time - time;
105 wp.teleport_time = time + fadetime;
106 wp.health = wp.health * fadetime / current_fadetime;
111 void WaypointSprite_Think()
118 if(time >= self.teleport_time)
122 WaypointSprite_Kill(self);
124 self.nextthink = time;
127 float WaypointSprite_CustomizeEntityForClient()
129 vector realorigin, porigin;
130 float distancealpha, timealpha;
136 timealpha = bound(0, (self.teleport_time - time) / self.health, 1);
139 timealpha = pow(timealpha, waypointsprite_timealphaexponent);
145 newmodel = self.waypointsprite_for_player(other);
148 self.modelindex = newmodel;
150 porigin = other.origin + other.view_ofs_z * '0 0 1';
152 #ifdef ATTACHMENT_WORKS_WITH_EF_NODEPTHTEST
153 realorigin = self.exteriormodeltoclient.origin + self.origin;
155 if(self.exteriormodeltoclient)
157 if(self.exteriormodeltoclient == other)
159 setattachment(self, other, "");
160 setorigin(self, self.view_ofs);
161 realorigin = other.origin + self.origin;
165 setattachment(self, world, "");
166 setorigin(self, self.exteriormodeltoclient.origin + self.view_ofs);
167 realorigin = self.origin;
171 realorigin = self.origin;
174 distance = vlen(realorigin - porigin);
177 if(distance >= self.max_health)
180 self.scale = max(1, distance / waypointsprite_normdistance) * waypointsprite_minscale;
182 if(self.max_health > waypointsprite_normdistance)
184 // alpha 1 at normdistance, alpha 0 at maxdistance
185 distancealpha = bound(0, (self.max_health - distance) / (self.max_health - waypointsprite_normdistance), 1);
186 distancealpha = pow(distancealpha, waypointsprite_distancealphaexponent);
188 else if(self.max_health)
190 // alpha 1 if visible
195 // alpha 1 at normdistance, alpha minalpha at fadedistance
196 distancealpha = bound(0, (waypointsprite_fadedistance - distance) / (waypointsprite_fadedistance - waypointsprite_normdistance), 1);
197 distancealpha = pow(distancealpha, waypointsprite_distancealphaexponent);
198 distancealpha = distancealpha * (1 - waypointsprite_minalpha) + waypointsprite_minalpha;
201 self.alpha = timealpha * distancealpha;
206 entity WaypointSprite_Spawn(
207 string spr, // sprite
208 float lifetime, float maxdistance, // lifetime, max distance
209 entity ref, vector ofs, // position
210 entity showto, float t, // show to whom? Use a flag to indicate a team
211 entity own, .entity ownfield, // remove when own gets killed
212 float hideable // true when it should be controlled by cl_hidewaypoints
217 wp.classname = "sprite_waypoint";
218 wp.teleport_time = time + lifetime;
219 wp.health = lifetime;
220 wp.exteriormodeltoclient = ref;
223 #ifdef ATTACHMENT_WORKS_WITH_EF_NODEPTHTEST
224 setattachment(wp, ref, "");
235 wp.currentammo = hideable;
239 remove(own.ownfield);
241 wp.owned_by_field = ownfield;
243 wp.max_health = maxdistance;
244 wp.customizeentityforclient = WaypointSprite_CustomizeEntityForClient;
245 wp.think = WaypointSprite_Think;
247 wp.effects = EF_NODEPTHTEST | EF_LOWPRECISION;
249 setmodel(wp, strcat("models/sprites/", spr, ".sp2")); // precision set above
251 wp.model = "waypoint";
252 setsize(wp, '0 0 0', '0 0 0');
253 wp.waypointsprite_for_player = waypointsprite_for_player_default;
257 entity WaypointSprite_SpawnFixed(
264 return WaypointSprite_Spawn(spr, 0, 0, world, ofs, world, 0, own, ownfield, TRUE);
267 .entity waypointsprite_deployed_fixed;
268 entity WaypointSprite_DeployFixed(
274 float t, maxdistance;
280 maxdistance = waypointsprite_limitedrange;
283 return WaypointSprite_Spawn(spr, waypointsprite_deployed_lifetime, maxdistance, world, ofs, world, t, self, waypointsprite_deployed_fixed, FALSE);
286 .entity waypointsprite_deployed_personal;
287 entity WaypointSprite_DeployPersonal(
292 return WaypointSprite_Spawn(spr, 0, 0, world, ofs, self, 0, self, waypointsprite_deployed_personal, FALSE);
295 .entity waypointsprite_attached;
296 .entity waypointsprite_attachedforcarrier;
297 entity WaypointSprite_Attach(
302 float t, maxdistance;
303 if(self.waypointsprite_attachedforcarrier)
304 return world; // can't attach to FC
310 maxdistance = waypointsprite_limitedrange;
313 return WaypointSprite_Spawn(spr, waypointsprite_deployed_lifetime, maxdistance, self, '0 0 64', world, t, self, waypointsprite_attached, FALSE);
316 entity WaypointSprite_AttachCarrier(
321 WaypointSprite_Kill(carrier.waypointsprite_attached); // FC overrides attached
322 return WaypointSprite_Spawn(spr, 0, 0, carrier, '0 0 64', world, carrier.team, carrier, waypointsprite_attachedforcarrier, FALSE);
325 void WaypointSprite_DetachCarrier(entity carrier)
327 WaypointSprite_Disown(carrier.waypointsprite_attachedforcarrier, waypointsprite_deadlifetime);
330 void WaypointSprite_ClearPersonal()
332 WaypointSprite_Kill(self.waypointsprite_deployed_personal);
335 void WaypointSprite_ClearOwned()
337 WaypointSprite_Kill(self.waypointsprite_deployed_fixed);
338 WaypointSprite_Kill(self.waypointsprite_deployed_personal);
339 WaypointSprite_Kill(self.waypointsprite_attached);
342 void WaypointSprite_PlayerDead()
344 WaypointSprite_Disown(self.waypointsprite_attached, waypointsprite_deadlifetime);
345 WaypointSprite_DetachCarrier(self);
348 void WaypointSprite_PlayerGone()
350 WaypointSprite_Disown(self.waypointsprite_deployed_fixed, waypointsprite_deadlifetime);
351 WaypointSprite_Kill(self.waypointsprite_deployed_personal);
352 WaypointSprite_Disown(self.waypointsprite_attached, waypointsprite_deadlifetime);
353 WaypointSprite_DetachCarrier(self);