really compiles! ;-)
[dd2d.git] / data / scripts / api / switch.dacs
blob9602b44654a961b94fe45cd278528446a7affae5
1 /* DooM2D: Midnight on the Firing Line
2  * coded by Ketmar // Invisible Vector <ketmar@ketmar.no-ip.org>
3  * Understanding is not required. Only obedience.
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 module apiSwitch;
20 import apiActor;
21 import apiMap;
22 import apiMove;
23 import stdlib;
26 public const SW_PL_PRESS = BIT(0);
27 public const SW_MN_PRESS = BIT(1);
28 public const SW_PL_NEAR  = BIT(2);
29 public const SW_MN_NEAR  = BIT(3);
30 public const SW_KEY_R    = BIT(4);
31 public const SW_KEY_G    = BIT(5);
32 public const SW_KEY_B    = BIT(6);
35 public int switchGetD (Actor me) { return (me.switchabf>>24)&0xff; }
36 public void switchSetD (Actor me, int d) { me.switchabf = (me.switchabf&0x00ffffffU)|((d&0xff)<<24); }
37 public int switchGetA (Actor me) { return (me.switchabf>>16)&0xff; }
38 public int switchGetB (Actor me) { return (me.switchabf>>8)&0xff; }
39 public int switchGetFlags (Actor me) { return (me.switchabf&0xff); }
42 // `pressed`==false: proximity
43 public auto switchTouch (Actor me, Actor other, int pressed) {
44   if (me.dead || other.dead) return false;
46   int x = other.x, y = other.y;
47   int sx = (x-other.radius)/TileSize;
48   int sy = (y-other.height+1)/TileSize;
49   x = (x+other.radius)/TileSize;
50   y /= TileSize;
52   int myx = me.x/TileSize;
53   int myy = me.y/TileSize;
55   if (other.classname == "DummyPressActor") writeln("sx=", sx, "; sy=", sy, "; x=", x, "; y=", y, "; myx=", myx, "; myy=", myy);
57   if (myx >= sx && myx <= x && myy >= sy && myy <= y) {
58     if (other.classname == "DummyPressActor") {
59       if (other.atm == 1) writeln("*** PRESSACTOR ACTIVATED SWITCH ***");
60       return (other.atm == 1);
61     }
62     auto sflags = me.switchGetFlags();
63     //if (other.isPlayer) writeln("isPlayer:", other.isPlayer, "; PLP:", (sflags&SW_PL_PRESS), "; PLN:", (sflags&SW_MN_NEAR));
64     if (pressed) {
65       // press
66       if (((sflags&SW_PL_PRESS) && other.isPlayer) ||
67           ((sflags&SW_MN_PRESS) && other.isMonster)) return true;
68     }
69     // proximity
70     if (((sflags&SW_PL_NEAR) && other.isPlayer) ||
71         ((sflags&SW_MN_NEAR) && other.isMonster)) return true;
72   }
73   return false;
77 public Actor switchWhoTouched (Actor me) {
78   if (me.dead) return null;
79   rewindTouchList();
80   for (Actor other = getNextTouchListItem; other; other = getNextTouchListItem) {
81     //writeln("switch touch: '", other.classtype, ":", other.classname, "'");
82     if (other.dead) continue;
83     if (!other.isPlayer && !other.isMonster && other.classname != "DummyPressActor") continue;
84     if (other.classname == "DummyPressActor") writeln("DUMMYACTOR CHECK");
85     int press = 0;
86     if (other.isPlayer) {
87       auto btn = getPlayerButtons(other.plrnum);
88       press = ((btn&PLK_USE) != 0);
89     }
90     if (!me.switchTouch(other, press)) {
91       if (other.classname == "DummyPressActor") writeln("DUMMYACTOR FUCK");
92       continue;
93     }
94     if (other.classname == "DummyPressActor") writeln("DUMMYACTOR OK");
95     //writeln("  switch: real touch");
96     // check keys
97     auto sflags = me.switchGetFlags();
98     if ((sflags&SW_KEY_R) && !other.hasRedKey) continue;
99     if ((sflags&SW_KEY_G) && !other.hasGreenKey) continue;
100     if ((sflags&SW_KEY_B) && !other.hasBlueKey) continue;
101     return other;
102   }
103   return null; // invalid actor
107 public void switchOpenDoor (Actor me) {
108   if (me.dead) return null;
109   int a = me.switchGetA();
110   int b = me.switchGetB();
111   //int j;
112   //swsnd = Z_sound(sndbdo, 128);
113   auto j = mapGetTile(LAYER_FRONT, a, b);
114   //cht = 2;
115   //chto = 3;
116   //chf = 0;
117   //f_ch = 1;
118   processDoor(a, b, TILE_DOORC, TILE_DOORO, 0, true);
119   mapSetTile(LAYER_FRONT, a, b, j);
123 public int switchShutDoor (Actor me) {
124   if (me.dead) return false;
125   int a = me.switchGetA();
126   int b = me.switchGetB();
127   //int cht = TILE_DOORO;
128   //int chto = TILE_ACTTRAP;
129   int chf = mapGetTile(LAYER_FRONT, a, b);
130   //int f_ch = 1;
131   processDoor(a, b, TILE_DOORO, TILE_ACTTRAP, chf, true);
132   //cht = TILE_ACTTRAP;
133   if (Z_chktrap(false, 0, null, HIT_SOME)) {
134     int j = mapGetTile(LAYER_FRONT, a, b);
135     //chto = 3;
136     //chf = 0;
137     //f_ch = 1;
138     processDoor(a, b, TILE_ACTTRAP, TILE_DOORO, 0, true);
139     mapSetTile(LAYER_FRONT, a, b, j);
140     return false;
141   }
142   //chto = 2;
143   processDoor(a, b, TILE_ACTTRAP, TILE_DOORC, chf, true);
144   //swsnd = Z_sound(sndbdc, 128);
145   return true;
149 public int switchShutTrap (Actor me) {
150   if (me.dead) return false;
151   int a = me.switchGetA();
152   int b = me.switchGetB();
153   if (mapGetTypeTile(a, b) != TILE_DOORO) return false;
154   //cht = TILE_DOORO;
155   //chto = TILE_ACTTRAP;
156   int chf = mapGetTile(LAYER_FRONT, a, b);
157   //f_ch = 1;
158   processDoor(a, b, TILE_DOORO, TILE_ACTTRAP, chf, true);
159   Z_chktrap(true, 100, null, HIT_TRAP);
160   //cht = TILE_ACTTRAP;
161   //chto = TILE_DOORC;
162   processDoor(a, b, TILE_ACTTRAP, TILE_DOORC|0x80, chf, true);
163   //swsnd = Z_sound(sndswn, 128);
164   me.atm = 1;
165   me.switchSetD(20);
166   return true;
170 public const SW_LIFT_TOGGLE = 0;
171 public const SW_LIFT_UP = 1;
172 public const SW_LIFT_DOWN = 2;
174 public void switchLift (Actor me, int type/*SW_LIFT_XXX*/) {
175   if (me.dead) return false;
176   int a = me.switchGetA();
177   int b = me.switchGetB();
178   int cht, chto;
179   if (type == SW_LIFT_TOGGLE) {
180     switch (mapGetTypeTile(a, b)) {
181       case TILE_LIFTD: type = SW_LIFT_UP; break;
182       case TILE_LIFTU: type = SW_LIFT_DOWN; break;
183       default: return;
184     }
185   }
186   if (type == SW_LIFT_UP) {
187     cht = TILE_LIFTD;
188     chto = TILE_LIFTU;
189   } else {
190     cht = TILE_LIFTU;
191     chto = TILE_LIFTD;
192   }
193   if (mapGetTypeTile(a, b) != cht) return;
194   processDoor(a, b, cht, chto, 0, false);
195   //swsnd = Z_sound(sndswx, 128);
196   me.atm = 9; // cooldown time
200 // `x` and `y` in tiles
201 void processDoor (int x, int y, int cht, int chto, int chf, int f_ch) {
202   if (x < 0 || y < 0 || x >= MapWidth || y >= MapHeight) return;
203   if (mapGetTypeTile(x, y) != cht) return;
204   int ex = x+1;
205   for (; x && mapGetTypeTile(x-1, y) == cht; --x) {}
206   for (; ex < MapWidth && mapGetTypeTile(ex, y) == cht; ++ex) {}
207   for (int mx = x; mx < ex; ++mx) mapSetTypeTile(mx, y, chto); //memset(fldm+y*MapWidth+x, chto, ex-x);
208   if (f_ch) for (int mx = x; mx < ex; ++mx) mapSetTile(LAYER_FRONT, mx, y, chf); //if (f_ch) memset(fldf+y*MapWidth+x, chf, ex-x);
209   for (; x < ex; ++x) {
210     processDoor(x, y-1, cht, chto, chf, f_ch);
211     processDoor(x, y+1, cht, chto, chf, f_ch);
212   }
216 // ////////////////////////////////////////////////////////////////////////// //
217 //public const SwitchSkipAction = -666;
218 //int funcdummy (Actor me) { return 0; }
219 //public int switchThink (Actor me) { return me.switchThink(&funcdummy); }
220 public void switchThink (Actor me, void function (Actor me) actcb) {
221   if (me.dead) return;
222   if (me.atm > 0) {
223     --me.atm;
224   } else {
225     me.atm = 0; // just in case
226     actcb(me);
227   }
231 public void switchTrapCooldown (Actor me) {
232   if (me.dead) return;
233   int d = me.switchGetD();
234   if (!d) return;
235   int a = me.switchGetA();
236   int b = me.switchGetB();
237   if (mapGetTypeTile(a, b) != TILE_DOORC) {
238     me.switchSetD(0);
239     return;
240   }
241   if (--d == 0) {
242     switchOpenDoor(me);
243     me.atm = 18;
244   }
245   me.switchSetD(d);
249 public void switchDoorCloseCooldown (Actor me) {
250   if (me.dead) return;
251   int d = me.switchGetD();
252   if (!d) return;
253   int a = me.switchGetA();
254   int b = me.switchGetB();
255   if (mapGetTypeTile(a, b) != TILE_DOORO) {
256     me.switchSetD(0);
257     return;
258   }
259   if (--d == 0 && !me.switchShutDoor) d = 9;
260   me.switchSetD(d);
264 public void switchToggleDoor (Actor me) {
265   if (me.dead) return;
266   int a = me.switchGetA();
267   int b = me.switchGetB();
268   switch (mapGetTypeTile(a, b)) {
269     case TILE_DOORC:
270       me.switchOpenDoor;
271       me.atm = 9; // cooldown time
272       me.switchSetD(me.classname == "Door5" ? 90 : 0);
273       break;
274     case TILE_DOORO:
275       if (me.switchShutDoor) {
276         me.atm = 9; // cooldown time
277         me.switchSetD(0);
278       } else {
279         //if (!swsnd) swsnd = Z_sound(sndnoway, 128);
280         me.switchSetD(2);
281       }
282       break;
283     default:
284   }