]> icculus.org git repositories - theoddone33/hheretic.git/blob - base/p_telept.c
Initial revision
[theoddone33/hheretic.git] / base / p_telept.c
1
2 // P_telept.c
3
4 #include "doomdef.h"
5 #include "p_local.h"
6 #include "soundst.h"
7
8 //----------------------------------------------------------------------------
9 //
10 // FUNC P_Teleport
11 //
12 //----------------------------------------------------------------------------
13
14 boolean P_Teleport(mobj_t *thing, fixed_t x, fixed_t y, angle_t angle)
15 {
16         fixed_t oldx;
17         fixed_t oldy;
18         fixed_t oldz;
19         fixed_t aboveFloor;
20         fixed_t fogDelta;
21         player_t *player;
22         unsigned an;
23         mobj_t *fog;
24
25         oldx = thing->x;
26         oldy = thing->y;
27         oldz = thing->z;
28         aboveFloor = thing->z-thing->floorz;
29         if(!P_TeleportMove(thing, x, y))
30         {
31                 return(false);
32         }
33         if(thing->player)
34         {
35                 player = thing->player;
36                 if(player->powers[pw_flight] && aboveFloor)
37                 {
38                         thing->z = thing->floorz+aboveFloor;
39                         if(thing->z+thing->height > thing->ceilingz)
40                         {
41                                 thing->z = thing->ceilingz-thing->height;
42                         }
43                         player->viewz = thing->z+player->viewheight;
44                 }
45                 else
46                 {
47                         thing->z = thing->floorz;
48                         player->viewz = thing->z+player->viewheight;
49                         player->lookdir = 0;
50                 }
51         }
52         else if(thing->flags&MF_MISSILE)
53         {
54                 thing->z = thing->floorz+aboveFloor;
55                 if(thing->z+thing->height > thing->ceilingz)
56                 {
57                         thing->z = thing->ceilingz-thing->height;
58                 }
59         }
60         else
61         {
62                 thing->z = thing->floorz;
63         }
64         // Spawn teleport fog at source and destination
65         fogDelta = thing->flags&MF_MISSILE ? 0 : TELEFOGHEIGHT;
66         fog = P_SpawnMobj(oldx, oldy, oldz+fogDelta, MT_TFOG);
67         S_StartSound(fog, sfx_telept);
68         an = angle>>ANGLETOFINESHIFT;
69         fog = P_SpawnMobj(x+20*finecosine[an],
70                 y+20*finesine[an], thing->z+fogDelta, MT_TFOG);
71         S_StartSound(fog, sfx_telept);
72         if(thing->player && !thing->player->powers[pw_weaponlevel2])
73         { // Freeze player for about .5 sec
74                 thing->reactiontime = 18;
75         }
76         thing->angle = angle;
77         if(thing->flags2&MF2_FOOTCLIP && P_GetThingFloorType(thing) != FLOOR_SOLID)
78         {
79                 thing->flags2 |= MF2_FEETARECLIPPED;
80         }
81         else if(thing->flags2&MF2_FEETARECLIPPED)
82         {
83                 thing->flags2 &= ~MF2_FEETARECLIPPED;
84         }
85         if(thing->flags&MF_MISSILE)
86         {
87                 angle >>= ANGLETOFINESHIFT;
88                 thing->momx = FixedMul(thing->info->speed, finecosine[angle]);
89                 thing->momy = FixedMul(thing->info->speed, finesine[angle]);
90         }
91         else
92         {
93                 thing->momx = thing->momy = thing->momz = 0;
94         }
95         return(true);
96 }
97
98 //----------------------------------------------------------------------------
99 //
100 // FUNC EV_Teleport
101 //
102 //----------------------------------------------------------------------------
103
104 boolean EV_Teleport(line_t *line, int side, mobj_t *thing)
105 {
106         int i;
107         int tag;
108         mobj_t *m;
109         thinker_t *thinker;
110         sector_t *sector;
111
112         if(thing->flags2&MF2_NOTELEPORT)
113         {
114                 return(false);
115         }
116         if(side == 1)
117         { // Don't teleport when crossing back side
118                 return(false);
119         }
120         tag = line->tag;
121         for(i = 0; i < numsectors; i++)
122         {
123                 if(sectors[i].tag == tag)
124                 {
125                         thinker = thinkercap.next;
126                         for(thinker = thinkercap.next; thinker != &thinkercap;
127                                 thinker = thinker->next)
128                         {
129                                 if(thinker->function != P_MobjThinker)
130                                 { // Not a mobj
131                                         continue;
132                                 }
133                                 m = (mobj_t *)thinker;
134                                 if(m->type != MT_TELEPORTMAN )
135                                 { // Not a teleportman
136                                         continue;
137                                 }
138                                 sector = m->subsector->sector;
139                                 if(sector-sectors != i)
140                                 { // Wrong sector
141                                         continue;
142                                 }
143                                 return(P_Teleport(thing, m->x, m->y, m->angle));
144                         }
145                 }
146         }
147         return(false);
148 }