]> icculus.org git repositories - theoddone33/hhexen.git/blob - base/p_telept.c
osezer patch 012
[theoddone33/hhexen.git] / base / p_telept.c
1
2 //**************************************************************************
3 //**
4 //** p_telept.c : Heretic 2 : Raven Software, Corp.
5 //**
6 //** $RCSfile$
7 //** $Revision$
8 //** $Date$
9 //** $Author$
10 //**
11 //**************************************************************************
12
13 // HEADER FILES ------------------------------------------------------------
14
15 #include "h2def.h"
16 #include "p_local.h"
17 #include "soundst.h"
18
19 // MACROS ------------------------------------------------------------------
20
21 // TYPES -------------------------------------------------------------------
22
23 // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
24
25 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
26
27 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
28
29 // EXTERNAL DATA DECLARATIONS ----------------------------------------------
30
31 // PUBLIC DATA DEFINITIONS -------------------------------------------------
32
33 // PRIVATE DATA DEFINITIONS ------------------------------------------------
34
35 // CODE --------------------------------------------------------------------
36
37 //==========================================================================
38 //
39 // P_Teleport
40 //
41 //==========================================================================
42
43 boolean P_Teleport(mobj_t *thing, fixed_t x, fixed_t y, angle_t angle,
44         boolean useFog)
45 {
46         fixed_t oldx;
47         fixed_t oldy;
48         fixed_t oldz;
49         fixed_t aboveFloor;
50         fixed_t fogDelta;
51         player_t *player;
52         unsigned an;
53         mobj_t *fog;
54
55         oldx = thing->x;
56         oldy = thing->y;
57         oldz = thing->z;
58         aboveFloor = thing->z-thing->floorz;
59         if(!P_TeleportMove(thing, x, y))
60         {
61                 return false;
62         }
63         if(thing->player)
64         {
65                 player = thing->player;
66                 if(player->powers[pw_flight] && aboveFloor)
67                 {
68                         thing->z = thing->floorz+aboveFloor;
69                         if(thing->z+thing->height > thing->ceilingz)
70                         {
71                                 thing->z = thing->ceilingz-thing->height;
72                         }
73                         player->viewz = thing->z+player->viewheight;
74                 }
75                 else
76                 {
77                         thing->z = thing->floorz;
78                         player->viewz = thing->z+player->viewheight;
79                         if(useFog)
80                         {
81                                 player->lookdir = 0;
82                         }
83                 }
84         }
85         else if(thing->flags&MF_MISSILE)
86         {
87                 thing->z = thing->floorz+aboveFloor;
88                 if(thing->z+thing->height > thing->ceilingz)
89                 {
90                         thing->z = thing->ceilingz-thing->height;
91                 }
92         }
93         else
94         {
95                 thing->z = thing->floorz;
96         }
97         // Spawn teleport fog at source and destination
98         if(useFog)
99         {
100                 fogDelta = thing->flags&MF_MISSILE ? 0 : TELEFOGHEIGHT;
101                 fog = P_SpawnMobj(oldx, oldy, oldz+fogDelta, MT_TFOG);
102                 S_StartSound(fog, SFX_TELEPORT);
103                 an = angle>>ANGLETOFINESHIFT;
104                 fog = P_SpawnMobj(x+20*finecosine[an],
105                         y+20*finesine[an], thing->z+fogDelta, MT_TFOG);
106                 S_StartSound(fog, SFX_TELEPORT);
107                 if(thing->player && !thing->player->powers[pw_speed])
108                 { // Freeze player for about .5 sec
109                         thing->reactiontime = 18;
110                 }
111                 thing->angle = angle;
112         }
113         if(thing->flags2&MF2_FLOORCLIP)
114         {
115                 if(thing->z == thing->subsector->sector->floorheight 
116                         && P_GetThingFloorType(thing) > FLOOR_SOLID)
117                 {
118                         thing->floorclip = 10*FRACUNIT;
119                 }
120                 else
121                 {
122                         thing->floorclip = 0;
123                 }
124         }
125         if(thing->flags&MF_MISSILE)
126         {
127                 angle >>= ANGLETOFINESHIFT;
128                 thing->momx = FixedMul(thing->info->speed, finecosine[angle]);
129                 thing->momy = FixedMul(thing->info->speed, finesine[angle]);
130         }
131         else if(useFog) // no fog doesn't alter the player's momentums
132         {
133                 thing->momx = thing->momy = thing->momz = 0;
134         }
135         return true;
136 }
137
138 //==========================================================================
139 //
140 // EV_Teleport
141 //
142 //==========================================================================
143
144 boolean EV_Teleport(int tid, mobj_t *thing, boolean fog)
145 {
146         int i;
147         int count;
148         mobj_t *mo = NULL; /* jim added initialiser */
149         int searcher;
150
151         if(!thing)
152         { // Teleport function called with an invalid mobj
153                 return false;
154         }
155         if(thing->flags2&MF2_NOTELEPORT)
156         {
157                 return false;
158         }
159         count = 0;
160         searcher = -1;
161         while(P_FindMobjFromTID(tid, &searcher) != NULL)
162         {
163                 count++;
164         }
165         if(count == 0)
166         {
167                 return false;
168         }
169         count = 1+(P_Random()%count);
170         searcher = -1;
171         for(i = 0; i < count; i++)
172         {
173                 mo = P_FindMobjFromTID(tid, &searcher);
174         }
175         if (!mo) I_Error("Can't find teleport mapspot\n");
176         return P_Teleport(thing, mo->x, mo->y, mo->angle, fog);
177 }
178