Quake II RTX doxygen  1.0 dev
g_func.c File Reference
#include "g_local.h"

Go to the source code of this file.

Macros

#define PLAT_LOW_TRIGGER   1
 
#define STATE_TOP   0
 
#define STATE_BOTTOM   1
 
#define STATE_UP   2
 
#define STATE_DOWN   3
 
#define DOOR_START_OPEN   1
 
#define DOOR_REVERSE   2
 
#define DOOR_CRUSHER   4
 
#define DOOR_NOMONSTER   8
 
#define DOOR_TOGGLE   32
 
#define DOOR_X_AXIS   64
 
#define DOOR_Y_AXIS   128
 
#define AccelerationDistance(target, rate)   (target * ((target / rate) + 1) / 2)
 
#define TRAIN_START_ON   1
 
#define TRAIN_TOGGLE   2
 
#define TRAIN_BLOCK_STOPS   4
 
#define SECRET_ALWAYS_SHOOT   1
 
#define SECRET_1ST_LEFT   2
 
#define SECRET_1ST_DOWN   4
 

Functions

void Move_Done (edict_t *ent)
 
void Move_Final (edict_t *ent)
 
void Move_Begin (edict_t *ent)
 
void Think_AccelMove (edict_t *ent)
 
void Move_Calc (edict_t *ent, vec3_t dest, void(*func)(edict_t *))
 
void AngleMove_Done (edict_t *ent)
 
void AngleMove_Final (edict_t *ent)
 
void AngleMove_Begin (edict_t *ent)
 
void AngleMove_Calc (edict_t *ent, void(*func)(edict_t *))
 
void plat_CalcAcceleratedMove (moveinfo_t *moveinfo)
 
void plat_Accelerate (moveinfo_t *moveinfo)
 
void plat_go_down (edict_t *ent)
 
void plat_hit_top (edict_t *ent)
 
void plat_hit_bottom (edict_t *ent)
 
void plat_go_up (edict_t *ent)
 
void plat_blocked (edict_t *self, edict_t *other)
 
void Use_Plat (edict_t *ent, edict_t *other, edict_t *activator)
 
void Touch_Plat_Center (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
 
void plat_spawn_inside_trigger (edict_t *ent)
 
void SP_func_plat (edict_t *ent)
 
void rotating_blocked (edict_t *self, edict_t *other)
 
void rotating_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
 
void rotating_use (edict_t *self, edict_t *other, edict_t *activator)
 
void SP_func_rotating (edict_t *ent)
 
void button_done (edict_t *self)
 
void button_return (edict_t *self)
 
void button_wait (edict_t *self)
 
void button_fire (edict_t *self)
 
void button_use (edict_t *self, edict_t *other, edict_t *activator)
 
void button_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
 
void button_killed (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
 
void SP_func_button (edict_t *ent)
 
void door_use_areaportals (edict_t *self, qboolean open)
 
void door_go_down (edict_t *self)
 
void door_hit_top (edict_t *self)
 
void door_hit_bottom (edict_t *self)
 
void door_go_up (edict_t *self, edict_t *activator)
 
void door_use (edict_t *self, edict_t *other, edict_t *activator)
 
void Touch_DoorTrigger (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
 
void Think_CalcMoveSpeed (edict_t *self)
 
void Think_SpawnDoorTrigger (edict_t *ent)
 
void door_blocked (edict_t *self, edict_t *other)
 
void door_killed (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
 
void door_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
 
void SP_func_door (edict_t *ent)
 
void SP_func_door_rotating (edict_t *ent)
 
void SP_func_water (edict_t *self)
 
void train_next (edict_t *self)
 
void train_blocked (edict_t *self, edict_t *other)
 
void train_wait (edict_t *self)
 
void train_resume (edict_t *self)
 
void func_train_find (edict_t *self)
 
void train_use (edict_t *self, edict_t *other, edict_t *activator)
 
void SP_func_train (edict_t *self)
 
void trigger_elevator_use (edict_t *self, edict_t *other, edict_t *activator)
 
void trigger_elevator_init (edict_t *self)
 
void SP_trigger_elevator (edict_t *self)
 
void func_timer_think (edict_t *self)
 
void func_timer_use (edict_t *self, edict_t *other, edict_t *activator)
 
void SP_func_timer (edict_t *self)
 
void func_conveyor_use (edict_t *self, edict_t *other, edict_t *activator)
 
void SP_func_conveyor (edict_t *self)
 
void door_secret_move1 (edict_t *self)
 
void door_secret_move2 (edict_t *self)
 
void door_secret_move3 (edict_t *self)
 
void door_secret_move4 (edict_t *self)
 
void door_secret_move5 (edict_t *self)
 
void door_secret_move6 (edict_t *self)
 
void door_secret_done (edict_t *self)
 
void door_secret_use (edict_t *self, edict_t *other, edict_t *activator)
 
void door_secret_blocked (edict_t *self, edict_t *other)
 
void door_secret_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
 
void SP_func_door_secret (edict_t *ent)
 
void use_killbox (edict_t *self, edict_t *other, edict_t *activator)
 
void SP_func_killbox (edict_t *ent)
 

Macro Definition Documentation

◆ AccelerationDistance

#define AccelerationDistance (   target,
  rate 
)    (target * ((target / rate) + 1) / 2)

Definition at line 218 of file g_func.c.

◆ DOOR_CRUSHER

#define DOOR_CRUSHER   4

Definition at line 63 of file g_func.c.

◆ DOOR_NOMONSTER

#define DOOR_NOMONSTER   8

Definition at line 64 of file g_func.c.

◆ DOOR_REVERSE

#define DOOR_REVERSE   2

Definition at line 62 of file g_func.c.

◆ DOOR_START_OPEN

#define DOOR_START_OPEN   1

Definition at line 61 of file g_func.c.

◆ DOOR_TOGGLE

#define DOOR_TOGGLE   32

Definition at line 65 of file g_func.c.

◆ DOOR_X_AXIS

#define DOOR_X_AXIS   64

Definition at line 66 of file g_func.c.

◆ DOOR_Y_AXIS

#define DOOR_Y_AXIS   128

Definition at line 67 of file g_func.c.

◆ PLAT_LOW_TRIGGER

#define PLAT_LOW_TRIGGER   1

Definition at line 54 of file g_func.c.

◆ SECRET_1ST_DOWN

#define SECRET_1ST_DOWN   4

Definition at line 1767 of file g_func.c.

◆ SECRET_1ST_LEFT

#define SECRET_1ST_LEFT   2

Definition at line 1766 of file g_func.c.

◆ SECRET_ALWAYS_SHOOT

#define SECRET_ALWAYS_SHOOT   1

Definition at line 1765 of file g_func.c.

◆ STATE_BOTTOM

#define STATE_BOTTOM   1

Definition at line 57 of file g_func.c.

◆ STATE_DOWN

#define STATE_DOWN   3

Definition at line 59 of file g_func.c.

◆ STATE_TOP

#define STATE_TOP   0

Definition at line 56 of file g_func.c.

◆ STATE_UP

#define STATE_UP   2

Definition at line 58 of file g_func.c.

◆ TRAIN_BLOCK_STOPS

#define TRAIN_BLOCK_STOPS   4

Definition at line 1375 of file g_func.c.

◆ TRAIN_START_ON

#define TRAIN_START_ON   1

Definition at line 1373 of file g_func.c.

◆ TRAIN_TOGGLE

#define TRAIN_TOGGLE   2

Definition at line 1374 of file g_func.c.

Function Documentation

◆ AngleMove_Begin()

void AngleMove_Begin ( edict_t *  ent)

Definition at line 163 of file g_func.c.

164 {
165  vec3_t destdelta;
166  float len;
167  float traveltime;
168  float frames;
169 
170  // set destdelta to the vector needed to move
171  if (ent->moveinfo.state == STATE_UP)
172  VectorSubtract(ent->moveinfo.end_angles, ent->s.angles, destdelta);
173  else
174  VectorSubtract(ent->moveinfo.start_angles, ent->s.angles, destdelta);
175 
176  // calculate length of vector
177  len = VectorLength(destdelta);
178 
179  // divide by speed to get time to reach dest
180  traveltime = len / ent->moveinfo.speed;
181 
182  if (traveltime < FRAMETIME) {
183  AngleMove_Final(ent);
184  return;
185  }
186 
187  frames = floor(traveltime / FRAMETIME);
188 
189  // scale the destdelta vector by the time spent traveling to get velocity
190  VectorScale(destdelta, 1.0 / traveltime, ent->avelocity);
191 
192  // set nextthink to trigger a think when dest is reached
193  ent->nextthink = level.time + frames * FRAMETIME;
194  ent->think = AngleMove_Final;
195 }

Referenced by AngleMove_Calc().

◆ AngleMove_Calc()

void AngleMove_Calc ( edict_t *  ent,
void(*)(edict_t *)  func 
)

Definition at line 197 of file g_func.c.

198 {
199  VectorClear(ent->avelocity);
200  ent->moveinfo.endfunc = func;
201  if (level.current_entity == ((ent->flags & FL_TEAMSLAVE) ? ent->teammaster : ent)) {
202  AngleMove_Begin(ent);
203  } else {
204  ent->nextthink = level.time + FRAMETIME;
205  ent->think = AngleMove_Begin;
206  }
207 }

Referenced by door_go_down(), and door_go_up().

◆ AngleMove_Done()

void AngleMove_Done ( edict_t *  ent)

Definition at line 137 of file g_func.c.

138 {
139  VectorClear(ent->avelocity);
140  ent->moveinfo.endfunc(ent);
141 }

Referenced by AngleMove_Final().

◆ AngleMove_Final()

void AngleMove_Final ( edict_t *  ent)

Definition at line 143 of file g_func.c.

144 {
145  vec3_t move;
146 
147  if (ent->moveinfo.state == STATE_UP)
148  VectorSubtract(ent->moveinfo.end_angles, ent->s.angles, move);
149  else
150  VectorSubtract(ent->moveinfo.start_angles, ent->s.angles, move);
151 
152  if (VectorCompare(move, vec3_origin)) {
153  AngleMove_Done(ent);
154  return;
155  }
156 
157  VectorScale(move, 1.0 / FRAMETIME, ent->avelocity);
158 
159  ent->think = AngleMove_Done;
160  ent->nextthink = level.time + FRAMETIME;
161 }

Referenced by AngleMove_Begin().

◆ button_done()

void button_done ( edict_t *  self)

Definition at line 656 of file g_func.c.

657 {
658  self->moveinfo.state = STATE_BOTTOM;
659  self->s.effects &= ~EF_ANIM23;
660  self->s.effects |= EF_ANIM01;
661 }

Referenced by button_return().

◆ button_fire()

void button_fire ( edict_t *  self)

Definition at line 689 of file g_func.c.

690 {
691  if (self->moveinfo.state == STATE_UP || self->moveinfo.state == STATE_TOP)
692  return;
693 
694  self->moveinfo.state = STATE_UP;
695  if (self->moveinfo.sound_start && !(self->flags & FL_TEAMSLAVE))
696  gi.sound(self, CHAN_NO_PHS_ADD + CHAN_VOICE, self->moveinfo.sound_start, 1, ATTN_STATIC, 0);
697  Move_Calc(self, self->moveinfo.end_origin, button_wait);
698 }

Referenced by button_killed(), button_touch(), and button_use().

◆ button_killed()

void button_killed ( edict_t *  self,
edict_t *  inflictor,
edict_t *  attacker,
int  damage,
vec3_t  point 
)

Definition at line 718 of file g_func.c.

719 {
720  self->activator = attacker;
721  self->health = self->max_health;
722  self->takedamage = DAMAGE_NO;
723  button_fire(self);
724 }

Referenced by SP_func_button().

◆ button_return()

void button_return ( edict_t *  self)

Definition at line 663 of file g_func.c.

664 {
665  self->moveinfo.state = STATE_DOWN;
666 
667  Move_Calc(self, self->moveinfo.start_origin, button_done);
668 
669  self->s.frame = 0;
670 
671  if (self->health)
672  self->takedamage = DAMAGE_YES;
673 }

Referenced by button_wait().

◆ button_touch()

void button_touch ( edict_t *  self,
edict_t *  other,
cplane_t *  plane,
csurface_t *  surf 
)

Definition at line 706 of file g_func.c.

707 {
708  if (!other->client)
709  return;
710 
711  if (other->health <= 0)
712  return;
713 
714  self->activator = other;
715  button_fire(self);
716 }

Referenced by SP_func_button().

◆ button_use()

void button_use ( edict_t *  self,
edict_t *  other,
edict_t *  activator 
)

Definition at line 700 of file g_func.c.

701 {
702  self->activator = activator;
703  button_fire(self);
704 }

Referenced by SP_func_button().

◆ button_wait()

void button_wait ( edict_t *  self)

Definition at line 675 of file g_func.c.

676 {
677  self->moveinfo.state = STATE_TOP;
678  self->s.effects &= ~EF_ANIM01;
679  self->s.effects |= EF_ANIM23;
680 
681  G_UseTargets(self, self->activator);
682  self->s.frame = 1;
683  if (self->moveinfo.wait >= 0) {
684  self->nextthink = level.time + self->moveinfo.wait;
685  self->think = button_return;
686  }
687 }

Referenced by button_fire().

◆ door_blocked()

void door_blocked ( edict_t *  self,
edict_t *  other 
)

Definition at line 1022 of file g_func.c.

1023 {
1024  edict_t *ent;
1025 
1026  if (!(other->svflags & SVF_MONSTER) && (!other->client)) {
1027  // give it a chance to go away on it's own terms (like gibs)
1028  T_Damage(other, self, self, vec3_origin, other->s.origin, vec3_origin, 100000, 1, 0, MOD_CRUSH);
1029  // if it's still there, nuke it
1030  if (other)
1032  return;
1033  }
1034 
1035  T_Damage(other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH);
1036 
1037  if (self->spawnflags & DOOR_CRUSHER)
1038  return;
1039 
1040 
1041 // if a door has a negative wait, it would never come back if blocked,
1042 // so let it just squash the object to death real fast
1043  if (self->moveinfo.wait >= 0) {
1044  if (self->moveinfo.state == STATE_DOWN) {
1045  for (ent = self->teammaster ; ent ; ent = ent->teamchain)
1046  door_go_up(ent, ent->activator);
1047  } else {
1048  for (ent = self->teammaster ; ent ; ent = ent->teamchain)
1049  door_go_down(ent);
1050  }
1051  }
1052 }

Referenced by SP_func_door(), and SP_func_door_rotating().

◆ door_go_down()

void door_go_down ( edict_t *  self)

Definition at line 856 of file g_func.c.

857 {
858  if (!(self->flags & FL_TEAMSLAVE)) {
859  if (self->moveinfo.sound_start)
860  gi.sound(self, CHAN_NO_PHS_ADD + CHAN_VOICE, self->moveinfo.sound_start, 1, ATTN_STATIC, 0);
861  self->s.sound = self->moveinfo.sound_middle;
862  }
863  if (self->max_health) {
864  self->takedamage = DAMAGE_YES;
865  self->health = self->max_health;
866  }
867 
868  self->moveinfo.state = STATE_DOWN;
869  if (strcmp(self->classname, "func_door") == 0)
870  Move_Calc(self, self->moveinfo.start_origin, door_hit_bottom);
871  else if (strcmp(self->classname, "func_door_rotating") == 0)
873 }

Referenced by door_blocked(), door_hit_top(), and door_use().

◆ door_go_up()

void door_go_up ( edict_t *  self,
edict_t *  activator 
)

Definition at line 875 of file g_func.c.

876 {
877  if (self->moveinfo.state == STATE_UP)
878  return; // already going up
879 
880  if (self->moveinfo.state == STATE_TOP) {
881  // reset top wait time
882  if (self->moveinfo.wait >= 0)
883  self->nextthink = level.time + self->moveinfo.wait;
884  return;
885  }
886 
887  if (!(self->flags & FL_TEAMSLAVE)) {
888  if (self->moveinfo.sound_start)
889  gi.sound(self, CHAN_NO_PHS_ADD + CHAN_VOICE, self->moveinfo.sound_start, 1, ATTN_STATIC, 0);
890  self->s.sound = self->moveinfo.sound_middle;
891  }
892  self->moveinfo.state = STATE_UP;
893  if (strcmp(self->classname, "func_door") == 0)
894  Move_Calc(self, self->moveinfo.end_origin, door_hit_top);
895  else if (strcmp(self->classname, "func_door_rotating") == 0)
897 
898  G_UseTargets(self, activator);
899  door_use_areaportals(self, qtrue);
900 }

Referenced by door_blocked(), and door_use().

◆ door_hit_bottom()

void door_hit_bottom ( edict_t *  self)

Definition at line 845 of file g_func.c.

846 {
847  if (!(self->flags & FL_TEAMSLAVE)) {
848  if (self->moveinfo.sound_end)
849  gi.sound(self, CHAN_NO_PHS_ADD + CHAN_VOICE, self->moveinfo.sound_end, 1, ATTN_STATIC, 0);
850  self->s.sound = 0;
851  }
852  self->moveinfo.state = STATE_BOTTOM;
853  door_use_areaportals(self, qfalse);
854 }

Referenced by door_go_down().

◆ door_hit_top()

void door_hit_top ( edict_t *  self)

Definition at line 829 of file g_func.c.

830 {
831  if (!(self->flags & FL_TEAMSLAVE)) {
832  if (self->moveinfo.sound_end)
833  gi.sound(self, CHAN_NO_PHS_ADD + CHAN_VOICE, self->moveinfo.sound_end, 1, ATTN_STATIC, 0);
834  self->s.sound = 0;
835  }
836  self->moveinfo.state = STATE_TOP;
837  if (self->spawnflags & DOOR_TOGGLE)
838  return;
839  if (self->moveinfo.wait >= 0) {
840  self->think = door_go_down;
841  self->nextthink = level.time + self->moveinfo.wait;
842  }
843 }

Referenced by door_go_up().

◆ door_killed()

void door_killed ( edict_t *  self,
edict_t *  inflictor,
edict_t *  attacker,
int  damage,
vec3_t  point 
)

Definition at line 1054 of file g_func.c.

1055 {
1056  edict_t *ent;
1057 
1058  for (ent = self->teammaster ; ent ; ent = ent->teamchain) {
1059  ent->health = ent->max_health;
1060  ent->takedamage = DAMAGE_NO;
1061  }
1062  door_use(self->teammaster, attacker, attacker);
1063 }

Referenced by SP_func_door(), SP_func_door_rotating(), and SP_func_door_secret().

◆ door_secret_blocked()

void door_secret_blocked ( edict_t *  self,
edict_t *  other 
)

Definition at line 1831 of file g_func.c.

1832 {
1833  if (!(other->svflags & SVF_MONSTER) && (!other->client)) {
1834  // give it a chance to go away on it's own terms (like gibs)
1835  T_Damage(other, self, self, vec3_origin, other->s.origin, vec3_origin, 100000, 1, 0, MOD_CRUSH);
1836  // if it's still there, nuke it
1837  if (other)
1839  return;
1840  }
1841 
1842  if (level.time < self->touch_debounce_time)
1843  return;
1844  self->touch_debounce_time = level.time + 0.5;
1845 
1846  T_Damage(other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH);
1847 }

Referenced by SP_func_door_secret().

◆ door_secret_die()

void door_secret_die ( edict_t *  self,
edict_t *  inflictor,
edict_t *  attacker,
int  damage,
vec3_t  point 
)

Definition at line 1849 of file g_func.c.

1850 {
1851  self->takedamage = DAMAGE_NO;
1852  door_secret_use(self, attacker, attacker);
1853 }

Referenced by SP_func_door_secret().

◆ door_secret_done()

void door_secret_done ( edict_t *  self)

Definition at line 1822 of file g_func.c.

1823 {
1824  if (!(self->targetname) || (self->spawnflags & SECRET_ALWAYS_SHOOT)) {
1825  self->health = 0;
1826  self->takedamage = DAMAGE_YES;
1827  }
1828  door_use_areaportals(self, qfalse);
1829 }

Referenced by door_secret_move6().

◆ door_secret_move1()

void door_secret_move1 ( edict_t *  self)

Definition at line 1787 of file g_func.c.

1788 {
1789  self->nextthink = level.time + 1.0;
1790  self->think = door_secret_move2;
1791 }

Referenced by door_secret_use().

◆ door_secret_move2()

void door_secret_move2 ( edict_t *  self)

Definition at line 1793 of file g_func.c.

1794 {
1795  Move_Calc(self, self->pos2, door_secret_move3);
1796 }

Referenced by door_secret_move1().

◆ door_secret_move3()

void door_secret_move3 ( edict_t *  self)

Definition at line 1798 of file g_func.c.

1799 {
1800  if (self->wait == -1)
1801  return;
1802  self->nextthink = level.time + self->wait;
1803  self->think = door_secret_move4;
1804 }

Referenced by door_secret_move2().

◆ door_secret_move4()

void door_secret_move4 ( edict_t *  self)

Definition at line 1806 of file g_func.c.

1807 {
1808  Move_Calc(self, self->pos1, door_secret_move5);
1809 }

Referenced by door_secret_move3().

◆ door_secret_move5()

void door_secret_move5 ( edict_t *  self)

Definition at line 1811 of file g_func.c.

1812 {
1813  self->nextthink = level.time + 1.0;
1814  self->think = door_secret_move6;
1815 }

Referenced by door_secret_move4().

◆ door_secret_move6()

void door_secret_move6 ( edict_t *  self)

Definition at line 1817 of file g_func.c.

1818 {
1820 }

Referenced by door_secret_move5().

◆ door_secret_use()

void door_secret_use ( edict_t *  self,
edict_t *  other,
edict_t *  activator 
)

Definition at line 1777 of file g_func.c.

1778 {
1779  // make sure we're not already moving
1780  if (!VectorCompare(self->s.origin, vec3_origin))
1781  return;
1782 
1783  Move_Calc(self, self->pos1, door_secret_move1);
1784  door_use_areaportals(self, qtrue);
1785 }

Referenced by door_secret_die(), and SP_func_door_secret().

◆ door_touch()

void door_touch ( edict_t *  self,
edict_t *  other,
cplane_t *  plane,
csurface_t *  surf 
)

Definition at line 1065 of file g_func.c.

1066 {
1067  if (!other->client)
1068  return;
1069 
1070  if (level.time < self->touch_debounce_time)
1071  return;
1072  self->touch_debounce_time = level.time + 5.0;
1073 
1074  gi.centerprintf(other, "%s", self->message);
1075  gi.sound(other, CHAN_AUTO, gi.soundindex("misc/talk1.wav"), 1, ATTN_NORM, 0);
1076 }

Referenced by SP_func_door(), SP_func_door_rotating(), and SP_func_door_secret().

◆ door_use()

void door_use ( edict_t *  self,
edict_t *  other,
edict_t *  activator 
)

Definition at line 902 of file g_func.c.

903 {
904  edict_t *ent;
905 
906  if (self->flags & FL_TEAMSLAVE)
907  return;
908 
909  if (self->spawnflags & DOOR_TOGGLE) {
910  if (self->moveinfo.state == STATE_UP || self->moveinfo.state == STATE_TOP) {
911  // trigger all paired doors
912  for (ent = self ; ent ; ent = ent->teamchain) {
913  ent->message = NULL;
914  ent->touch = NULL;
915  door_go_down(ent);
916  }
917  return;
918  }
919  }
920 
921  // trigger all paired doors
922  for (ent = self ; ent ; ent = ent->teamchain) {
923  ent->message = NULL;
924  ent->touch = NULL;
925  door_go_up(ent, activator);
926  }
927 }

Referenced by door_killed(), SP_func_door(), SP_func_door_rotating(), SP_func_water(), and Touch_DoorTrigger().

◆ door_use_areaportals()

void door_use_areaportals ( edict_t *  self,
qboolean  open 
)

Definition at line 813 of file g_func.c.

814 {
815  edict_t *t = NULL;
816 
817  if (!self->target)
818  return;
819 
820  while ((t = G_Find(t, FOFS(targetname), self->target))) {
821  if (Q_stricmp(t->classname, "func_areaportal") == 0) {
822  gi.SetAreaPortalState(t->style, open);
823  }
824  }
825 }

Referenced by door_go_up(), door_hit_bottom(), door_secret_done(), door_secret_use(), and Think_SpawnDoorTrigger().

◆ func_conveyor_use()

void func_conveyor_use ( edict_t *  self,
edict_t *  other,
edict_t *  activator 
)

Definition at line 1720 of file g_func.c.

1721 {
1722  if (self->spawnflags & 1) {
1723  self->speed = 0;
1724  self->spawnflags &= ~1;
1725  } else {
1726  self->speed = self->count;
1727  self->spawnflags |= 1;
1728  }
1729 
1730  if (!(self->spawnflags & 2))
1731  self->count = 0;
1732 }

Referenced by SP_func_conveyor().

◆ func_timer_think()

void func_timer_think ( edict_t *  self)

Definition at line 1669 of file g_func.c.

1670 {
1671  G_UseTargets(self, self->activator);
1672  self->nextthink = level.time + self->wait + crandom() * self->random;
1673 }

Referenced by func_timer_use(), and SP_func_timer().

◆ func_timer_use()

void func_timer_use ( edict_t *  self,
edict_t *  other,
edict_t *  activator 
)

Definition at line 1675 of file g_func.c.

1676 {
1677  self->activator = activator;
1678 
1679  // if on, turn it off
1680  if (self->nextthink) {
1681  self->nextthink = 0;
1682  return;
1683  }
1684 
1685  // turn it on
1686  if (self->delay)
1687  self->nextthink = level.time + self->delay;
1688  else
1689  func_timer_think(self);
1690 }

Referenced by SP_func_timer().

◆ func_train_find()

void func_train_find ( edict_t *  self)

Definition at line 1515 of file g_func.c.

1516 {
1517  edict_t *ent;
1518 
1519  if (!self->target) {
1520  gi.dprintf("train_find: no target\n");
1521  return;
1522  }
1523  ent = G_PickTarget(self->target);
1524  if (!ent) {
1525  gi.dprintf("train_find: target %s not found\n", self->target);
1526  return;
1527  }
1528  self->target = ent->target;
1529 
1530  VectorSubtract(ent->s.origin, self->mins, self->s.origin);
1531  gi.linkentity(self);
1532 
1533  // if not triggered, start immediately
1534  if (!self->targetname)
1535  self->spawnflags |= TRAIN_START_ON;
1536 
1537  if (self->spawnflags & TRAIN_START_ON) {
1538  self->nextthink = level.time + FRAMETIME;
1539  self->think = train_next;
1540  self->activator = self;
1541  }
1542 }

Referenced by SP_func_train(), SP_misc_strogg_ship(), and SP_misc_viper().

◆ Move_Begin()

void Move_Begin ( edict_t *  ent)

Definition at line 93 of file g_func.c.

94 {
95  float frames;
96 
97  if ((ent->moveinfo.speed * FRAMETIME) >= ent->moveinfo.remaining_distance) {
98  Move_Final(ent);
99  return;
100  }
101  VectorScale(ent->moveinfo.dir, ent->moveinfo.speed, ent->velocity);
102  frames = floor((ent->moveinfo.remaining_distance / ent->moveinfo.speed) / FRAMETIME);
103  ent->moveinfo.remaining_distance -= frames * ent->moveinfo.speed * FRAMETIME;
104  ent->nextthink = level.time + (frames * FRAMETIME);
105  ent->think = Move_Final;
106 }

Referenced by Move_Calc().

◆ Move_Calc()

void Move_Calc ( edict_t *  ent,
vec3_t  dest,
void(*)(edict_t *)  func 
)

Definition at line 110 of file g_func.c.

111 {
112  VectorClear(ent->velocity);
113  VectorSubtract(dest, ent->s.origin, ent->moveinfo.dir);
114  ent->moveinfo.remaining_distance = VectorNormalize(ent->moveinfo.dir);
115  ent->moveinfo.endfunc = func;
116 
117  if (ent->moveinfo.speed == ent->moveinfo.accel && ent->moveinfo.speed == ent->moveinfo.decel) {
118  if (level.current_entity == ((ent->flags & FL_TEAMSLAVE) ? ent->teammaster : ent)) {
119  Move_Begin(ent);
120  } else {
121  ent->nextthink = level.time + FRAMETIME;
122  ent->think = Move_Begin;
123  }
124  } else {
125  // accelerative
126  ent->moveinfo.current_speed = 0;
127  ent->think = Think_AccelMove;
128  ent->nextthink = level.time + FRAMETIME;
129  }
130 }

Referenced by button_fire(), button_return(), door_go_down(), door_go_up(), door_secret_move2(), door_secret_move4(), door_secret_move6(), door_secret_use(), plat_go_down(), plat_go_up(), train_next(), and train_resume().

◆ Move_Done()

void Move_Done ( edict_t *  ent)

Definition at line 74 of file g_func.c.

75 {
76  VectorClear(ent->velocity);
77  ent->moveinfo.endfunc(ent);
78 }

Referenced by Move_Final().

◆ Move_Final()

void Move_Final ( edict_t *  ent)

Definition at line 80 of file g_func.c.

81 {
82  if (ent->moveinfo.remaining_distance == 0) {
83  Move_Done(ent);
84  return;
85  }
86 
87  VectorScale(ent->moveinfo.dir, ent->moveinfo.remaining_distance / FRAMETIME, ent->velocity);
88 
89  ent->think = Move_Done;
90  ent->nextthink = level.time + FRAMETIME;
91 }

Referenced by Move_Begin(), and Think_AccelMove().

◆ plat_Accelerate()

void plat_Accelerate ( moveinfo_t moveinfo)

Definition at line 246 of file g_func.c.

247 {
248  // are we decelerating?
249  if (moveinfo->remaining_distance <= moveinfo->decel_distance) {
250  if (moveinfo->remaining_distance < moveinfo->decel_distance) {
251  if (moveinfo->next_speed) {
252  moveinfo->current_speed = moveinfo->next_speed;
253  moveinfo->next_speed = 0;
254  return;
255  }
256  if (moveinfo->current_speed > moveinfo->decel)
257  moveinfo->current_speed -= moveinfo->decel;
258  }
259  return;
260  }
261 
262  // are we at full speed and need to start decelerating during this move?
263  if (moveinfo->current_speed == moveinfo->move_speed)
264  if ((moveinfo->remaining_distance - moveinfo->current_speed) < moveinfo->decel_distance) {
265  float p1_distance;
266  float p2_distance;
267  float distance;
268 
269  p1_distance = moveinfo->remaining_distance - moveinfo->decel_distance;
270  p2_distance = moveinfo->move_speed * (1.0 - (p1_distance / moveinfo->move_speed));
271  distance = p1_distance + p2_distance;
272  moveinfo->current_speed = moveinfo->move_speed;
273  moveinfo->next_speed = moveinfo->move_speed - moveinfo->decel * (p2_distance / distance);
274  return;
275  }
276 
277  // are we accelerating?
278  if (moveinfo->current_speed < moveinfo->speed) {
279  float old_speed;
280  float p1_distance;
281  float p1_speed;
282  float p2_distance;
283  float distance;
284 
285  old_speed = moveinfo->current_speed;
286 
287  // figure simple acceleration up to move_speed
288  moveinfo->current_speed += moveinfo->accel;
289  if (moveinfo->current_speed > moveinfo->speed)
290  moveinfo->current_speed = moveinfo->speed;
291 
292  // are we accelerating throughout this entire move?
293  if ((moveinfo->remaining_distance - moveinfo->current_speed) >= moveinfo->decel_distance)
294  return;
295 
296  // during this move we will accelrate from current_speed to move_speed
297  // and cross over the decel_distance; figure the average speed for the
298  // entire move
299  p1_distance = moveinfo->remaining_distance - moveinfo->decel_distance;
300  p1_speed = (old_speed + moveinfo->move_speed) / 2.0;
301  p2_distance = moveinfo->move_speed * (1.0 - (p1_distance / p1_speed));
302  distance = p1_distance + p2_distance;
303  moveinfo->current_speed = (p1_speed * (p1_distance / distance)) + (moveinfo->move_speed * (p2_distance / distance));
304  moveinfo->next_speed = moveinfo->move_speed - moveinfo->decel * (p2_distance / distance);
305  return;
306  }
307 
308  // we are at constant velocity (move_speed)
309  return;
310 }

Referenced by Think_AccelMove().

◆ plat_blocked()

void plat_blocked ( edict_t *  self,
edict_t *  other 
)

Definition at line 380 of file g_func.c.

381 {
382  if (!(other->svflags & SVF_MONSTER) && (!other->client)) {
383  // give it a chance to go away on it's own terms (like gibs)
384  T_Damage(other, self, self, vec3_origin, other->s.origin, vec3_origin, 100000, 1, 0, MOD_CRUSH);
385  // if it's still there, nuke it
386  if (other)
388  return;
389  }
390 
391  T_Damage(other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH);
392 
393  if (self->moveinfo.state == STATE_UP)
394  plat_go_down(self);
395  else if (self->moveinfo.state == STATE_DOWN)
396  plat_go_up(self);
397 }

Referenced by SP_func_plat().

◆ plat_CalcAcceleratedMove()

void plat_CalcAcceleratedMove ( moveinfo_t moveinfo)

Definition at line 220 of file g_func.c.

221 {
222  float accel_dist;
223  float decel_dist;
224 
225  moveinfo->move_speed = moveinfo->speed;
226 
227  if (moveinfo->remaining_distance < moveinfo->accel) {
228  moveinfo->current_speed = moveinfo->remaining_distance;
229  return;
230  }
231 
232  accel_dist = AccelerationDistance(moveinfo->speed, moveinfo->accel);
233  decel_dist = AccelerationDistance(moveinfo->speed, moveinfo->decel);
234 
235  if ((moveinfo->remaining_distance - accel_dist - decel_dist) < 0) {
236  float f;
237 
238  f = (moveinfo->accel + moveinfo->decel) / (moveinfo->accel * moveinfo->decel);
239  moveinfo->move_speed = (-2 + sqrt(4 - 4 * f * (-2 * moveinfo->remaining_distance))) / (2 * f);
240  decel_dist = AccelerationDistance(moveinfo->move_speed, moveinfo->decel);
241  }
242 
243  moveinfo->decel_distance = decel_dist;
244 }

Referenced by Think_AccelMove().

◆ plat_go_down()

void plat_go_down ( edict_t *  ent)

Definition at line 358 of file g_func.c.

359 {
360  if (!(ent->flags & FL_TEAMSLAVE)) {
361  if (ent->moveinfo.sound_start)
362  gi.sound(ent, CHAN_NO_PHS_ADD + CHAN_VOICE, ent->moveinfo.sound_start, 1, ATTN_STATIC, 0);
363  ent->s.sound = ent->moveinfo.sound_middle;
364  }
365  ent->moveinfo.state = STATE_DOWN;
366  Move_Calc(ent, ent->moveinfo.end_origin, plat_hit_bottom);
367 }

Referenced by plat_blocked(), plat_hit_top(), and Use_Plat().

◆ plat_go_up()

void plat_go_up ( edict_t *  ent)

Definition at line 369 of file g_func.c.

370 {
371  if (!(ent->flags & FL_TEAMSLAVE)) {
372  if (ent->moveinfo.sound_start)
373  gi.sound(ent, CHAN_NO_PHS_ADD + CHAN_VOICE, ent->moveinfo.sound_start, 1, ATTN_STATIC, 0);
374  ent->s.sound = ent->moveinfo.sound_middle;
375  }
376  ent->moveinfo.state = STATE_UP;
377  Move_Calc(ent, ent->moveinfo.start_origin, plat_hit_top);
378 }

Referenced by plat_blocked(), and Touch_Plat_Center().

◆ plat_hit_bottom()

void plat_hit_bottom ( edict_t *  ent)

Definition at line 348 of file g_func.c.

349 {
350  if (!(ent->flags & FL_TEAMSLAVE)) {
351  if (ent->moveinfo.sound_end)
352  gi.sound(ent, CHAN_NO_PHS_ADD + CHAN_VOICE, ent->moveinfo.sound_end, 1, ATTN_STATIC, 0);
353  ent->s.sound = 0;
354  }
355  ent->moveinfo.state = STATE_BOTTOM;
356 }

Referenced by plat_go_down().

◆ plat_hit_top()

void plat_hit_top ( edict_t *  ent)

Definition at line 335 of file g_func.c.

336 {
337  if (!(ent->flags & FL_TEAMSLAVE)) {
338  if (ent->moveinfo.sound_end)
339  gi.sound(ent, CHAN_NO_PHS_ADD + CHAN_VOICE, ent->moveinfo.sound_end, 1, ATTN_STATIC, 0);
340  ent->s.sound = 0;
341  }
342  ent->moveinfo.state = STATE_TOP;
343 
344  ent->think = plat_go_down;
345  ent->nextthink = level.time + 3;
346 }

Referenced by plat_go_up().

◆ plat_spawn_inside_trigger()

void plat_spawn_inside_trigger ( edict_t *  ent)

Definition at line 423 of file g_func.c.

424 {
425  edict_t *trigger;
426  vec3_t tmin, tmax;
427 
428 //
429 // middle trigger
430 //
431  trigger = G_Spawn();
432  trigger->touch = Touch_Plat_Center;
433  trigger->movetype = MOVETYPE_NONE;
434  trigger->solid = SOLID_TRIGGER;
435  trigger->enemy = ent;
436 
437  tmin[0] = ent->mins[0] + 25;
438  tmin[1] = ent->mins[1] + 25;
439  tmin[2] = ent->mins[2];
440 
441  tmax[0] = ent->maxs[0] - 25;
442  tmax[1] = ent->maxs[1] - 25;
443  tmax[2] = ent->maxs[2] + 8;
444 
445  tmin[2] = tmax[2] - (ent->pos1[2] - ent->pos2[2] + st.lip);
446 
447  if (ent->spawnflags & PLAT_LOW_TRIGGER)
448  tmax[2] = tmin[2] + 8;
449 
450  if (tmax[0] - tmin[0] <= 0) {
451  tmin[0] = (ent->mins[0] + ent->maxs[0]) * 0.5;
452  tmax[0] = tmin[0] + 1;
453  }
454  if (tmax[1] - tmin[1] <= 0) {
455  tmin[1] = (ent->mins[1] + ent->maxs[1]) * 0.5;
456  tmax[1] = tmin[1] + 1;
457  }
458 
459  VectorCopy(tmin, trigger->mins);
460  VectorCopy(tmax, trigger->maxs);
461 
462  gi.linkentity(trigger);
463 }

Referenced by SP_func_plat().

◆ rotating_blocked()

void rotating_blocked ( edict_t *  self,
edict_t *  other 
)

Definition at line 562 of file g_func.c.

563 {
564  T_Damage(other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH);
565 }

Referenced by SP_func_rotating().

◆ rotating_touch()

void rotating_touch ( edict_t *  self,
edict_t *  other,
cplane_t *  plane,
csurface_t *  surf 
)

Definition at line 567 of file g_func.c.

568 {
569  if (self->avelocity[0] || self->avelocity[1] || self->avelocity[2])
570  T_Damage(other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH);
571 }

Referenced by rotating_use().

◆ rotating_use()

void rotating_use ( edict_t *  self,
edict_t *  other,
edict_t *  activator 
)

Definition at line 573 of file g_func.c.

574 {
575  if (!VectorCompare(self->avelocity, vec3_origin)) {
576  self->s.sound = 0;
577  VectorClear(self->avelocity);
578  self->touch = NULL;
579  } else {
580  self->s.sound = self->moveinfo.sound_middle;
581  VectorScale(self->movedir, self->speed, self->avelocity);
582  if (self->spawnflags & 16)
583  self->touch = rotating_touch;
584  }
585 }

Referenced by SP_func_rotating().

◆ SP_func_button()

void SP_func_button ( edict_t *  ent)

Definition at line 726 of file g_func.c.

727 {
728  vec3_t abs_movedir;
729  float dist;
730 
731  G_SetMovedir(ent->s.angles, ent->movedir);
732  ent->movetype = MOVETYPE_STOP;
733  ent->solid = SOLID_BSP;
734  gi.setmodel(ent, ent->model);
735 
736  if (ent->sounds != 1)
737  ent->moveinfo.sound_start = gi.soundindex("switches/butn2.wav");
738 
739  if (!ent->speed)
740  ent->speed = 40;
741  if (!ent->accel)
742  ent->accel = ent->speed;
743  if (!ent->decel)
744  ent->decel = ent->speed;
745 
746  if (!ent->wait)
747  ent->wait = 3;
748  if (!st.lip)
749  st.lip = 4;
750 
751  VectorCopy(ent->s.origin, ent->pos1);
752  abs_movedir[0] = fabs(ent->movedir[0]);
753  abs_movedir[1] = fabs(ent->movedir[1]);
754  abs_movedir[2] = fabs(ent->movedir[2]);
755  dist = abs_movedir[0] * ent->size[0] + abs_movedir[1] * ent->size[1] + abs_movedir[2] * ent->size[2] - st.lip;
756  VectorMA(ent->pos1, dist, ent->movedir, ent->pos2);
757 
758  ent->use = button_use;
759  ent->s.effects |= EF_ANIM01;
760 
761  if (ent->health) {
762  ent->max_health = ent->health;
763  ent->die = button_killed;
764  ent->takedamage = DAMAGE_YES;
765  } else if (! ent->targetname)
766  ent->touch = button_touch;
767 
768  ent->moveinfo.state = STATE_BOTTOM;
769 
770  ent->moveinfo.speed = ent->speed;
771  ent->moveinfo.accel = ent->accel;
772  ent->moveinfo.decel = ent->decel;
773  ent->moveinfo.wait = ent->wait;
774  VectorCopy(ent->pos1, ent->moveinfo.start_origin);
775  VectorCopy(ent->s.angles, ent->moveinfo.start_angles);
776  VectorCopy(ent->pos2, ent->moveinfo.end_origin);
777  VectorCopy(ent->s.angles, ent->moveinfo.end_angles);
778 
779  gi.linkentity(ent);
780 }

◆ SP_func_conveyor()

void SP_func_conveyor ( edict_t *  self)

Definition at line 1734 of file g_func.c.

1735 {
1736  if (!self->speed)
1737  self->speed = 100;
1738 
1739  if (!(self->spawnflags & 1)) {
1740  self->count = self->speed;
1741  self->speed = 0;
1742  }
1743 
1744  self->use = func_conveyor_use;
1745 
1746  gi.setmodel(self, self->model);
1747  self->solid = SOLID_BSP;
1748  gi.linkentity(self);
1749 }

◆ SP_func_door()

void SP_func_door ( edict_t *  ent)

Definition at line 1078 of file g_func.c.

1079 {
1080  vec3_t abs_movedir;
1081 
1082  if (ent->sounds != 1) {
1083  ent->moveinfo.sound_start = gi.soundindex("doors/dr1_strt.wav");
1084  ent->moveinfo.sound_middle = gi.soundindex("doors/dr1_mid.wav");
1085  ent->moveinfo.sound_end = gi.soundindex("doors/dr1_end.wav");
1086  }
1087 
1088  G_SetMovedir(ent->s.angles, ent->movedir);
1089  ent->movetype = MOVETYPE_PUSH;
1090  ent->solid = SOLID_BSP;
1091  gi.setmodel(ent, ent->model);
1092 
1093  ent->blocked = door_blocked;
1094  ent->use = door_use;
1095 
1096  if (!ent->speed)
1097  ent->speed = 100;
1098  if (deathmatch->value)
1099  ent->speed *= 2;
1100 
1101  if (!ent->accel)
1102  ent->accel = ent->speed;
1103  if (!ent->decel)
1104  ent->decel = ent->speed;
1105 
1106  if (!ent->wait)
1107  ent->wait = 3;
1108  if (!st.lip)
1109  st.lip = 8;
1110  if (!ent->dmg)
1111  ent->dmg = 2;
1112 
1113  // calculate second position
1114  VectorCopy(ent->s.origin, ent->pos1);
1115  abs_movedir[0] = fabs(ent->movedir[0]);
1116  abs_movedir[1] = fabs(ent->movedir[1]);
1117  abs_movedir[2] = fabs(ent->movedir[2]);
1118  ent->moveinfo.distance = abs_movedir[0] * ent->size[0] + abs_movedir[1] * ent->size[1] + abs_movedir[2] * ent->size[2] - st.lip;
1119  VectorMA(ent->pos1, ent->moveinfo.distance, ent->movedir, ent->pos2);
1120 
1121  // if it starts open, switch the positions
1122  if (ent->spawnflags & DOOR_START_OPEN) {
1123  VectorCopy(ent->pos2, ent->s.origin);
1124  VectorCopy(ent->pos1, ent->pos2);
1125  VectorCopy(ent->s.origin, ent->pos1);
1126  }
1127 
1128  ent->moveinfo.state = STATE_BOTTOM;
1129 
1130  if (ent->health) {
1131  ent->takedamage = DAMAGE_YES;
1132  ent->die = door_killed;
1133  ent->max_health = ent->health;
1134  } else if (ent->targetname && ent->message) {
1135  gi.soundindex("misc/talk.wav");
1136  ent->touch = door_touch;
1137  }
1138 
1139  ent->moveinfo.speed = ent->speed;
1140  ent->moveinfo.accel = ent->accel;
1141  ent->moveinfo.decel = ent->decel;
1142  ent->moveinfo.wait = ent->wait;
1143  VectorCopy(ent->pos1, ent->moveinfo.start_origin);
1144  VectorCopy(ent->s.angles, ent->moveinfo.start_angles);
1145  VectorCopy(ent->pos2, ent->moveinfo.end_origin);
1146  VectorCopy(ent->s.angles, ent->moveinfo.end_angles);
1147 
1148  if (ent->spawnflags & 16)
1149  ent->s.effects |= EF_ANIM_ALL;
1150  if (ent->spawnflags & 64)
1151  ent->s.effects |= EF_ANIM_ALLFAST;
1152 
1153  // to simplify logic elsewhere, make non-teamed doors into a team of one
1154  if (!ent->team)
1155  ent->teammaster = ent;
1156 
1157  gi.linkentity(ent);
1158 
1159  ent->nextthink = level.time + FRAMETIME;
1160  if (ent->health || ent->targetname)
1161  ent->think = Think_CalcMoveSpeed;
1162  else
1163  ent->think = Think_SpawnDoorTrigger;
1164 }

◆ SP_func_door_rotating()

void SP_func_door_rotating ( edict_t *  ent)

Definition at line 1196 of file g_func.c.

1197 {
1198  VectorClear(ent->s.angles);
1199 
1200  // set the axis of rotation
1201  VectorClear(ent->movedir);
1202  if (ent->spawnflags & DOOR_X_AXIS)
1203  ent->movedir[2] = 1.0;
1204  else if (ent->spawnflags & DOOR_Y_AXIS)
1205  ent->movedir[0] = 1.0;
1206  else // Z_AXIS
1207  ent->movedir[1] = 1.0;
1208 
1209  // check for reverse rotation
1210  if (ent->spawnflags & DOOR_REVERSE)
1211  VectorNegate(ent->movedir, ent->movedir);
1212 
1213  if (!st.distance) {
1214  gi.dprintf("%s at %s with no distance set\n", ent->classname, vtos(ent->s.origin));
1215  st.distance = 90;
1216  }
1217 
1218  VectorCopy(ent->s.angles, ent->pos1);
1219  VectorMA(ent->s.angles, st.distance, ent->movedir, ent->pos2);
1220  ent->moveinfo.distance = st.distance;
1221 
1222  ent->movetype = MOVETYPE_PUSH;
1223  ent->solid = SOLID_BSP;
1224  gi.setmodel(ent, ent->model);
1225 
1226  ent->blocked = door_blocked;
1227  ent->use = door_use;
1228 
1229  if (!ent->speed)
1230  ent->speed = 100;
1231  if (!ent->accel)
1232  ent->accel = ent->speed;
1233  if (!ent->decel)
1234  ent->decel = ent->speed;
1235 
1236  if (!ent->wait)
1237  ent->wait = 3;
1238  if (!ent->dmg)
1239  ent->dmg = 2;
1240 
1241  if (ent->sounds != 1) {
1242  ent->moveinfo.sound_start = gi.soundindex("doors/dr1_strt.wav");
1243  ent->moveinfo.sound_middle = gi.soundindex("doors/dr1_mid.wav");
1244  ent->moveinfo.sound_end = gi.soundindex("doors/dr1_end.wav");
1245  }
1246 
1247  // if it starts open, switch the positions
1248  if (ent->spawnflags & DOOR_START_OPEN) {
1249  VectorCopy(ent->pos2, ent->s.angles);
1250  VectorCopy(ent->pos1, ent->pos2);
1251  VectorCopy(ent->s.angles, ent->pos1);
1252  VectorNegate(ent->movedir, ent->movedir);
1253  }
1254 
1255  if (ent->health) {
1256  ent->takedamage = DAMAGE_YES;
1257  ent->die = door_killed;
1258  ent->max_health = ent->health;
1259  }
1260 
1261  if (ent->targetname && ent->message) {
1262  gi.soundindex("misc/talk.wav");
1263  ent->touch = door_touch;
1264  }
1265 
1266  ent->moveinfo.state = STATE_BOTTOM;
1267  ent->moveinfo.speed = ent->speed;
1268  ent->moveinfo.accel = ent->accel;
1269  ent->moveinfo.decel = ent->decel;
1270  ent->moveinfo.wait = ent->wait;
1271  VectorCopy(ent->s.origin, ent->moveinfo.start_origin);
1272  VectorCopy(ent->pos1, ent->moveinfo.start_angles);
1273  VectorCopy(ent->s.origin, ent->moveinfo.end_origin);
1274  VectorCopy(ent->pos2, ent->moveinfo.end_angles);
1275 
1276  if (ent->spawnflags & 16)
1277  ent->s.effects |= EF_ANIM_ALL;
1278 
1279  // to simplify logic elsewhere, make non-teamed doors into a team of one
1280  if (!ent->team)
1281  ent->teammaster = ent;
1282 
1283  gi.linkentity(ent);
1284 
1285  ent->nextthink = level.time + FRAMETIME;
1286  if (ent->health || ent->targetname)
1287  ent->think = Think_CalcMoveSpeed;
1288  else
1289  ent->think = Think_SpawnDoorTrigger;
1290 }

◆ SP_func_door_secret()

void SP_func_door_secret ( edict_t *  ent)

Definition at line 1855 of file g_func.c.

1856 {
1857  vec3_t forward, right, up;
1858  float side;
1859  float width;
1860  float length;
1861 
1862  ent->moveinfo.sound_start = gi.soundindex("doors/dr1_strt.wav");
1863  ent->moveinfo.sound_middle = gi.soundindex("doors/dr1_mid.wav");
1864  ent->moveinfo.sound_end = gi.soundindex("doors/dr1_end.wav");
1865 
1866  ent->movetype = MOVETYPE_PUSH;
1867  ent->solid = SOLID_BSP;
1868  gi.setmodel(ent, ent->model);
1869 
1870  ent->blocked = door_secret_blocked;
1871  ent->use = door_secret_use;
1872 
1873  if (!(ent->targetname) || (ent->spawnflags & SECRET_ALWAYS_SHOOT)) {
1874  ent->health = 0;
1875  ent->takedamage = DAMAGE_YES;
1876  ent->die = door_secret_die;
1877  }
1878 
1879  if (!ent->dmg)
1880  ent->dmg = 2;
1881 
1882  if (!ent->wait)
1883  ent->wait = 5;
1884 
1885  ent->moveinfo.accel =
1886  ent->moveinfo.decel =
1887  ent->moveinfo.speed = 50;
1888 
1889  // calculate positions
1890  AngleVectors(ent->s.angles, forward, right, up);
1891  VectorClear(ent->s.angles);
1892  side = 1.0 - (ent->spawnflags & SECRET_1ST_LEFT);
1893  if (ent->spawnflags & SECRET_1ST_DOWN)
1894  width = fabs(DotProduct(up, ent->size));
1895  else
1896  width = fabs(DotProduct(right, ent->size));
1897  length = fabs(DotProduct(forward, ent->size));
1898  if (ent->spawnflags & SECRET_1ST_DOWN)
1899  VectorMA(ent->s.origin, -1 * width, up, ent->pos1);
1900  else
1901  VectorMA(ent->s.origin, side * width, right, ent->pos1);
1902  VectorMA(ent->pos1, length, forward, ent->pos2);
1903 
1904  if (ent->health) {
1905  ent->takedamage = DAMAGE_YES;
1906  ent->die = door_killed;
1907  ent->max_health = ent->health;
1908  } else if (ent->targetname && ent->message) {
1909  gi.soundindex("misc/talk.wav");
1910  ent->touch = door_touch;
1911  }
1912 
1913  ent->classname = "func_door";
1914 
1915  gi.linkentity(ent);
1916 }

◆ SP_func_killbox()

void SP_func_killbox ( edict_t *  ent)

Definition at line 1927 of file g_func.c.

1928 {
1929  gi.setmodel(ent, ent->model);
1930  ent->use = use_killbox;
1931  ent->svflags = SVF_NOCLIENT;
1932 }

◆ SP_func_plat()

void SP_func_plat ( edict_t *  ent)

Definition at line 483 of file g_func.c.

484 {
485  VectorClear(ent->s.angles);
486  ent->solid = SOLID_BSP;
487  ent->movetype = MOVETYPE_PUSH;
488 
489  gi.setmodel(ent, ent->model);
490 
491  ent->blocked = plat_blocked;
492 
493  if (!ent->speed)
494  ent->speed = 20;
495  else
496  ent->speed *= 0.1;
497 
498  if (!ent->accel)
499  ent->accel = 5;
500  else
501  ent->accel *= 0.1;
502 
503  if (!ent->decel)
504  ent->decel = 5;
505  else
506  ent->decel *= 0.1;
507 
508  if (!ent->dmg)
509  ent->dmg = 2;
510 
511  if (!st.lip)
512  st.lip = 8;
513 
514  // pos1 is the top position, pos2 is the bottom
515  VectorCopy(ent->s.origin, ent->pos1);
516  VectorCopy(ent->s.origin, ent->pos2);
517  if (st.height)
518  ent->pos2[2] -= st.height;
519  else
520  ent->pos2[2] -= (ent->maxs[2] - ent->mins[2]) - st.lip;
521 
522  ent->use = Use_Plat;
523 
524  plat_spawn_inside_trigger(ent); // the "start moving" trigger
525 
526  if (ent->targetname) {
527  ent->moveinfo.state = STATE_UP;
528  } else {
529  VectorCopy(ent->pos2, ent->s.origin);
530  gi.linkentity(ent);
531  ent->moveinfo.state = STATE_BOTTOM;
532  }
533 
534  ent->moveinfo.speed = ent->speed;
535  ent->moveinfo.accel = ent->accel;
536  ent->moveinfo.decel = ent->decel;
537  ent->moveinfo.wait = ent->wait;
538  VectorCopy(ent->pos1, ent->moveinfo.start_origin);
539  VectorCopy(ent->s.angles, ent->moveinfo.start_angles);
540  VectorCopy(ent->pos2, ent->moveinfo.end_origin);
541  VectorCopy(ent->s.angles, ent->moveinfo.end_angles);
542 
543  ent->moveinfo.sound_start = gi.soundindex("plats/pt1_strt.wav");
544  ent->moveinfo.sound_middle = gi.soundindex("plats/pt1_mid.wav");
545  ent->moveinfo.sound_end = gi.soundindex("plats/pt1_end.wav");
546 }

◆ SP_func_rotating()

void SP_func_rotating ( edict_t *  ent)

Definition at line 587 of file g_func.c.

588 {
589  ent->solid = SOLID_BSP;
590  if (ent->spawnflags & 32)
591  ent->movetype = MOVETYPE_STOP;
592  else
593  ent->movetype = MOVETYPE_PUSH;
594 
595  // set the axis of rotation
596  VectorClear(ent->movedir);
597  if (ent->spawnflags & 4)
598  ent->movedir[2] = 1.0;
599  else if (ent->spawnflags & 8)
600  ent->movedir[0] = 1.0;
601  else // Z_AXIS
602  ent->movedir[1] = 1.0;
603 
604  // check for reverse rotation
605  if (ent->spawnflags & 2)
606  VectorNegate(ent->movedir, ent->movedir);
607 
608  if (!ent->speed)
609  ent->speed = 100;
610  if (!ent->dmg)
611  ent->dmg = 2;
612 
613 // ent->moveinfo.sound_middle = "doors/hydro1.wav";
614 
615  ent->use = rotating_use;
616  if (ent->dmg)
617  ent->blocked = rotating_blocked;
618 
619  if (ent->spawnflags & 1)
620  ent->use(ent, NULL, NULL);
621 
622  if (ent->spawnflags & 64)
623  ent->s.effects |= EF_ANIM_ALL;
624  if (ent->spawnflags & 128)
625  ent->s.effects |= EF_ANIM_ALLFAST;
626 
627  gi.setmodel(ent, ent->model);
628  gi.linkentity(ent);
629 }

◆ SP_func_timer()

void SP_func_timer ( edict_t *  self)

Definition at line 1692 of file g_func.c.

1693 {
1694  if (!self->wait)
1695  self->wait = 1.0;
1696 
1697  self->use = func_timer_use;
1698  self->think = func_timer_think;
1699 
1700  if (self->random >= self->wait) {
1701  self->random = self->wait - FRAMETIME;
1702  gi.dprintf("func_timer at %s has random >= wait\n", vtos(self->s.origin));
1703  }
1704 
1705  if (self->spawnflags & 1) {
1706  self->nextthink = level.time + 1.0 + st.pausetime + self->delay + self->wait + crandom() * self->random;
1707  self->activator = self;
1708  }
1709 
1710  self->svflags = SVF_NOCLIENT;
1711 }

◆ SP_func_train()

void SP_func_train ( edict_t *  self)

Definition at line 1562 of file g_func.c.

1563 {
1564  self->movetype = MOVETYPE_PUSH;
1565 
1566  VectorClear(self->s.angles);
1567  self->blocked = train_blocked;
1568  if (self->spawnflags & TRAIN_BLOCK_STOPS)
1569  self->dmg = 0;
1570  else {
1571  if (!self->dmg)
1572  self->dmg = 100;
1573  }
1574  self->solid = SOLID_BSP;
1575  gi.setmodel(self, self->model);
1576 
1577  if (st.noise)
1578  self->moveinfo.sound_middle = gi.soundindex(st.noise);
1579 
1580  if (!self->speed)
1581  self->speed = 100;
1582 
1583  self->moveinfo.speed = self->speed;
1584  self->moveinfo.accel = self->moveinfo.decel = self->moveinfo.speed;
1585 
1586  self->use = train_use;
1587 
1588  gi.linkentity(self);
1589 
1590  if (self->target) {
1591  // start trains on the second frame, to make sure their targets have had
1592  // a chance to spawn
1593  self->nextthink = level.time + FRAMETIME;
1594  self->think = func_train_find;
1595  } else {
1596  gi.dprintf("func_train without a target at %s\n", vtos(self->absmin));
1597  }
1598 }

◆ SP_func_water()

void SP_func_water ( edict_t *  self)

Definition at line 1308 of file g_func.c.

1309 {
1310  vec3_t abs_movedir;
1311 
1312  G_SetMovedir(self->s.angles, self->movedir);
1313  self->movetype = MOVETYPE_PUSH;
1314  self->solid = SOLID_BSP;
1315  gi.setmodel(self, self->model);
1316 
1317  switch (self->sounds) {
1318  default:
1319  break;
1320 
1321  case 1: // water
1322  self->moveinfo.sound_start = gi.soundindex("world/mov_watr.wav");
1323  self->moveinfo.sound_end = gi.soundindex("world/stp_watr.wav");
1324  break;
1325 
1326  case 2: // lava
1327  self->moveinfo.sound_start = gi.soundindex("world/mov_watr.wav");
1328  self->moveinfo.sound_end = gi.soundindex("world/stp_watr.wav");
1329  break;
1330  }
1331 
1332  // calculate second position
1333  VectorCopy(self->s.origin, self->pos1);
1334  abs_movedir[0] = fabs(self->movedir[0]);
1335  abs_movedir[1] = fabs(self->movedir[1]);
1336  abs_movedir[2] = fabs(self->movedir[2]);
1337  self->moveinfo.distance = abs_movedir[0] * self->size[0] + abs_movedir[1] * self->size[1] + abs_movedir[2] * self->size[2] - st.lip;
1338  VectorMA(self->pos1, self->moveinfo.distance, self->movedir, self->pos2);
1339 
1340  // if it starts open, switch the positions
1341  if (self->spawnflags & DOOR_START_OPEN) {
1342  VectorCopy(self->pos2, self->s.origin);
1343  VectorCopy(self->pos1, self->pos2);
1344  VectorCopy(self->s.origin, self->pos1);
1345  }
1346 
1347  VectorCopy(self->pos1, self->moveinfo.start_origin);
1348  VectorCopy(self->s.angles, self->moveinfo.start_angles);
1349  VectorCopy(self->pos2, self->moveinfo.end_origin);
1350  VectorCopy(self->s.angles, self->moveinfo.end_angles);
1351 
1352  self->moveinfo.state = STATE_BOTTOM;
1353 
1354  if (!self->speed)
1355  self->speed = 25;
1356  self->moveinfo.accel = self->moveinfo.decel = self->moveinfo.speed = self->speed;
1357 
1358  if (!self->wait)
1359  self->wait = -1;
1360  self->moveinfo.wait = self->wait;
1361 
1362  self->use = door_use;
1363 
1364  if (self->wait == -1)
1365  self->spawnflags |= DOOR_TOGGLE;
1366 
1367  self->classname = "func_door";
1368 
1369  gi.linkentity(self);
1370 }

◆ SP_trigger_elevator()

void SP_trigger_elevator ( edict_t *  self)

Definition at line 1648 of file g_func.c.

1649 {
1650  self->think = trigger_elevator_init;
1651  self->nextthink = level.time + FRAMETIME;
1652 }

◆ Think_AccelMove()

void Think_AccelMove ( edict_t *  ent)

Definition at line 312 of file g_func.c.

313 {
314  ent->moveinfo.remaining_distance -= ent->moveinfo.current_speed;
315 
316  if (ent->moveinfo.current_speed == 0) // starting or blocked
317  plat_CalcAcceleratedMove(&ent->moveinfo);
318 
319  plat_Accelerate(&ent->moveinfo);
320 
321  // will the entire move complete on next frame?
322  if (ent->moveinfo.remaining_distance <= ent->moveinfo.current_speed) {
323  Move_Final(ent);
324  return;
325  }
326 
327  VectorScale(ent->moveinfo.dir, ent->moveinfo.current_speed * 10, ent->velocity);
328  ent->nextthink = level.time + FRAMETIME;
329  ent->think = Think_AccelMove;
330 }

Referenced by Move_Calc().

◆ Think_CalcMoveSpeed()

void Think_CalcMoveSpeed ( edict_t *  self)

Definition at line 947 of file g_func.c.

948 {
949  edict_t *ent;
950  float min;
951  float time;
952  float newspeed;
953  float ratio;
954  float dist;
955 
956  if (self->flags & FL_TEAMSLAVE)
957  return; // only the team master does this
958 
959  // find the smallest distance any member of the team will be moving
960  min = fabs(self->moveinfo.distance);
961  for (ent = self->teamchain; ent; ent = ent->teamchain) {
962  dist = fabs(ent->moveinfo.distance);
963  if (dist < min)
964  min = dist;
965  }
966 
967  time = min / self->moveinfo.speed;
968 
969  // adjust speeds so they will all complete at the same time
970  for (ent = self; ent; ent = ent->teamchain) {
971  newspeed = fabs(ent->moveinfo.distance) / time;
972  ratio = newspeed / ent->moveinfo.speed;
973  if (ent->moveinfo.accel == ent->moveinfo.speed)
974  ent->moveinfo.accel = newspeed;
975  else
976  ent->moveinfo.accel *= ratio;
977  if (ent->moveinfo.decel == ent->moveinfo.speed)
978  ent->moveinfo.decel = newspeed;
979  else
980  ent->moveinfo.decel *= ratio;
981  ent->moveinfo.speed = newspeed;
982  }
983 }

Referenced by SP_func_door(), SP_func_door_rotating(), and Think_SpawnDoorTrigger().

◆ Think_SpawnDoorTrigger()

void Think_SpawnDoorTrigger ( edict_t *  ent)

Definition at line 985 of file g_func.c.

986 {
987  edict_t *other;
988  vec3_t mins, maxs;
989 
990  if (ent->flags & FL_TEAMSLAVE)
991  return; // only the team leader spawns a trigger
992 
993  VectorCopy(ent->absmin, mins);
994  VectorCopy(ent->absmax, maxs);
995 
996  for (other = ent->teamchain ; other ; other = other->teamchain) {
997  AddPointToBounds(other->absmin, mins, maxs);
998  AddPointToBounds(other->absmax, mins, maxs);
999  }
1000 
1001  // expand
1002  mins[0] -= 60;
1003  mins[1] -= 60;
1004  maxs[0] += 60;
1005  maxs[1] += 60;
1006 
1007  other = G_Spawn();
1008  VectorCopy(mins, other->mins);
1009  VectorCopy(maxs, other->maxs);
1010  other->owner = ent;
1011  other->solid = SOLID_TRIGGER;
1012  other->movetype = MOVETYPE_NONE;
1013  other->touch = Touch_DoorTrigger;
1014  gi.linkentity(other);
1015 
1016  if (ent->spawnflags & DOOR_START_OPEN)
1017  door_use_areaportals(ent, qtrue);
1018 
1019  Think_CalcMoveSpeed(ent);
1020 }

Referenced by SP_func_door(), and SP_func_door_rotating().

◆ Touch_DoorTrigger()

void Touch_DoorTrigger ( edict_t *  self,
edict_t *  other,
cplane_t *  plane,
csurface_t *  surf 
)

Definition at line 929 of file g_func.c.

930 {
931  if (other->health <= 0)
932  return;
933 
934  if (!(other->svflags & SVF_MONSTER) && (!other->client))
935  return;
936 
937  if ((self->owner->spawnflags & DOOR_NOMONSTER) && (other->svflags & SVF_MONSTER))
938  return;
939 
940  if (level.time < self->touch_debounce_time)
941  return;
942  self->touch_debounce_time = level.time + 1.0;
943 
944  door_use(self->owner, other, other);
945 }

Referenced by Think_SpawnDoorTrigger().

◆ Touch_Plat_Center()

void Touch_Plat_Center ( edict_t *  ent,
edict_t *  other,
cplane_t *  plane,
csurface_t *  surf 
)

Definition at line 408 of file g_func.c.

409 {
410  if (!other->client)
411  return;
412 
413  if (other->health <= 0)
414  return;
415 
416  ent = ent->enemy; // now point at the plat, not the trigger
417  if (ent->moveinfo.state == STATE_BOTTOM)
418  plat_go_up(ent);
419  else if (ent->moveinfo.state == STATE_TOP)
420  ent->nextthink = level.time + 1; // the player is still on the plat, so delay going down
421 }

Referenced by plat_spawn_inside_trigger().

◆ train_blocked()

void train_blocked ( edict_t *  self,
edict_t *  other 
)

Definition at line 1389 of file g_func.c.

1390 {
1391  if (!(other->svflags & SVF_MONSTER) && (!other->client)) {
1392  // give it a chance to go away on it's own terms (like gibs)
1393  T_Damage(other, self, self, vec3_origin, other->s.origin, vec3_origin, 100000, 1, 0, MOD_CRUSH);
1394  // if it's still there, nuke it
1395  if (other)
1397  return;
1398  }
1399 
1400  if (level.time < self->touch_debounce_time)
1401  return;
1402 
1403  if (!self->dmg)
1404  return;
1405  self->touch_debounce_time = level.time + 0.5;
1406  T_Damage(other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH);
1407 }

Referenced by SP_func_train().

◆ train_next()

void train_next ( edict_t *  self)

Definition at line 1448 of file g_func.c.

1449 {
1450  edict_t *ent;
1451  vec3_t dest;
1452  qboolean first;
1453 
1454  first = qtrue;
1455 again:
1456  if (!self->target) {
1457 // gi.dprintf ("train_next: no next target\n");
1458  return;
1459  }
1460 
1461  ent = G_PickTarget(self->target);
1462  if (!ent) {
1463  gi.dprintf("train_next: bad target %s\n", self->target);
1464  return;
1465  }
1466 
1467  self->target = ent->target;
1468 
1469  // check for a teleport path_corner
1470  if (ent->spawnflags & 1) {
1471  if (!first) {
1472  gi.dprintf("connected teleport path_corners, see %s at %s\n", ent->classname, vtos(ent->s.origin));
1473  return;
1474  }
1475  first = qfalse;
1476  VectorSubtract(ent->s.origin, self->mins, self->s.origin);
1477  VectorCopy(self->s.origin, self->s.old_origin);
1478  self->s.event = EV_OTHER_TELEPORT;
1479  gi.linkentity(self);
1480  goto again;
1481  }
1482 
1483  self->moveinfo.wait = ent->wait;
1484  self->target_ent = ent;
1485 
1486  if (!(self->flags & FL_TEAMSLAVE)) {
1487  if (self->moveinfo.sound_start)
1488  gi.sound(self, CHAN_NO_PHS_ADD + CHAN_VOICE, self->moveinfo.sound_start, 1, ATTN_STATIC, 0);
1489  self->s.sound = self->moveinfo.sound_middle;
1490  }
1491 
1492  VectorSubtract(ent->s.origin, self->mins, dest);
1493  self->moveinfo.state = STATE_TOP;
1494  VectorCopy(self->s.origin, self->moveinfo.start_origin);
1495  VectorCopy(dest, self->moveinfo.end_origin);
1496  Move_Calc(self, dest, train_wait);
1497  self->spawnflags |= TRAIN_START_ON;
1498 }

Referenced by func_train_find(), train_use(), and train_wait().

◆ train_resume()

void train_resume ( edict_t *  self)

Definition at line 1500 of file g_func.c.

1501 {
1502  edict_t *ent;
1503  vec3_t dest;
1504 
1505  ent = self->target_ent;
1506 
1507  VectorSubtract(ent->s.origin, self->mins, dest);
1508  self->moveinfo.state = STATE_TOP;
1509  VectorCopy(self->s.origin, self->moveinfo.start_origin);
1510  VectorCopy(dest, self->moveinfo.end_origin);
1511  Move_Calc(self, dest, train_wait);
1512  self->spawnflags |= TRAIN_START_ON;
1513 }

Referenced by train_use(), and trigger_elevator_use().

◆ train_use()

void train_use ( edict_t *  self,
edict_t *  other,
edict_t *  activator 
)

Definition at line 1544 of file g_func.c.

1545 {
1546  self->activator = activator;
1547 
1548  if (self->spawnflags & TRAIN_START_ON) {
1549  if (!(self->spawnflags & TRAIN_TOGGLE))
1550  return;
1551  self->spawnflags &= ~TRAIN_START_ON;
1552  VectorClear(self->velocity);
1553  self->nextthink = 0;
1554  } else {
1555  if (self->target_ent)
1556  train_resume(self);
1557  else
1558  train_next(self);
1559  }
1560 }

Referenced by misc_strogg_ship_use(), misc_viper_use(), and SP_func_train().

◆ train_wait()

void train_wait ( edict_t *  self)

Definition at line 1409 of file g_func.c.

1410 {
1411  if (self->target_ent->pathtarget) {
1412  char *savetarget;
1413  edict_t *ent;
1414 
1415  ent = self->target_ent;
1416  savetarget = ent->target;
1417  ent->target = ent->pathtarget;
1418  G_UseTargets(ent, self->activator);
1419  ent->target = savetarget;
1420 
1421  // make sure we didn't get killed by a killtarget
1422  if (!self->inuse)
1423  return;
1424  }
1425 
1426  if (self->moveinfo.wait) {
1427  if (self->moveinfo.wait > 0) {
1428  self->nextthink = level.time + self->moveinfo.wait;
1429  self->think = train_next;
1430  } else if (self->spawnflags & TRAIN_TOGGLE) { // && wait < 0
1431  train_next(self);
1432  self->spawnflags &= ~TRAIN_START_ON;
1433  VectorClear(self->velocity);
1434  self->nextthink = 0;
1435  }
1436 
1437  if (!(self->flags & FL_TEAMSLAVE)) {
1438  if (self->moveinfo.sound_end)
1439  gi.sound(self, CHAN_NO_PHS_ADD + CHAN_VOICE, self->moveinfo.sound_end, 1, ATTN_STATIC, 0);
1440  self->s.sound = 0;
1441  }
1442  } else {
1443  train_next(self);
1444  }
1445 
1446 }

Referenced by train_next(), and train_resume().

◆ trigger_elevator_init()

void trigger_elevator_init ( edict_t *  self)

Definition at line 1627 of file g_func.c.

1628 {
1629  if (!self->target) {
1630  gi.dprintf("trigger_elevator has no target\n");
1631  return;
1632  }
1633  self->movetarget = G_PickTarget(self->target);
1634  if (!self->movetarget) {
1635  gi.dprintf("trigger_elevator unable to find target %s\n", self->target);
1636  return;
1637  }
1638  if (strcmp(self->movetarget->classname, "func_train") != 0) {
1639  gi.dprintf("trigger_elevator target %s is not a train\n", self->target);
1640  return;
1641  }
1642 
1643  self->use = trigger_elevator_use;
1644  self->svflags = SVF_NOCLIENT;
1645 
1646 }

Referenced by SP_trigger_elevator().

◆ trigger_elevator_use()

void trigger_elevator_use ( edict_t *  self,
edict_t *  other,
edict_t *  activator 
)

Definition at line 1603 of file g_func.c.

1604 {
1605  edict_t *target;
1606 
1607  if (self->movetarget->nextthink) {
1608 // gi.dprintf("elevator busy\n");
1609  return;
1610  }
1611 
1612  if (!other->pathtarget) {
1613  gi.dprintf("elevator used with no pathtarget\n");
1614  return;
1615  }
1616 
1617  target = G_PickTarget(other->pathtarget);
1618  if (!target) {
1619  gi.dprintf("elevator used with bad pathtarget: %s\n", other->pathtarget);
1620  return;
1621  }
1622 
1623  self->movetarget->target_ent = target;
1624  train_resume(self->movetarget);
1625 }

Referenced by trigger_elevator_init().

◆ use_killbox()

void use_killbox ( edict_t *  self,
edict_t *  other,
edict_t *  activator 
)

Definition at line 1922 of file g_func.c.

1923 {
1924  KillBox(self);
1925 }

Referenced by SP_func_killbox().

◆ Use_Plat()

void Use_Plat ( edict_t *  ent,
edict_t *  other,
edict_t *  activator 
)

Definition at line 400 of file g_func.c.

401 {
402  if (ent->think)
403  return; // already down
404  plat_go_down(ent);
405 }

Referenced by SP_func_plat().

gi
game_import_t gi
Definition: g_main.c:23
moveinfo_t::decel
float decel
Definition: g_local.h:377
train_use
void train_use(edict_t *self, edict_t *other, edict_t *activator)
Definition: g_func.c:1544
func_train_find
void func_train_find(edict_t *self)
Definition: g_func.c:1515
deathmatch
cvar_t * deathmatch
Definition: g_main.c:33
Think_AccelMove
void Think_AccelMove(edict_t *ent)
Definition: g_func.c:312
button_use
void button_use(edict_t *self, edict_t *other, edict_t *activator)
Definition: g_func.c:700
DOOR_Y_AXIS
#define DOOR_Y_AXIS
Definition: g_func.c:67
door_go_up
void door_go_up(edict_t *self, edict_t *activator)
Definition: g_func.c:875
G_Spawn
edict_t * G_Spawn(void)
Definition: g_utils.c:391
door_secret_move3
void door_secret_move3(edict_t *self)
Definition: g_func.c:1798
func_timer_think
void func_timer_think(edict_t *self)
Definition: g_func.c:1669
func_conveyor_use
void func_conveyor_use(edict_t *self, edict_t *other, edict_t *activator)
Definition: g_func.c:1720
plat_go_down
void plat_go_down(edict_t *ent)
Definition: g_func.c:358
DOOR_NOMONSTER
#define DOOR_NOMONSTER
Definition: g_func.c:64
button_killed
void button_killed(edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
Definition: g_func.c:718
Use_Plat
void Use_Plat(edict_t *ent, edict_t *other, edict_t *activator)
Definition: g_func.c:400
FRAMETIME
#define FRAMETIME
Definition: g_local.h:75
door_secret_die
void door_secret_die(edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
Definition: g_func.c:1849
door_secret_move2
void door_secret_move2(edict_t *self)
Definition: g_func.c:1793
plat_Accelerate
void plat_Accelerate(moveinfo_t *moveinfo)
Definition: g_func.c:246
st
spawn_temp_t st
Definition: g_main.c:25
MOVETYPE_STOP
@ MOVETYPE_STOP
Definition: g_local.h:189
plat_blocked
void plat_blocked(edict_t *self, edict_t *other)
Definition: g_func.c:380
plat_CalcAcceleratedMove
void plat_CalcAcceleratedMove(moveinfo_t *moveinfo)
Definition: g_func.c:220
STATE_TOP
#define STATE_TOP
Definition: g_func.c:56
rotating_touch
void rotating_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
Definition: g_func.c:567
MOVETYPE_PUSH
@ MOVETYPE_PUSH
Definition: g_local.h:188
G_Find
edict_t * G_Find(edict_t *from, int fieldofs, char *match)
Definition: g_utils.c:43
BecomeExplosion1
void BecomeExplosion1(edict_t *self)
Definition: g_misc.c:297
train_blocked
void train_blocked(edict_t *self, edict_t *other)
Definition: g_func.c:1389
rotating_use
void rotating_use(edict_t *self, edict_t *other, edict_t *activator)
Definition: g_func.c:573
DAMAGE_YES
@ DAMAGE_YES
Definition: g_local.h:88
Move_Calc
void Move_Calc(edict_t *ent, vec3_t dest, void(*func)(edict_t *))
Definition: g_func.c:110
FOFS
#define FOFS(x)
Definition: g_local.h:498
PLAT_LOW_TRIGGER
#define PLAT_LOW_TRIGGER
Definition: g_func.c:54
door_secret_move6
void door_secret_move6(edict_t *self)
Definition: g_func.c:1817
DOOR_X_AXIS
#define DOOR_X_AXIS
Definition: g_func.c:66
door_use
void door_use(edict_t *self, edict_t *other, edict_t *activator)
Definition: g_func.c:902
T_Damage
void T_Damage(edict_t *targ, edict_t *inflictor, edict_t *attacker, vec3_t dir, vec3_t point, vec3_t normal, int damage, int knockback, int dflags, int mod)
Definition: g_combat.c:358
other
@ other
Definition: ogg.c:63
moveinfo_t::decel_distance
float decel_distance
Definition: g_local.h:389
button_return
void button_return(edict_t *self)
Definition: g_func.c:663
door_secret_move4
void door_secret_move4(edict_t *self)
Definition: g_func.c:1806
TRAIN_BLOCK_STOPS
#define TRAIN_BLOCK_STOPS
Definition: g_func.c:1375
button_touch
void button_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
Definition: g_func.c:706
train_next
void train_next(edict_t *self)
Definition: g_func.c:1448
train_wait
void train_wait(edict_t *self)
Definition: g_func.c:1409
level_locals_t::current_entity
edict_t * current_entity
Definition: g_local.h:332
button_fire
void button_fire(edict_t *self)
Definition: g_func.c:689
SECRET_1ST_LEFT
#define SECRET_1ST_LEFT
Definition: g_func.c:1766
vec3_origin
vec3_t vec3_origin
Definition: shared.c:21
STATE_UP
#define STATE_UP
Definition: g_func.c:58
width
static int width
Definition: physical_sky.c:38
button_done
void button_done(edict_t *self)
Definition: g_func.c:656
plat_hit_bottom
void plat_hit_bottom(edict_t *ent)
Definition: g_func.c:348
spawn_temp_t::height
int height
Definition: g_local.h:351
door_secret_done
void door_secret_done(edict_t *self)
Definition: g_func.c:1822
DOOR_TOGGLE
#define DOOR_TOGGLE
Definition: g_func.c:65
button_wait
void button_wait(edict_t *self)
Definition: g_func.c:675
TRAIN_START_ON
#define TRAIN_START_ON
Definition: g_func.c:1373
MOVETYPE_NONE
@ MOVETYPE_NONE
Definition: g_local.h:186
trigger_elevator_use
void trigger_elevator_use(edict_t *self, edict_t *other, edict_t *activator)
Definition: g_func.c:1603
AngleMove_Calc
void AngleMove_Calc(edict_t *ent, void(*func)(edict_t *))
Definition: g_func.c:197
moveinfo_t::remaining_distance
float remaining_distance
Definition: g_local.h:388
door_use_areaportals
void door_use_areaportals(edict_t *self, qboolean open)
Definition: g_func.c:813
use_killbox
void use_killbox(edict_t *self, edict_t *other, edict_t *activator)
Definition: g_func.c:1922
rotating_blocked
void rotating_blocked(edict_t *self, edict_t *other)
Definition: g_func.c:562
forward
static vec3_t forward
Definition: p_view.c:27
crandom
#define crandom()
Definition: g_local.h:505
spawn_temp_t::lip
int lip
Definition: g_local.h:349
moveinfo_t::move_speed
float move_speed
Definition: g_local.h:386
door_go_down
void door_go_down(edict_t *self)
Definition: g_func.c:856
vtos
char * vtos(vec3_t v)
Definition: g_utils.c:275
STATE_DOWN
#define STATE_DOWN
Definition: g_func.c:59
door_secret_move5
void door_secret_move5(edict_t *self)
Definition: g_func.c:1811
AngleVectors
void AngleVectors(vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
Definition: shared.c:23
DAMAGE_NO
@ DAMAGE_NO
Definition: g_local.h:87
Touch_DoorTrigger
void Touch_DoorTrigger(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
Definition: g_func.c:929
DOOR_CRUSHER
#define DOOR_CRUSHER
Definition: g_func.c:63
AngleMove_Final
void AngleMove_Final(edict_t *ent)
Definition: g_func.c:143
TRAIN_TOGGLE
#define TRAIN_TOGGLE
Definition: g_func.c:1374
moveinfo_t::current_speed
float current_speed
Definition: g_local.h:385
Move_Begin
void Move_Begin(edict_t *ent)
Definition: g_func.c:93
door_secret_blocked
void door_secret_blocked(edict_t *self, edict_t *other)
Definition: g_func.c:1831
Think_SpawnDoorTrigger
void Think_SpawnDoorTrigger(edict_t *ent)
Definition: g_func.c:985
DOOR_REVERSE
#define DOOR_REVERSE
Definition: g_func.c:62
door_blocked
void door_blocked(edict_t *self, edict_t *other)
Definition: g_func.c:1022
AngleMove_Begin
void AngleMove_Begin(edict_t *ent)
Definition: g_func.c:163
door_killed
void door_killed(edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
Definition: g_func.c:1054
door_hit_top
void door_hit_top(edict_t *self)
Definition: g_func.c:829
MOD_CRUSH
#define MOD_CRUSH
Definition: g_local.h:477
DOOR_START_OPEN
#define DOOR_START_OPEN
Definition: g_func.c:61
STATE_BOTTOM
#define STATE_BOTTOM
Definition: g_func.c:57
door_secret_use
void door_secret_use(edict_t *self, edict_t *other, edict_t *activator)
Definition: g_func.c:1777
moveinfo_t::next_speed
float next_speed
Definition: g_local.h:387
level_locals_t::time
float time
Definition: g_local.h:299
plat_go_up
void plat_go_up(edict_t *ent)
Definition: g_func.c:369
SECRET_ALWAYS_SHOOT
#define SECRET_ALWAYS_SHOOT
Definition: g_func.c:1765
AccelerationDistance
#define AccelerationDistance(target, rate)
Definition: g_func.c:218
Move_Final
void Move_Final(edict_t *ent)
Definition: g_func.c:80
up
static vec3_t up
Definition: p_view.c:27
Think_CalcMoveSpeed
void Think_CalcMoveSpeed(edict_t *self)
Definition: g_func.c:947
right
static vec3_t right
Definition: p_view.c:27
G_UseTargets
void G_UseTargets(edict_t *ent, edict_t *activator)
Definition: g_utils.c:166
FL_TEAMSLAVE
#define FL_TEAMSLAVE
Definition: g_local.h:69
level
level_locals_t level
Definition: g_main.c:22
SECRET_1ST_DOWN
#define SECRET_1ST_DOWN
Definition: g_func.c:1767
spawn_temp_t::distance
int distance
Definition: g_local.h:350
moveinfo_t::accel
float accel
Definition: g_local.h:375
door_touch
void door_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
Definition: g_func.c:1065
G_SetMovedir
void G_SetMovedir(vec3_t angles, vec3_t movedir)
Definition: g_utils.c:296
KillBox
qboolean KillBox(edict_t *ent)
Definition: g_utils.c:515
AngleMove_Done
void AngleMove_Done(edict_t *ent)
Definition: g_func.c:137
func_timer_use
void func_timer_use(edict_t *self, edict_t *other, edict_t *activator)
Definition: g_func.c:1675
plat_spawn_inside_trigger
void plat_spawn_inside_trigger(edict_t *ent)
Definition: g_func.c:423
Touch_Plat_Center
void Touch_Plat_Center(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
Definition: g_func.c:408
train_resume
void train_resume(edict_t *self)
Definition: g_func.c:1500
spawn_temp_t::noise
char * noise
Definition: g_local.h:352
G_PickTarget
edict_t * G_PickTarget(char *targetname)
Definition: g_utils.c:114
spawn_temp_t::pausetime
float pausetime
Definition: g_local.h:353
VectorNormalize
vec_t VectorNormalize(vec3_t v)
Definition: shared.c:55
AddPointToBounds
void AddPointToBounds(const vec3_t v, vec3_t mins, vec3_t maxs)
Definition: shared.c:97
door_secret_move1
void door_secret_move1(edict_t *self)
Definition: g_func.c:1787
door_hit_bottom
void door_hit_bottom(edict_t *self)
Definition: g_func.c:845
trigger_elevator_init
void trigger_elevator_init(edict_t *self)
Definition: g_func.c:1627
Move_Done
void Move_Done(edict_t *ent)
Definition: g_func.c:74
moveinfo_t::speed
float speed
Definition: g_local.h:376
plat_hit_top
void plat_hit_top(edict_t *ent)
Definition: g_func.c:335