1 /**
2 * @file portal.cpp
3 *
4 * Implementation of functionality for handling town portals.
5 */
6 #include "all.h"
7
8 DEVILUTION_BEGIN_NAMESPACE
9
10 /** In-game state of portals. */
11 PortalStruct portal[MAXPORTAL];
12 /** Current portal number (a portal array index). */
13 int portalindex;
14
15 /** X-coordinate of each players portal in town. */
16 int WarpDropX[MAXPORTAL] = { 57, 59, 61, 63 };
17 /** Y-coordinate of each players portal in town. */
18 int WarpDropY[MAXPORTAL] = { 40, 40, 40, 40 };
19
InitPortals()20 void InitPortals()
21 {
22 int i;
23
24 for (i = 0; i < MAXPORTAL; i++) {
25 if (delta_portal_inited(i))
26 portal[i].open = FALSE;
27 }
28 }
29
SetPortalStats(int i,BOOL o,int x,int y,int lvl,dungeon_type lvltype)30 void SetPortalStats(int i, BOOL o, int x, int y, int lvl, dungeon_type lvltype)
31 {
32 portal[i].open = o;
33 portal[i].x = x;
34 portal[i].y = y;
35 portal[i].level = lvl;
36 portal[i].ltype = lvltype;
37 portal[i].setlvl = FALSE;
38 }
39
AddWarpMissile(int i,int x,int y)40 void AddWarpMissile(int i, int x, int y)
41 {
42 int mi;
43
44 missiledata[MIS_TOWN].mlSFX = -1;
45 dMissile[x][y] = 0;
46 mi = AddMissile(0, 0, x, y, 0, MIS_TOWN, TARGET_MONSTERS, i, 0, 0);
47
48 if (mi != -1) {
49 SetMissDir(mi, 1);
50
51 if (currlevel != 0)
52 missile[mi]._mlid = AddLight(missile[mi]._mix, missile[mi]._miy, 15);
53
54 missiledata[MIS_TOWN].mlSFX = LS_SENTINEL;
55 }
56 }
57
SyncPortals()58 void SyncPortals()
59 {
60 int i;
61
62 for (i = 0; i < MAXPORTAL; i++) {
63 if (!portal[i].open)
64 continue;
65 if (currlevel == 0)
66 AddWarpMissile(i, WarpDropX[i], WarpDropY[i]);
67 else {
68 int lvl = currlevel;
69 if (setlevel)
70 lvl = setlvlnum;
71 if (portal[i].level == lvl && portal[i].setlvl == setlevel)
72 AddWarpMissile(i, portal[i].x, portal[i].y);
73 }
74 }
75 }
76
AddInTownPortal(int i)77 void AddInTownPortal(int i)
78 {
79 AddWarpMissile(i, WarpDropX[i], WarpDropY[i]);
80 }
81
ActivatePortal(int i,int x,int y,int lvl,dungeon_type lvltype,BOOL sp)82 void ActivatePortal(int i, int x, int y, int lvl, dungeon_type lvltype, BOOL sp)
83 {
84 portal[i].open = TRUE;
85
86 if (lvl != 0) {
87 portal[i].x = x;
88 portal[i].y = y;
89 portal[i].level = lvl;
90 portal[i].ltype = lvltype;
91 portal[i].setlvl = sp;
92 }
93 }
94
DeactivatePortal(int i)95 void DeactivatePortal(int i)
96 {
97 portal[i].open = FALSE;
98 }
99
PortalOnLevel(int i)100 BOOL PortalOnLevel(int i)
101 {
102 if (portal[i].level == currlevel)
103 return TRUE;
104 else
105 return currlevel == 0;
106 }
107
RemovePortalMissile(int id)108 void RemovePortalMissile(int id)
109 {
110 int i;
111 int mi;
112
113 for (i = 0; i < nummissiles; i++) {
114 mi = missileactive[i];
115 if (missile[mi]._mitype == MIS_TOWN && missile[mi]._misource == id) {
116 dFlags[missile[mi]._mix][missile[mi]._miy] &= ~BFLAG_MISSILE;
117 dMissile[missile[mi]._mix][missile[mi]._miy] = 0;
118
119 if (portal[id].level != 0)
120 AddUnLight(missile[mi]._mlid);
121
122 DeleteMissile(mi, i);
123 }
124 }
125 }
126
SetCurrentPortal(int p)127 void SetCurrentPortal(int p)
128 {
129 portalindex = p;
130 }
131
GetPortalLevel()132 void GetPortalLevel()
133 {
134 if (currlevel != 0) {
135 setlevel = FALSE;
136 currlevel = 0;
137 plr[myplr].plrlevel = 0;
138 leveltype = DTYPE_TOWN;
139 } else {
140 if (portal[portalindex].setlvl) {
141 setlevel = TRUE;
142 setlvlnum = portal[portalindex].level;
143 currlevel = portal[portalindex].level;
144 plr[myplr].plrlevel = setlvlnum;
145 leveltype = portal[portalindex].ltype;
146 } else {
147 setlevel = FALSE;
148 currlevel = portal[portalindex].level;
149 plr[myplr].plrlevel = currlevel;
150 leveltype = portal[portalindex].ltype;
151 }
152 if (portalindex == myplr) {
153 NetSendCmd(TRUE, CMD_DEACTIVATEPORTAL);
154 DeactivatePortal(portalindex);
155 }
156 }
157 }
158
GetPortalLvlPos()159 void GetPortalLvlPos()
160 {
161 if (currlevel == 0) {
162 ViewX = WarpDropX[portalindex] + 1;
163 ViewY = WarpDropY[portalindex] + 1;
164 } else {
165 ViewX = portal[portalindex].x;
166 ViewY = portal[portalindex].y;
167
168 if (portalindex != myplr) {
169 ViewX++;
170 ViewY++;
171 }
172 }
173 }
174
PosOkPortal(int lvl,int x,int y)175 BOOL PosOkPortal(int lvl, int x, int y)
176 {
177 int i;
178
179 for (i = 0; i < MAXPORTAL; i++) {
180 if (portal[i].open && portal[i].level == lvl && ((portal[i].x == x && portal[i].y == y) || (portal[i].x == x - 1 && portal[i].y == y - 1)))
181 return TRUE;
182 }
183 return FALSE;
184 }
185
186 DEVILUTION_END_NAMESPACE
187