2
Copyright (C) 1994-1995 Apogee Software, Ltd.
4
This program is free software; you can redistribute it and/or
5
modify it under the terms of the GNU General Public License
6
as published by the Free Software Foundation; either version 2
7
of the License, or (at your option) any later version.
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
See the GNU General Public License for more details.
15
You should have received a copy of the GNU General Public License
16
along with this program; if not, write to the Free Software
17
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
48
/*=============================================================================
52
doorobjlist[] holds most of the information for the doors
54
Open doors conect two areas, so sounds will travel between them and sight
55
will be checked when the player is in a connected area.
57
Areaconnect is incremented/decremented by each door. If >0 they connect
59
Every time a door opens or closes the areabyplayer matrix gets recalculated.
60
An area is true if it connects with the player's current spor.
62
=============================================================================
69
#define ELEVATORMUSICTIME 560
71
elevator_t ELEVATOR[MAXELEVATORS];
73
animmaskedwallobj_t* FIRSTANIMMASKEDWALL,*LASTANIMMASKEDWALL;
74
maskedwallobj_t* FIRSTMASKEDWALL,*LASTMASKEDWALL;
75
byte touchindices[MAPSIZE][MAPSIZE],lasttouch;
76
touchplatetype *touchplate[MAXTOUCHPLATES],*lastaction[MAXTOUCHPLATES];
78
byte numactions[MAXTOUCHPLATES];
81
byte TRIGGER[MAXTOUCHPLATES];
82
doorobj_t *doorobjlist[MAXDOORS];
84
maskedwallobj_t *maskobjlist[MAXMASKED];
87
pwallobj_t *pwallobjlist[MAXPWALLS];
90
byte areaconnect[NUMAREAS][NUMAREAS];
92
boolean areabyplayer[NUMAREAS];
97
static void (*touchactions[NUMTOUCHPLATEACTIONS])(int) =
107
#if ((DEVELOPMENT == 1))
108
#if ((LOADSAVETEST == 1))
109
static char*touchstrings[NUMTOUCHPLATEACTIONS] =
121
#if ((DEVELOPMENT == 1))
122
#if ((ELEVATORTEST == 1))
124
static char*elevstring[NUMELEVATORACTIONS] =
126
"ready at destination",
128
"moving to destination",
134
void UtilizeDoor (int door,void (*action)(int));
135
void UseDoor (int door);
136
void Teleport(elevator_t*eptr,int destination);
137
void ConnectPushWall (int pwall);
138
void SetupPushWall (int pwall);
139
void WallMoving (int pwall);
140
int SetNextAction(elevator_t*eptr,int action);
145
= MakeMaskedWallActive
150
void MakeMaskedWallActive(maskedwallobj_t* tmwall)
151
{if (!FIRSTMASKEDWALL)
152
FIRSTMASKEDWALL = tmwall;
154
{tmwall->prev = LASTMASKEDWALL;
155
LASTMASKEDWALL->next = tmwall;
157
LASTMASKEDWALL = tmwall;
163
= MakeMaskedWallInactive
169
void MakeMaskedWallInactive(maskedwallobj_t* tmwall)
171
if (tmwall == LASTMASKEDWALL)
172
LASTMASKEDWALL = tmwall->prev;
174
tmwall->next->prev = tmwall->prev;
176
if (tmwall == FIRSTMASKEDWALL)
177
FIRSTMASKEDWALL = tmwall->next;
179
tmwall->prev->next = tmwall->next;
190
= ActivateAnimMaskedWall
195
void ActivateAnimMaskedWall(animmaskedwallobj_t* amwall)
197
if (!FIRSTANIMMASKEDWALL)
198
FIRSTANIMMASKEDWALL = amwall;
201
amwall->prev = LASTANIMMASKEDWALL;
202
LASTANIMMASKEDWALL->next = amwall;
204
LASTANIMMASKEDWALL = amwall;
210
= DeactivateAnimMaskedWall
216
void DeactivateAnimMaskedWall(animmaskedwallobj_t* amwall)
218
if (amwall == LASTANIMMASKEDWALL)
219
LASTANIMMASKEDWALL = amwall->prev;
221
amwall->next->prev = amwall->prev;
223
if (amwall == FIRSTANIMMASKEDWALL)
224
FIRSTANIMMASKEDWALL = amwall->next;
226
amwall->prev->next = amwall->next;
234
int PlatformHeight(int tilex,int tiley)
238
if (!IsPlatform(tilex,tiley))
239
return nominalheight;
241
platform = MAPSPOT(tilex,tiley,2);
248
return nominalheight;
251
return nominalheight - 64;
253
return nominalheight;
262
void SpawnAnimatedMaskedWall ( int num )
264
animmaskedwallobj_t * temp;
266
temp = (animmaskedwallobj_t *)Z_LevelMalloc(sizeof(animmaskedwallobj_t),PU_LEVELSTRUCT,NULL);
268
Error("SpawnAnimatedMaskedWall: Failed on allocation of animated masked wall");
270
temp->count=AMW_NUMFRAMES;
271
temp->ticcount=AMW_TICCOUNT;
274
ActivateAnimMaskedWall(temp);
277
void KillAnimatedMaskedWall ( animmaskedwallobj_t * temp )
279
DeactivateAnimMaskedWall(temp);
284
void DoAnimatedMaskedWalls ( void )
287
animmaskedwallobj_t * temp;
289
for(temp=FIRSTANIMMASKEDWALL;temp;)
292
temp->ticcount-=tics;
293
while (temp->ticcount<0)
295
temp->ticcount+=AMW_TICCOUNT;
297
maskobjlist[temp->num]->bottomtexture++;
306
animmaskedwallobj_t * temp2;
309
KillAnimatedMaskedWall(temp);
318
int GetIndexForAction(void (*action)(int))
321
for(i=0;i<NUMTOUCHPLATEACTIONS;i++)
322
if (action == touchactions[i])
325
Error("Touchplate Action Not Matched");
330
void SaveTouchPlates(byte ** buffer,int *size)
333
touchplatetype *temp;
334
saved_touch_type dummy;
336
*size = sizeof(TRIGGER);
337
*size += sizeof(numactions);
338
*size += sizeof(saved_touch_type)*totalactions;
340
*buffer = (byte *)SafeMalloc(*size);
342
memcpy(tptr,&TRIGGER[0],sizeof(TRIGGER));
343
tptr+=sizeof(TRIGGER);
345
memcpy(tptr,&numactions[0],sizeof(numactions));
346
tptr+=sizeof(numactions);
348
#if ((DEVELOPMENT == 1))
349
#if (LOADSAVETEST == 1)
350
Debug("\n\nSAVE INFO\n");
353
Debug("\n\nTOUCHINDICES\n");
354
Debug("------------\n\n");
355
for(i=0;i<MAPSIZE;i++)
356
for(j=0;j< MAPSIZE;j++)
357
if (touchindices[i][j])
358
Debug("\ntouchindices[%3d][%3d]: %d",i,j,touchindices[i][j]);
360
Debug("\n\nTRIGGER: ");
361
for(i=0;i<(sizeof(TRIGGER)/sizeof(TRIGGER[0]));i++)
363
Debug("%1d",TRIGGER[i]);
364
Debug("\n\nNUMACTIONS PER TOUCHPLATE\n");
365
Debug("-------------------------\n\n");
366
for(i=0;i<(sizeof(numactions)/sizeof(numactions[0]));i++)
368
Debug("\n %2d: %2d",i,numactions[i]);
372
for(i=0;i<lasttouch;i++)
374
#if ((DEVELOPMENT == 1))
375
#if (LOADSAVETEST == 1)
376
Debug("\n\nTOUCHPLATE[%2d]\n",i);
377
Debug("--------------\n\n");
381
for(k=0,temp=touchplate[i];temp;k++,temp = temp->nextaction)
383
dummy.tictime = temp->tictime;
384
dummy.ticcount = temp->ticcount;
385
dummy.triggered = temp->triggered;
386
dummy.done = temp->done;
387
dummy.complete = temp->complete;
390
dummy.actionindex = GetIndexForAction(temp->action);
392
dummy.actionindex = -1;
394
if (temp->swapaction)
395
dummy.swapactionindex = GetIndexForAction(temp->swapaction);
397
dummy.swapactionindex = -1;
398
if ((dummy.actionindex > 5) || (dummy.swapactionindex > 5)) // means whichobj holds pointer to actor
402
tstat = (statobj_t*)(temp->whichobj);
403
dummy.whichobj = (tstat->whichstat|FL_TSTAT);
406
else if ((dummy.actionindex > 3) || (dummy.swapactionindex > 3))
411
tactor = (objtype*)(temp->whichobj);
412
dummy.whichobj = (tactor->whichactor|FL_TACT);
416
dummy.whichobj = temp->whichobj;
418
#if ((DEVELOPMENT == 1))
419
#if (LOADSAVETEST == 1)
420
Debug("action node %d: tictime: %d, ticcount: %d ",k,dummy.tictime,dummy.ticcount);
421
if (dummy.actionindex == -1)
422
Debug("action: -1,");
424
Debug("action: %13s,",touchstrings[dummy.actionindex]);
426
if (dummy.swapactionindex == -1)
427
Debug("swapaction: -1,");
429
Debug("swapaction: %13s,",touchstrings[dummy.swapactionindex]);
431
if (dummy.whichobj & FL_TACT)
432
Debug("whichobj (actor): %4x\n",(dummy.whichobj & ~FL_TACT));
434
Debug("whichobj (nonactor): %4x\n",dummy.whichobj);
439
memcpy(tptr,&dummy,sizeof(saved_touch_type));
440
tptr+=sizeof(saved_touch_type);
445
statobj_t* GetStatForIndex(int index)
448
for(temp = FIRSTSTAT;temp;temp=temp->statnext)
449
if (temp->whichstat == index)
452
SoftError("\nstat not found in GetStatForIndex");
458
void LoadTouchPlates(byte * buffer, int size)
459
{touchplatetype *temp;
460
int i,savedactions,loadedactions,index=0;
461
saved_touch_type dummy;
463
savedactions = (size-sizeof(TRIGGER)-sizeof(numactions))/sizeof(saved_touch_type);
464
memset(touchplate,0,sizeof(touchplate));
465
memset(lastaction,0,sizeof(lastaction));
466
memset(numactions,0,sizeof(numactions));
469
memcpy(&TRIGGER[0],buffer,sizeof(TRIGGER));
470
buffer += sizeof(TRIGGER);
472
memcpy(&numactions[0],buffer,sizeof(numactions));
473
buffer += sizeof(numactions);
475
for(loadedactions=0,index=0,i=0;i<savedactions;i++)
476
{memcpy(&dummy,buffer,sizeof(saved_touch_type));
477
temp = (touchplatetype*)Z_LevelMalloc(sizeof(touchplatetype),PU_LEVELSTRUCT,NULL);
479
Error("LoadTouchplates: Failed on allocation of touchplates %ld of %ld",i,savedactions);
480
memset(temp,0,sizeof(*temp));
482
temp->tictime = dummy.tictime;
483
temp->ticcount = dummy.ticcount;
484
temp->triggered = dummy.triggered;
485
temp->done = dummy.done;
486
temp->complete = dummy.complete;
488
if (dummy.whichobj & FL_TACT)
489
temp->whichobj = (int)(objlist[dummy.whichobj & ~FL_TACT]);
491
else if (dummy.whichobj & FL_TSTAT)
492
temp->whichobj = (int)(GetStatForIndex(dummy.whichobj & ~FL_TSTAT));
494
temp->whichobj = dummy.whichobj;
495
if (dummy.actionindex != -1)
496
temp->action = touchactions[dummy.actionindex];
500
if (dummy.swapactionindex != -1)
501
temp->swapaction = touchactions[dummy.swapactionindex];
503
temp->swapaction = NULL;
505
buffer+=sizeof(saved_touch_type);
507
while (!numactions[index])
510
AddTouchplateAction(temp,index);
512
/*if (touchplate[index])
513
lastaction[index]->nextaction = temp;
515
touchplate[index] = temp;
516
lastaction[index] = temp;*/
521
if (loadedactions == numactions[index]) // found end of a touchplate's actions, goto next touch.
528
#if ((DEVELOPMENT == 1))
529
#if (LOADSAVETEST == 1)
530
Debug("\n\nLOAD INFO\n");
533
Debug("\n\nTOUCHINDICES\n");
534
Debug("------------\n\n");
535
for(i=0;i<MAPSIZE;i++)
536
for(j=0;j< MAPSIZE;j++)
537
if (touchindices[i][j])
538
Debug("\ntouchindices[%3d][%3d]: %d",i,j,touchindices[i][j]);
540
Debug("\n\nTRIGGER: ");
541
for(i=0;i<(sizeof(TRIGGER)/sizeof(TRIGGER[0]));i++)
543
Debug("%1d",TRIGGER[i]);
544
Debug("\n\nNUMACTIONS PER TOUCHPLATE\n");
545
Debug("-------------------------\n\n");
546
for(i=0;i<(sizeof(numactions)/sizeof(numactions[0]));i++)
548
Debug("\n %2d: %2d",i,numactions[i]);
550
for(i=0;i<lasttouch;i++)
552
Debug("\n\nTOUCHPLATE[%2d]\n",i);
553
Debug("--------------\n\n");
555
for(k=0,temp=touchplate[i];temp;k++,temp = temp->nextaction)
557
Debug("action node %d: tictime: %d, ticcount: %d ",k,temp->tictime,temp->ticcount);
559
Debug("action: NULL,");
561
Debug("action: %13s,",touchstrings[GetIndexForAction(temp->action)]);
563
if (!temp->swapaction)
564
Debug("swapaction: NULL,");
566
Debug("swapaction: %13s,",touchstrings[GetIndexForAction(temp->swapaction)]);
568
Debug("whichobj: %4x\n",(int)temp->whichobj);
581
void AddTouchplateAction(touchplatetype *tplate,int index)
583
if (touchplate[index])
584
{tplate->prevaction = lastaction[index];
585
lastaction[index]->nextaction = tplate;
588
touchplate[index] = tplate;
589
lastaction[index] = tplate;
596
void RemoveTouchplateAction(touchplatetype *tplate,int index)
598
if (tplate == lastaction[index]) // remove from master list
599
lastaction[index] = tplate->prevaction;
601
tplate->nextaction->prevaction = tplate->prevaction;
603
if (tplate == touchplate[index])
604
touchplate[index] = tplate->nextaction;
606
tplate->prevaction->nextaction = tplate->nextaction;
616
void Link_To_Touchplate(word touchlocx, word touchlocy, void (*maction)(int), void (*swapaction)(int), int wobj, int delaytime)
617
{touchplatetype *temp;
620
index = touchindices[touchlocx][touchlocy]-1;
622
temp = (touchplatetype*)Z_LevelMalloc(sizeof(touchplatetype),PU_LEVELSTRUCT,NULL);
624
Error("Link_To_Touchplate: Failed on allocation of touchplate\n");
625
memset(temp,0,sizeof(*temp));
626
temp->action = maction;
627
temp->swapaction = swapaction;
628
temp->whichobj = wobj;
629
temp->tictime = temp->ticcount = delaytime;
631
AddTouchplateAction(temp,index);
632
/*if(touchplate[index])
633
lastaction[index]->nextaction=temp;
635
touchplate[index] = temp;
636
lastaction[index] = temp;*/
643
void ClockLink (void (*saction)(int), void (*eaction)(int), int wobj,int whichclock)
644
{touchplatetype*temp;
647
// adding two actions per clock
648
temp = (touchplatetype*)Z_LevelMalloc(sizeof(touchplatetype),PU_LEVELSTRUCT,NULL);
650
Error("ClockLink: Failed on allocation of clock");
651
memset(temp,0,sizeof(*temp));
652
temp->action = saction;
653
temp->swapaction = eaction;
654
temp->whichobj = wobj;
657
AddTouchplateAction(temp,whichclock);
658
/* if(touchplate[whichclock])
659
lastaction[whichclock]->nextaction = temp;
661
touchplate[whichclock] = temp;
662
lastaction[whichclock]=temp;*/
664
numactions[whichclock]++;
669
void DisplayMessageForAction(touchplatetype *temp, boolean *wallmessage,
670
boolean *doormessage, boolean*columnmessage)
673
if ((temp->action == ActivatePushWall) ||
674
(temp->action == ActivateMoveWall)
677
if (*wallmessage == false)
680
AddMessage("Time-delay wall moves.",MSG_GAME);
682
AddMessage("A wall moves.",MSG_GAME);
687
else if (temp->action == LinkedCloseDoor)
689
if (*doormessage == false)
692
AddMessage("Time-delay door closes.",MSG_GAME);
694
AddMessage("A door closes.",MSG_GAME);
699
else if (temp->action == LinkedOpenDoor)
701
if (*doormessage == false)
704
AddMessage("Time-delay door opens.",MSG_GAME);
706
AddMessage("A door opens.",MSG_GAME);
711
else if (temp->action == EnableObject)
713
objtype *tempactor = (objtype*)(temp->whichobj);
715
if (M_ISACTOR(tempactor) && (tempactor->obclass == pillarobj))
717
if (*columnmessage == false)
720
AddMessage("Time-delay column moves.",MSG_GAME);
722
AddMessage("A column moves.",MSG_GAME);
723
*columnmessage = true;
729
void TriggerStuff(void)
731
touchplatetype *temp;
732
int i,touchcomplete,j;
734
void (*tempact)(int);
735
boolean wallmessage,doormessage,columnmessage;
737
for(i=0;i<lasttouch;i++)
740
for( j = 0; j < numplayers; j++ )
742
if ( i == touchindices[ PLAYER[ j ]->tilex ][ PLAYER[ j ]->tiley ] - 1 )
753
else if (touchplate[i]->complete)
760
if (touchplate[i]->done)
764
for(temp = touchplate[i];temp;temp = temp->nextaction)
765
temp->triggered=false;
767
touchplate[i]->done = false;
775
columnmessage = false;
777
for(temp = touchplate[i];temp;temp = temp->nextaction)
779
if (temp->action && (!temp->triggered))
783
temp->action(temp->whichobj);
784
if (temp->action == ActivateMoveWall)
788
tilex = pwallobjlist[temp->whichobj]->tilex;
789
tiley = pwallobjlist[temp->whichobj]->tiley;
790
tilemap[tilex][tiley] = 0;
793
if (gamestate.difficulty == gd_baby)
795
DisplayMessageForAction(temp,&wallmessage,&doormessage,&columnmessage);
798
tempact = temp->action;
799
temp->action = temp->swapaction;
800
temp->swapaction = tempact;
801
temp->ticcount = temp->tictime;
802
temp->triggered = true;
811
// check to see if any actions will ever be triggered by this
812
// touchplate again; if not, null touchplate out; else,
813
// check status of other actions
816
for(temp = touchplate[i];temp;temp = temp->nextaction)
826
touchplate[i]->complete = 1; // this touchplate is out of commission
829
touchplate[i]->done = true;
830
for(temp = touchplate[i];temp;temp = temp->nextaction)
832
if (temp->action && (!temp->triggered))
834
touchplate[i]->done = false;
844
//==================== Tile stuff ====================================
846
boolean CheckTile(int x, int y)
849
if ((x < 2) || (x > (MAPSIZE-1)) || (y < 2) || (y > (MAPSIZE - 1)))
853
{objtype *check = (objtype*)(actorat[x][y]);
856
if (!(M_ISACTOR(check) && (check->obclass == playerobj)))
863
if ((tilemap[x][y]) && (IsPlatform(x,y)==false))
865
if ((AREANUMBER(x,y)<=0) || (AREANUMBER(x,y)>NUMAREAS))
873
#define CountTile(x,y) \
875
if (oldarea == AREANUMBER(x,y))\
876
{if (CheckTile(x,y)) \
880
if (areanumbercount == numareatiles[oldarea])\
881
return numemptytiles; \
887
int Number_of_Empty_Tiles_In_Area_Around(int x, int y)
888
{int roverx,rovery,areanumbercount=0,
889
numemptytiles=0,oldarea,i,limit,j;
891
oldarea = AREANUMBER(x,y);
897
CountTile(roverx,rovery);
902
CountTile(roverx,rovery);
907
CountTile(roverx,rovery);
912
CountTile(roverx,rovery);
915
for(j=0;j<limit-1;j++)
917
CountTile(roverx,rovery);
924
#define CheckSet(x,y) \
925
{if (CheckTile(x,y) && (oldarea == AREANUMBER(x,y))) \
934
void FindEmptyTile(int *stilex, int *stiley)
936
int i,j,x,y,oldarea,roverx,rovery,limit;
938
oldarea = AREANUMBER(*stilex,*stiley);
943
if (CheckTile(x,y) && (oldarea == AREANUMBER(x,y)))
950
CheckSet(roverx,rovery);
955
CheckSet(roverx,rovery);
960
CheckSet(roverx,rovery);
965
CheckSet(roverx,rovery);
968
for(j=0;j<limit-1;j++)
970
CheckSet(roverx,rovery);
975
//================================================================
980
void RecursiveConnect (int areanumber)
984
for (i=0;i<NUMAREAS;i++)
986
if (areaconnect[areanumber][i] && !areabyplayer[i])
988
areabyplayer[i] = true;
989
RecursiveConnect (i);
1000
= Scans outward from playerarea, marking all connected areas
1005
void ConnectAreas (void)
1009
#define MASTER_DISK(ob) ((ob->obclass == diskobj) && (ob->flags & FL_MASTER))
1011
memset (areabyplayer,0,sizeof(areabyplayer));
1012
for (i=0;i<numplayers;i++)
1014
areabyplayer[PLAYER[i]->areanumber] = true;
1015
RecursiveConnect (PLAYER[i]->areanumber);
1017
for(temp=FIRSTACTOR;temp;temp=temp->next)
1019
if (MASTER_DISK(temp))
1021
if (!areabyplayer[temp->areanumber])
1023
if (!(temp->flags & FL_ABP))
1024
{temp->flags |= FL_ABP;
1029
for(tstat=FIRSTSTAT;tstat;tstat=tstat->statnext)
1030
{if (areabyplayer[tstat->areanumber])
1031
{if (!(tstat->flags & FL_ABP))
1032
{tstat->flags |= FL_ABP;
1033
MakeStatActive(tstat);
1036
else if (tstat->flags & FL_ABP)
1037
{MakeStatInactive(tstat);
1038
tstat->flags &= ~FL_ABP;
1042
for(i=0;i<maskednum;i++)
1043
{if (areabyplayer[maskobjlist[i]->areanumber])
1044
{if (!(maskobjlist[i]->flags & MW_ABP))
1045
{maskobjlist[i]->flags |= MW_ABP;
1046
MakeMaskedWallActive(maskobjlist[i]);
1049
else if (maskobjlist[i]->flags & MW_ABP)
1050
{MakeMaskedWallInactive(maskobjlist[i]);
1051
maskobjlist[i]->flags &= ~MW_ABP;
1057
void InitAreas (void)
1059
memset (areabyplayer,0,sizeof(areabyplayer));
1060
memset (areaconnect,0,sizeof(areaconnect));
1072
void InitDoorList (void)
1080
memset(touchindices,0,sizeof(touchindices));
1081
memset(touchplate,0,sizeof(touchplate));
1082
memset(lastaction,0,sizeof(lastaction));
1083
memset(numactions,0,sizeof(numactions));
1085
memset(TRIGGER,0,sizeof(TRIGGER));
1086
memset(Clocks,0,sizeof(Clocks));
1087
FIRSTMASKEDWALL=NULL;
1088
LASTMASKEDWALL=NULL;
1089
FIRSTANIMMASKEDWALL=NULL;
1090
LASTANIMMASKEDWALL=NULL;
1101
int IsWall (int tilex, int tiley)
1105
map=MAPSPOT(tilex,tiley,0);
1107
if ((map>=1) && (map<=89))
1110
else if ((map>=106) && (map<=107))
1113
else if ((map>=224) && (map<=233))
1116
else if ((map>=242) && (map<=244))
1132
void InitElevators(void)
1134
memset(ELEVATOR,0,sizeof(ELEVATOR));
1148
int IsDoor (int tilex, int tiley)
1152
map=MAPSPOT(tilex,tiley,0);
1154
if ((map>=33) && (map<=35))
1157
if ((map>=90) && (map<=104))
1160
if ((map>=154) && (map<=156))
1163
if (M_ISDOOR(tilex,tiley))
1178
void SpawnDoor (int tilex, int tiley, int lock, int texture)
1181
doorobj_t * lastdoorobj;
1187
abovewallstart=W_GetNumForName("ABVWSTRT")+1;
1188
swallstart=W_GetNumForName("SIDESTRT")+1;
1190
doorobjlist[doornum]=(doorobj_t*)Z_LevelMalloc(sizeof(doorobj_t),PU_LEVELSTRUCT,NULL);
1191
if (!doorobjlist[doornum])
1192
Error("SpawnDoor: Failed on allocation of door %ld ",doornum);
1193
memset(doorobjlist[doornum],0,sizeof(doorobj_t));
1194
lastdoorobj=doorobjlist[doornum];
1197
( MAPSPOT(tilex,tiley,1) >= 29 ) &&
1198
( MAPSPOT(tilex,tiley,1) <= 32 )
1201
lock = MAPSPOT(tilex,tiley,1) - 28;
1204
lastdoorobj->position = 0;
1205
lastdoorobj->tilex = tilex;
1206
lastdoorobj->tiley = tiley;
1207
lastdoorobj->lock = lock;
1208
lastdoorobj->action = dr_closed;
1209
lastdoorobj->which = DOOR;
1210
lastdoorobj->flags = 0;
1211
lastdoorobj->eindex = -1;
1214
// make the door space solid
1217
if (loadedgame==false)
1218
actorat[tilex][tiley] = lastdoorobj;
1220
if (IsDoor(tilex,tiley-1)) up=2;
1221
else if (IsWall(tilex,tiley-1)) up=1;
1224
if (IsDoor(tilex,tiley+1)) dn=2;
1225
else if (IsWall(tilex,tiley+1)) dn=1;
1228
if (IsDoor(tilex-1,tiley)) lt=2;
1229
else if (IsWall(tilex-1,tiley)) lt=1;
1232
if (IsDoor(tilex+1,tiley)) rt=2;
1233
else if (IsWall(tilex+1,tiley)) rt=1;
1236
if ((up==1) && (dn==1))
1237
lastdoorobj->vertical = true;
1238
else if ((lt==1) && (rt==1))
1239
lastdoorobj->vertical = false;
1240
else if ((up>0) && (dn>0))
1241
lastdoorobj->vertical = true;
1242
else if ((lt>0) && (rt>0))
1243
lastdoorobj->vertical = false;
1245
lastdoorobj->vertical = true;
1247
lastdoorobj->vertical = true;
1249
lastdoorobj->vertical = false;
1251
lastdoorobj->vertical = false;
1258
basetexture = W_GetNumForName("RAMDOOR1\0");
1263
basetexture = W_GetNumForName("DOOR2\0");
1270
basetexture = W_GetNumForName("TRIDOOR1\0");
1276
basetexture = W_GetNumForName("SDOOR4\0");
1282
basetexture = W_GetNumForName("EDOOR\0");
1285
basetexture = W_GetNumForName("SNDOOR\0");
1288
basetexture = W_GetNumForName("SNADOOR\0");
1291
basetexture = W_GetNumForName("SNKDOOR\0");
1295
basetexture = W_GetNumForName("TNDOOR\0");
1298
basetexture = W_GetNumForName("TNADOOR\0");
1301
basetexture = W_GetNumForName("TNKDOOR\0");
1304
Error("Illegal door value encountered\n");
1307
lastdoorobj->basetexture = basetexture;
1308
lastdoorobj->texture = lastdoorobj->basetexture;
1310
SD_PreCacheSoundGroup(SD_OPENDOORSND,SD_CLOSEDOORSND);
1313
// make the door tile a special tile, and mark the adjacent tiles
1316
tilemap[tilex][tiley] = doornum | 0x8000;
1331
lastdoorobj->sidepic = W_GetNumForName("SIDE8");
1332
lastdoorobj->alttexture = W_GetNumForName("ABOVEW3");
1338
#if (SHAREWARE == 1)
1339
lastdoorobj->sidepic = W_GetNumForName("SIDE8");
1342
lastdoorobj->sidepic = W_GetNumForName("SIDE16");
1345
lastdoorobj->alttexture = W_GetNumForName("ABOVEW16");
1351
#if (SHAREWARE == 1)
1352
lastdoorobj->sidepic = W_GetNumForName("SIDE8");
1353
lastdoorobj->alttexture = W_GetNumForName("ABOVEW3");
1356
lastdoorobj->sidepic = W_GetNumForName("SIDE17");
1357
lastdoorobj->alttexture = W_GetNumForName("ABOVEW17");
1363
Error("Illegal door value encountered\n");
1369
if ((lock>0) && (lock<5))
1370
lastdoorobj->sidepic = W_GetNumForName("lock1")+lock-1;
1372
PreCacheLump(lastdoorobj->sidepic,PU_CACHEWALLS);
1373
PreCacheLump(lastdoorobj->alttexture,PU_CACHEWALLS);
1375
if (lastdoorobj->vertical==true)
1378
tilemap[tilex][tiley-1] |= 0x4000;
1380
lastdoorobj->flags|=DF_MULTI;
1382
tilemap[tilex][tiley+1] |= 0x4000;
1384
lastdoorobj->flags|=DF_MULTI;
1389
tilemap[tilex-1][tiley] |= 0x4000;
1391
lastdoorobj->flags|=DF_MULTI;
1393
tilemap[tilex+1][tiley] |= 0x4000;
1395
lastdoorobj->flags|=DF_MULTI;
1399
PreCacheLump(lastdoorobj->texture+i,PU_CACHEWALLS);
1402
if (doornum==MAXDOORS)
1403
Error ("Too many doors on level!");
1410
= MakeWideDoorVisible
1414
void MakeWideDoorVisible ( int doornum )
1421
dr=doorobjlist[doornum];
1424
if (dr->vertical==true)
1428
spotvis[dr->tilex][dr->tiley]=1;
1431
while (M_ISDOOR(tx,ty))
1435
num=tilemap[tx][ty]&0x3ff;
1436
dr2=doorobjlist[num];
1437
if (!(dr2->flags&DF_MULTI))
1446
while (M_ISDOOR(tx,ty))
1450
num=tilemap[tx][ty]&0x3ff;
1451
dr2=doorobjlist[num];
1452
if (!(dr2->flags&DF_MULTI))
1462
=====================
1466
=====================
1469
void LockLinkedDoor (int door)
1473
dptr = doorobjlist[door];
1479
=====================
1483
=====================
1486
boolean IsDoorLinked (int door)
1490
dptr = doorobjlist[door];
1500
= FixDoorAreaNumbers
1504
void FixDoorAreaNumbers ( void )
1510
for (i=0;i<doornum;i++)
1512
tilex=doorobjlist[i]->tilex;
1513
tiley=doorobjlist[i]->tiley;
1514
up=MAPSPOT(tilex,tiley-1,0)-AREATILE;
1515
dn=MAPSPOT(tilex,tiley+1,0)-AREATILE;
1516
lt=MAPSPOT(tilex-1,tiley,0)-AREATILE;
1517
rt=MAPSPOT(tilex+1,tiley,0)-AREATILE;
1519
up = ((up>0) && (up<=NUMAREAS));
1520
dn = ((dn>0) && (dn<=NUMAREAS));
1521
lt = ((lt>0) && (lt<=NUMAREAS));
1522
rt = ((rt>0) && (rt<=NUMAREAS));
1525
if (doorobjlist[i]->vertical==true)
1528
MAPSPOT(tilex,tiley,0) = MAPSPOT(tilex+1,tiley,0);
1530
MAPSPOT(tilex,tiley,0) = MAPSPOT(tilex-1,tiley,0);
1532
Error("FixDoors: Couldn't fix up area at x=%ld y=%ld\n",tilex,tiley);
1537
MAPSPOT(tilex,tiley,0) = MAPSPOT(tilex,tiley+1,0);
1539
MAPSPOT(tilex,tiley,0) = MAPSPOT(tilex,tiley-1,0);
1541
Error("FixDoors: Couldn't fix up area at x=%ld y=%ld\n",tilex,tiley);
1543
if (IsDoorLinked(i))
1544
UtilizeDoor(i,LockLinkedDoor);
1549
//===========================================================================
1552
=====================
1556
=====================
1559
void OpenDoor (int door)
1561
if (doorobjlist[door]->action == dr_open)
1562
doorobjlist[door]->ticcount = 0; // reset open time
1565
doorobjlist[door]->action = dr_opening; // start it opening
1570
=====================
1574
=====================
1577
boolean DoorUnBlocked (int door)
1583
dptr = doorobjlist[door];
1586
// don't close on anything solid
1589
tilex = dptr->tilex;
1590
tiley = dptr->tiley;
1591
check = (objtype*)actorat[tilex][tiley];
1593
if (check && (check->which == ACTOR))
1596
if (dptr->vertical==true)
1598
check = (objtype*)actorat[tilex-1][tiley];
1599
if (check && (check->which==ACTOR) && ((check->x+MINDIST) >> TILESHIFT) == tilex )
1601
check = (objtype*)actorat[tilex+1][tiley];
1602
if (check && (check->which==ACTOR) && ((check->x-MINDIST) >> TILESHIFT) == tilex )
1605
else if (dptr->vertical==false)
1607
check = (objtype*)actorat[tilex][tiley-1];
1608
if (check && (check->which==ACTOR) && ((check->y+MINDIST) >> TILESHIFT) == tiley )
1610
check = (objtype*)actorat[tilex][tiley+1];
1611
if (check && (check->which==ACTOR) && ((check->y-MINDIST) >> TILESHIFT) == tiley )
1619
=====================
1623
= Alter the door's state
1625
=====================
1628
boolean DoorReadyToClose(int door)
1636
dptr = doorobjlist[door];
1638
if (dptr->action==dr_closed)
1641
if (DoorUnBlocked(door)==false)
1645
if (dptr->vertical==true)
1651
while (M_ISDOOR(tx,ty))
1655
num=tilemap[tx][ty]&0x3ff;
1656
dr2=doorobjlist[num];
1657
if (!(dr2->flags&DF_MULTI))
1659
if (DoorUnBlocked(num)==false)
1666
while (M_ISDOOR(tx,ty))
1670
num=tilemap[tx][ty]&0x3ff;
1671
dr2=doorobjlist[num];
1672
if (!(dr2->flags&DF_MULTI))
1674
if (DoorUnBlocked(num)==false)
1684
=====================
1688
=====================
1691
void CloseDoor (int door)
1693
int tilex,tiley,area;
1696
dptr = doorobjlist[door];
1697
if (dptr->action == dr_closed)
1699
tilex = dptr->tilex;
1700
tiley = dptr->tiley;
1705
area = MAPSPOT(tilex,tiley,0)-AREATILE;
1706
if (areabyplayer[area])
1708
dptr->soundhandle=SD_PlaySoundRTP ( SD_CLOSEDOORSND, dptr->tilex<<16, dptr->tiley<<16 );
1711
dptr->action = dr_closing;
1713
// make the door space solid
1715
actorat[tilex][tiley] = dptr;
1721
=====================
1725
= The player wants to change the door's direction
1727
=====================
1730
void OperateDoor (int keys, int door, boolean localplayer )
1735
dptr = doorobjlist[door];
1736
if ( ( dptr->flags & DF_ELEVLOCKED ) ||
1737
( MISCVARS->GASON && ( MAPSPOT( dptr->tilex,
1738
dptr->tiley, 1 ) == GASVALUE ) ) )
1743
SD_Play ( SD_NOITEMSND );
1749
if ( lock && !( keys & ( 1 << ( lock - 1 ) ) ) )
1757
AddMessage("You need the \\EGOLD key",MSG_DOOR);
1761
AddMessage("You need the \\FSILVER key",MSG_DOOR);
1765
AddMessage("You need the \\8IRON key",MSG_DOOR);
1769
AddMessage("You need the \\AOSCURO key",MSG_DOOR);
1773
AddMessage("This door appears to be locked",MSG_DOOR);
1777
SD_Play( SD_NOITEMSND );
1785
=====================
1789
=====================
1792
void LinkedOpenDoor (int door)
1794
UtilizeDoor(door,OpenDoor);
1798
=====================
1802
=====================
1805
void LinkedCloseDoor (int door)
1807
if (DoorReadyToClose(door)==true)
1808
UtilizeDoor(door,CloseDoor);
1812
=====================
1816
= Alter the door's state
1818
=====================
1821
void UtilizeDoor (int door,void (*action)(int))
1828
dptr = doorobjlist[door];
1833
if (dptr->vertical==true)
1839
while (M_ISDOOR(tx,ty))
1843
num=tilemap[tx][ty]&0x3ff;
1844
dr2=doorobjlist[num];
1845
if (!(dr2->flags&DF_MULTI))
1853
while (M_ISDOOR(tx,ty))
1857
num=tilemap[tx][ty]&0x3ff;
1858
dr2=doorobjlist[num];
1859
if (!(dr2->flags&DF_MULTI))
1868
=====================
1872
= Alter the door's state
1874
=====================
1877
void UseDoor (int door)
1879
switch (doorobjlist[door]->action)
1882
SD_StopSound(doorobjlist[door]->soundhandle);
1884
UtilizeDoor(door,OpenDoor);
1887
SD_StopSound(doorobjlist[door]->soundhandle);
1889
if (DoorReadyToClose(door)==true)
1890
UtilizeDoor(door,CloseDoor);
1895
//===========================================================================
1902
= Close the door after three seconds
1907
void DoorOpen (int door)
1910
dptr = doorobjlist[door];
1911
dptr->ticcount += 1;
1912
if ((dptr->ticcount >= OPENTICS) &&
1913
(!(dptr->flags & DF_TIMED)) &&
1914
(DoorReadyToClose(door)==true))
1915
UtilizeDoor(door,CloseDoor);
1928
void DoorOpening (int door)
1935
position = doorobjlist[door]->position;
1936
tilex = doorobjlist[door]->tilex;
1937
tiley = doorobjlist[door]->tiley;
1941
// door is just starting to open, so connect the areas
1943
map = &MAPSPOT(tilex,tiley,0);
1945
if (doorobjlist[door]->vertical==true)
1952
area1 = *(map-mapwidth);
1953
area2 = *(map+mapwidth);
1957
areaconnect[area1][area2]++;
1958
areaconnect[area2][area1]++;
1959
if ((insetupgame==false) && (loadedgame==false))
1961
if (areabyplayer[area1])
1963
doorobjlist[door]->soundhandle=SD_PlaySoundRTP ( SD_OPENDOORSND, doorobjlist[door]->tilex<<16, doorobjlist[door]->tiley<<16 );
1968
// slide the door by an adaptive amount
1971
if (position >= 0xffff)
1974
// door is all the way open
1977
doorobjlist[door]->ticcount = 0;
1978
doorobjlist[door]->action = dr_open;
1979
if (doorobjlist[door] == actorat[tilex][tiley])
1980
actorat[tilex][tiley] = 0;
1983
doorobjlist[door]->position = position;
1984
doorobjlist[door]->texture=doorobjlist[door]->basetexture+((position+1)>>13);
1996
void DoorClosing (int door)
2004
dptr = doorobjlist[door];
2006
tilex = dptr->tilex;
2007
tiley = dptr->tiley;
2009
position = dptr->position;
2012
// slide the door by an adaptive amount
2015
if (position < (0xffff >> 1))
2016
ResolveDoorSpace(tilex,tiley);
2022
// door is closed all the way, so disconnect the areas
2026
dptr->action = dr_closed;
2030
map = &MAPSPOT(tilex,tiley,0);
2032
if (areabyplayer[(*map-AREATILE)])
2034
dptr->soundhandle=SD_PlaySoundRTP ( SD_DOORHITSND, dptr->tilex<<16, dptr->tiley<<16 );
2037
if (dptr->vertical==true)
2044
area1 = *(map-mapwidth);
2045
area2 = *(map+mapwidth);
2049
areaconnect[area1][area2]--;
2050
areaconnect[area2][area1]--;
2055
dptr->position = position;
2056
dptr->texture=dptr->basetexture+((position+1)>>13);
2067
int IsMaskedWall (int tilex, int tiley)
2071
if (IsPlatform(tilex,tiley))
2074
map=MAPSPOT(tilex,tiley,0);
2076
if ((map>=157) && (map<=160))
2079
if ((map>=162) && (map<=179))
2082
if (M_ISMWALL(tilex,tiley))
2097
void SpawnMaskedWall (int tilex, int tiley, int which, int flags)
2103
int side, middle, above, bottom;
2104
maskedwallobj_t * lastmaskobj;
2107
int abovemaskedwallstart;
2110
himask=W_GetNumForName("HMSKSTRT")+1;
2111
maskedstart=W_GetNumForName("MASKSTRT");
2112
abovemaskedwallstart=W_GetNumForName("ABVMSTRT");
2113
swallstart=W_GetNumForName("SIDESTRT");
2115
maskobjlist[maskednum]=(maskedwallobj_t*)Z_LevelMalloc(sizeof(maskedwallobj_t),PU_LEVELSTRUCT,NULL);
2116
memset(maskobjlist[maskednum],0,sizeof(maskedwallobj_t));
2117
lastmaskobj=maskobjlist[maskednum];
2121
lastmaskobj->tilex = tilex;
2122
lastmaskobj->tiley = tiley;
2123
lastmaskobj->which = MWALL;
2124
up=MAPSPOT(tilex,tiley-1,0)-AREATILE;
2125
dn=MAPSPOT(tilex,tiley+1,0)-AREATILE;
2126
lt=MAPSPOT(tilex-1,tiley,0)-AREATILE;
2127
rt=MAPSPOT(tilex+1,tiley,0)-AREATILE;
2129
if (IsMaskedWall(tilex,tiley-1)) up=2;
2130
else if (IsWall(tilex,tiley-1)) up=1;
2133
if (IsMaskedWall(tilex,tiley+1)) dn=2;
2134
else if (IsWall(tilex,tiley+1)) dn=1;
2137
if (IsMaskedWall(tilex-1,tiley)) lt=2;
2138
else if (IsWall(tilex-1,tiley)) lt=1;
2141
if (IsMaskedWall(tilex+1,tiley)) rt=2;
2142
else if (IsWall(tilex+1,tiley)) rt=1;
2145
if ((up==1) && (dn==1))
2146
lastmaskobj->vertical = true;
2147
else if ((lt==1) && (rt==1))
2148
lastmaskobj->vertical = false;
2149
else if ((up>0) && (dn>0))
2150
lastmaskobj->vertical = true;
2151
else if ((lt>0) && (rt>0))
2152
lastmaskobj->vertical = false;
2154
lastmaskobj->vertical = true;
2156
lastmaskobj->vertical = true;
2158
lastmaskobj->vertical = false;
2160
lastmaskobj->vertical = false;
2162
tilemap[tilex][tiley] = maskednum | 0xc000;
2163
map = &MAPSPOT(tilex,tiley,0);
2165
if (lastmaskobj->vertical==true)
2173
areaconnect[area1][area2]++;
2174
areaconnect[area2][area1]++;
2179
area1 = *(map-mapwidth);
2180
area2 = *(map+mapwidth);
2185
areaconnect[area1][area2]++;
2186
areaconnect[area2][area1]++;
2189
lastmaskobj->flags=flags;
2191
if (IsPlatform(tilex,tiley))
2193
if (MAPSPOT(tilex,tiley,0)==21)
2196
actorat[tilex][tiley]=0;
2208
//#if (SHAREWARE == 1)
2209
side = W_GetNumForName("SIDE21");
2210
middle = W_GetNumForName("ABOVEM4A") ;
2211
above = W_GetNumForName("ABOVEM4") ;
2214
side = W_GetNumForName("SIDE16");
2215
middle = W_GetNumForName("ABOVEM3A") ;
2216
above = W_GetNumForName("ABOVEM2A") ;
2220
bottom = W_GetNumForName("PEEPMASK");
2226
side = W_GetNumForName("SIDE21");
2227
above = W_GetNumForName("ABOVEM4") ;
2229
#if (SHAREWARE == 1)
2230
middle = W_GetNumForName("ABOVEM4A") ;
2232
middle = W_GetNumForName("ABOVEM9") ;
2235
bottom = W_GetNumForName("DOGMASK");
2241
#if (SHAREWARE == 1)
2242
side = W_GetNumForName("SIDE21");
2243
middle = W_GetNumForName("ABOVEM4A") ;
2244
above = W_GetNumForName("ABOVEM4") ;
2248
//side = W_GetNumForName("SIDE23") ;
2249
side = W_GetNumForName("SIDE21") ;
2250
middle = W_GetNumForName("ABOVEM5A") ;
2251
above = W_GetNumForName("ABOVEM5") ;
2255
bottom = W_GetNumForName("MULTI1");
2260
#if (SHAREWARE == 1)
2261
side = W_GetNumForName("SIDE21");
2262
middle = W_GetNumForName("ABOVEM4A");
2263
above = W_GetNumForName("ABOVEM4") ;
2267
//side = W_GetNumForName("SIDE23") ;
2268
side = W_GetNumForName("SIDE21") ;
2269
middle = W_GetNumForName("ABOVEM5B");
2270
above = W_GetNumForName("ABOVEM5") ;
2275
bottom = W_GetNumForName("MULTI2");
2281
#if (SHAREWARE == 1)
2282
side = W_GetNumForName("SIDE21");
2283
middle = W_GetNumForName("ABOVEM4A") ;
2284
above = W_GetNumForName("ABOVEM4") ;
2288
//side = W_GetNumForName("SIDE23") ;
2289
side = W_GetNumForName("SIDE21") ;
2290
middle = W_GetNumForName("ABOVEM5C") ;
2291
above = W_GetNumForName("ABOVEM5") ;
2296
bottom = W_GetNumForName("MULTI3");
2301
// #if (SHAREWARE == 1)
2302
side = W_GetNumForName("SIDE21");
2305
// side = W_GetNumForName("SIDE22") ;
2308
middle = W_GetNumForName("ABOVEM4A") ;
2309
above = W_GetNumForName("ABOVEM4") ;
2310
bottom = W_GetNumForName("MASKED4");
2314
side = W_GetNumForName("SIDE21");
2317
// #if (SHAREWARE == 1)
2318
middle = W_GetNumForName("ABOVEM4A") ;
2319
above = W_GetNumForName("ABOVEM4") ;
2322
// middle = W_GetNumForName("ABOVEM1A") ;
2323
// above = W_GetNumForName("ABOVEM1") ;
2328
bottom = W_GetNumForName("MASKED1");
2332
side = W_GetNumForName("SIDE21");
2334
//#if (SHAREWARE == 1)
2335
middle = W_GetNumForName("ABOVEM4A") ;
2336
above = W_GetNumForName("ABOVEM4") ;
2339
// middle = W_GetNumForName("ABOVEM2A") ;
2340
// above = W_GetNumForName("ABOVEM2") ;
2344
bottom = W_GetNumForName("MASKED2");
2348
side = W_GetNumForName("SIDE21");
2350
//#if (SHAREWARE == 1)
2351
middle = W_GetNumForName("ABOVEM4A") ;
2352
above = W_GetNumForName("ABOVEM4") ;
2355
// middle = W_GetNumForName("ABOVEM3A") ;
2356
// above = W_GetNumForName("ABOVEM3") ;
2360
bottom = W_GetNumForName("MASKED3");
2365
side = W_GetNumForName("SIDE21");
2367
//#if (SHAREWARE == 1)
2368
middle = W_GetNumForName("ABOVEM4A") ;
2369
above = W_GetNumForName("ABOVEM4") ;
2372
// middle = W_GetNumForName("ABOVEM6A") ;
2373
// above = W_GetNumForName("ABOVEM6") ;
2377
bottom = W_GetNumForName("EXITARCH");
2380
case mw_secretexitarch:
2382
side = W_GetNumForName("SIDE21");
2384
//#if (SHAREWARE == 1)
2385
middle = W_GetNumForName("ABOVEM4A") ;
2386
above = W_GetNumForName("ABOVEM4") ;
2389
// middle = W_GetNumForName("ABOVEM8A") ;
2390
// above = W_GetNumForName("ABOVEM8") ;
2394
bottom = W_GetNumForName("EXITARCA");
2401
bottom = W_GetNumForName("RAILING");
2411
case mw_hiswitchoff:
2419
side = W_GetNumForName("SIDE21");
2421
//#if (SHAREWARE == 1)
2422
//side = W_GetNumForName("SIDE21");
2423
middle = W_GetNumForName("ABOVEM4A") ;
2424
above = W_GetNumForName("ABOVEM4") ;
2427
//side = W_GetNumForName("SIDE20") ;
2428
// middle = W_GetNumForName("ABOVEM7A") ;
2429
// above = W_GetNumForName("ABOVEM7") ;
2434
bottom = W_GetNumForName("ENTRARCH");
2461
lastmaskobj->flags|=MW_BOTTOMFLIPPING;
2475
lastmaskobj->flags|=MW_BOTTOMFLIPPING;
2501
lastmaskobj->flags|=MW_TOPFLIPPING;
2515
lastmaskobj->flags|=MW_TOPFLIPPING;
2522
if ((up==1) || (dn==1))
2523
lastmaskobj->vertical=true;
2524
else if ((lt==1) || (rt==1))
2525
lastmaskobj->vertical=false;
2527
Error("Perpendicular platform used with no wall near it\n");
2535
lastmaskobj->flags|=MW_TOPFLIPPING;
2548
if (!(flags & MW_SHOOTABLE))
2552
lastmaskobj->midtexture=middle;
2553
lastmaskobj->toptexture=above;
2554
lastmaskobj->bottomtexture=bottom;
2556
if (sidepic == true)
2558
lastmaskobj->sidepic=side;
2559
if (lastmaskobj->vertical==true)
2562
tilemap[tilex][tiley-1] |= 0x4000;
2564
tilemap[tilex][tiley+1] |= 0x4000;
2569
tilemap[tilex-1][tiley] |= 0x4000;
2571
tilemap[tilex+1][tiley] |= 0x4000;
2575
// Cache in the broken version
2577
if (lastmaskobj->flags & MW_SHOOTABLE)
2581
for (i=1;i<AMW_NUMFRAMES;i++)
2583
PreCacheLump(lastmaskobj->bottomtexture+i,PU_CACHEWALLS);
2585
SD_PreCacheSound(SD_GLASSBREAKSND);
2589
PreCacheLump(lastmaskobj->sidepic,PU_CACHEWALLS);
2591
if (lastmaskobj->bottomtexture>=0)
2592
PreCacheLump(lastmaskobj->bottomtexture,PU_CACHEWALLS);
2593
if (lastmaskobj->toptexture>=0)
2594
PreCacheLump(lastmaskobj->toptexture,PU_CACHEWALLS);
2595
if (lastmaskobj->midtexture>=0)
2596
PreCacheLump(lastmaskobj->midtexture,PU_CACHEWALLS);
2599
if (maskednum==MAXMASKED)
2600
Error ("Too many masked walls\n");
2606
= FixMaskedWallAreaNumbers
2610
void FixMaskedWallAreaNumbers ( void )
2616
for (i=0;i<maskednum;i++)
2619
tilex=maskobjlist[i]->tilex;
2620
tiley=maskobjlist[i]->tiley;
2621
tile=MAPSPOT(tilex,tiley,0)-AREATILE;
2622
if ((tile<=NUMAREAS) && (tile>0))
2624
maskobjlist[i]->areanumber = tile;
2627
up=MAPSPOT(tilex,tiley-1,0)-AREATILE;
2628
dn=MAPSPOT(tilex,tiley+1,0)-AREATILE;
2629
lt=MAPSPOT(tilex-1,tiley,0)-AREATILE;
2630
rt=MAPSPOT(tilex+1,tiley,0)-AREATILE;
2634
up = ((up>0) && (up<=NUMAREAS));
2635
dn = ((dn>0) && (dn<=NUMAREAS));
2636
lt = ((lt>0) && (lt<=NUMAREAS));
2637
rt = ((rt>0) && (rt<=NUMAREAS));
2639
if (maskobjlist[i]->vertical==true)
2642
MAPSPOT(tilex,tiley,0) = MAPSPOT(tilex+1,tiley,0);
2644
MAPSPOT(tilex,tiley,0) = MAPSPOT(tilex-1,tiley,0);
2646
MAPSPOT(tilex,tiley,0) = MAPSPOT(tilex,tiley-1,0);
2648
MAPSPOT(tilex,tiley,0) = MAPSPOT(tilex,tiley+1,0);
2650
Error("FixMaskedWalls: Couldn't fix up area at x=%ld y=%ld\n",tilex,tiley);
2655
MAPSPOT(tilex,tiley,0) = MAPSPOT(tilex,tiley+1,0);
2657
MAPSPOT(tilex,tiley,0) = MAPSPOT(tilex,tiley-1,0);
2659
MAPSPOT(tilex,tiley,0) = MAPSPOT(tilex+1,tiley,0);
2661
MAPSPOT(tilex,tiley,0) = MAPSPOT(tilex-1,tiley,0);
2663
Error("FixMaskedWalls: Couldn't fix up area at x=%ld y=%ld\n",tilex,tiley);
2665
maskobjlist[i]->areanumber = MAPSPOT(tilex,tiley,0)-AREATILE;
2666
if ((maskobjlist[i]->areanumber <0) || (maskobjlist[i]->areanumber > NUMAREAS))
2667
Error("Bad masked wall areanumber of %d",maskobjlist[i]->areanumber);
2680
int CheckMaskedWall( maskedwallobj_t * mw )
2685
if (mw->flags & MW_SHOOTABLE)
2687
if (mw->flags & MW_BLOCKINGCHANGES)
2689
mw->flags&=~MW_BLOCKINGCHANGES;
2690
mw->flags&=~MW_BLOCKING;
2691
mw->flags|=MW_BOTTOMPASSABLE;
2693
mw->flags&=~MW_SHOOTABLE;
2694
// mw->bottomtexture++;
2709
int UpdateMaskedWall (int num)
2711
maskedwallobj_t * mw;
2715
mw=maskobjlist[num];
2716
result=CheckMaskedWall(mw);
2719
SpawnAnimatedMaskedWall(num);
2720
if (loadedgame==false)
2721
SD_PlaySoundRTP(SD_GLASSBREAKSND,mw->tilex<<16,mw->tiley<<16);
2722
if (mw->flags&MW_MULTI)
2727
maskedwallobj_t * mw2;
2730
if (mw->vertical==true)
2735
while (M_ISMWALL(mw->tilex+(dx*i),mw->tiley+(dy*i)))
2739
num=tilemap[mw->tilex+(dx*i)][mw->tiley+(dy*i)]&0x3ff;
2740
mw2=maskobjlist[num];
2741
if (!(mw2->flags&MW_MULTI))
2743
r=CheckMaskedWall(mw2);
2746
SpawnAnimatedMaskedWall(num);
2747
if (loadedgame==false)
2748
SD_PlaySoundRTP(SD_GLASSBREAKSND,mw2->tilex<<16,mw2->tiley<<16);
2753
while (M_ISMWALL(mw->tilex-(dx*i),mw->tiley-(dy*i)))
2757
num=tilemap[mw->tilex-(dx*i)][mw->tiley-(dy*i)]&0x3ff;
2758
mw2=maskobjlist[num];
2759
if (!(mw2->flags&MW_MULTI))
2761
r=CheckMaskedWall(mw2);
2764
SpawnAnimatedMaskedWall(num);
2765
if (loadedgame==false)
2766
SD_PlaySoundRTP(SD_GLASSBREAKSND,mw2->tilex<<16,mw2->tiley<<16);
2778
============================
2780
= ExecuteElevatorStopActions
2782
============================
2786
void ExecuteElevatorStopActions(elevator_t *eptr, int teleport_location,
2787
int desttilex,int desttiley)
2789
eptr->state = ev_doorclosing;
2790
eptr->doorclosing = eptr->doortoopen;
2791
doorobjlist[eptr->doortoopen]->flags &= ~DF_ELEVLOCKED;
2792
OpenDoor(eptr->doortoopen);
2793
SD_PlaySoundRTP(SD_ELEVATORENDSND,desttilex,desttiley);
2794
Teleport(eptr,teleport_location);
2795
eptr->ticcount = OPENTICS;
2796
eptr->doortoopen = -1;
2797
if (MISCVARS->elevatormusicon == true)
2799
MU_StartSong(song_level);
2800
MU_RestoreSongPosition();
2801
MISCVARS->elevatormusicon = false;
2807
boolean PlayerInElevator(elevator_t *eptr)
2809
if (eptr->state == ev_mts)
2811
if ((eptr->dx == player->tilex) && (eptr->dy == player->tiley))
2814
else if (eptr->state == ev_mtd)
2816
if ((eptr->sx == player->tilex) && (eptr->sy == player->tiley))
2824
#define SHOULD_START_ELEVATOR_MUSIC(eptr) \
2825
((demoplayback == false) && (demorecord == false) && \
2826
(MusicStarted() == true) && \
2828
(!(player->flags & FL_GODMODE)) &&\
2829
(GameRandomNumber("elevator music",0) < 25) && \
2830
(PlayerInElevator(eptr)) \
2835
==========================
2837
= SetElevatorOperationTime
2839
==========================
2843
void SetElevatorOperationTime(elevator_t*eptr)
2845
if (SHOULD_START_ELEVATOR_MUSIC(eptr))
2847
MU_StoreSongPosition();
2848
MU_StartSong(song_elevator);
2849
MISCVARS->elevatormusicon = true;
2850
eptr->ticcount = ELEVATORMUSICTIME;
2853
else if (AREANUMBER(eptr->sx,eptr->sy) == AREANUMBER(eptr->dx,eptr->dy))
2854
eptr->ticcount = 70;
2856
eptr->ticcount = 170;
2862
=====================
2864
= CheckElevatorStart
2866
=====================
2869
void CheckElevatorStart (elevator_t*eptr)
2871
doorobj_t *dptr = doorobjlist[eptr->doorclosing];
2873
if (dptr->action == dr_closed)
2876
if (eptr->nextaction!=-1)
2878
eptr->state = eptr->nextaction;
2879
eptr->nextaction = -1;
2880
switch (eptr->state)
2883
eptr->doortoopen = eptr->door2;
2884
SD_PlaySoundRTP(SD_ELEVATORONSND,eptr->sx<<16,eptr->sy<<16);
2885
//eptr->doorclosing = eptr->door1;
2887
SetElevatorOperationTime(eptr);
2891
eptr->doortoopen = eptr->door1;
2893
SD_PlaySoundRTP(SD_ELEVATORONSND,eptr->dx<<16,eptr->dy<<16);
2895
SetElevatorOperationTime(eptr);
2900
else if (eptr->doorclosing == eptr->door1)
2901
eptr->state = ev_ras;
2904
else if (eptr->doorclosing == eptr->door2)
2905
eptr->state = ev_rad;
2908
eptr->doorclosing = -1;
2914
=====================
2918
= Called from PlayLoop
2920
=====================
2923
void ProcessElevators (void)
2928
for (ectr = 0 ; ectr < _numelevators ; ectr++)
2930
eptr = &ELEVATOR[ectr];
2935
switch (eptr->state)
2945
ExecuteElevatorStopActions(eptr,0,(eptr->sx << 16),(eptr->sy << 16));
2949
ExecuteElevatorStopActions(eptr,1,(eptr->dx << 16),(eptr->dy << 16));
2952
case ev_doorclosing:
2953
CheckElevatorStart(eptr);
2962
void Teleport(elevator_t*eptr,int destination)
2965
int startx,starty,destx,desty;
2967
if (destination) // move to dest
2972
tilemap[eptr->esx][eptr->esy] = (elevatorstart + 5) | 0x2000;
2980
tilemap[eptr->edx][eptr->edy] = (elevatorstart + 5) | 0x2000;
2983
for(tstat=firstactivestat;tstat;tstat=tstat->nextactive)
2984
{if ((tstat->tilex == startx) && (tstat->tiley == starty))
2986
tstat->x += ((destx - tstat->tilex) << TILESHIFT);
2987
tstat->y += ((desty - tstat->tiley) << TILESHIFT);
2988
tstat->tilex = tstat->x >> TILESHIFT;
2989
tstat->tiley = tstat->y >> TILESHIFT;
2990
tstat->visspot = &spotvis[tstat->tilex][tstat->tiley];
2991
if (sprites[startx][starty] == tstat)
2992
{sprites[startx][starty] = NULL;
2993
sprites[destx][desty] = tstat;
3000
for(temp=firstactive;temp;temp=temp->nextactive)
3001
{if ((temp->tilex == startx) && (temp->tiley == starty))
3002
{temp->x += ((destx - temp->tilex) << TILESHIFT);
3003
temp->y += ((desty - temp->tiley) << TILESHIFT);
3004
temp->tilex = temp->x >> TILESHIFT;
3005
temp->tiley = temp->y >> TILESHIFT;
3006
if (temp->obclass!=inertobj)
3008
RemoveFromArea (temp);
3009
temp->areanumber = AREANUMBER(temp->tilex,temp->tiley);
3010
MakeLastInArea (temp);
3023
void OperateElevatorDoor(int dnum)
3026
doorobj_t *dptr,*door1,*door2;
3028
dptr = doorobjlist[dnum];
3029
eptr = &ELEVATOR[dptr->eindex];
3030
door1 = doorobjlist[eptr->door1];
3031
door2 = doorobjlist[eptr->door2];
3035
case ev_mtd: // if already on the way to request,
3036
// ignore; else, put request in
3037
if (dnum == eptr->door1)
3038
{eptr->nextaction = ev_mts;
3039
//eptr->doortoopen = eptr->door1;
3040
#if (DEVELOPMENT == 1)
3041
#if (ELEVATORTEST == 1)
3042
Debug("\nplayer at source requesting elev %d mtd",dptr->eindex);
3049
if (dnum == eptr->door2)
3050
{eptr->nextaction = ev_mtd;
3051
//eptr->doortoopen = eptr->door2;
3052
#if (DEVELOPMENT == 1)
3053
#if (ELEVATORTEST == 1)
3054
Debug("\nplayer at dest requesting elev %d mts",dptr->eindex);
3060
case ev_rad: // if ready at other place,
3061
if ((dnum == eptr->door1) && (eptr->nextaction != ev_mts)) // process request, lock doors,
3064
#if (DEVELOPMENT == 1)
3065
#if (ELEVATORTEST == 1)
3066
Debug("\nplayer at source requesting elev %d rad",dptr->eindex);
3069
// start moving to current loc;
3070
SetNextAction(eptr,0); // if already there, do nothing
3076
if ((dnum == eptr->door2) && (eptr->nextaction != ev_mtd))
3078
#if (DEVELOPMENT == 1)
3079
#if (ELEVATORTEST == 1)
3080
Debug("\nplayer at dest requesting elev %d ras",dptr->eindex);
3083
SetNextAction(eptr,1);
3088
case ev_doorclosing:
3089
if (eptr->doorclosing == dnum) // if opening door at current loc,
3090
// reset elev state to ready
3091
{//if (eptr->door1 == dnum)
3092
// eptr->nextaction = ev_ras;
3094
//eptr->nextaction = ev_rad;
3096
else //else prepare for movement
3097
{if ((eptr->door1 == dnum) && (eptr->nextaction != ev_mts))
3099
#if ((DEVELOPMENT == 1))
3100
#if ((ELEVATORTEST == 1))
3101
Debug("\nplayer at source requesting elev %d dc",dptr->eindex);
3104
SetNextAction(eptr,0);
3107
else if ((eptr->door2 == dnum) && (eptr->nextaction != ev_mtd))
3109
#if ((DEVELOPMENT == 1))
3110
#if ((ELEVATORTEST == 1))
3111
Debug("\nplayer at dest requesting elev %d dc",dptr->eindex);
3114
SetNextAction(eptr,1);
3126
int SetNextAction(elevator_t*eptr,int action)
3130
{if (!DoorReadyToClose(eptr->door1))
3133
eptr->nextaction = ev_mtd;
3137
{if (!DoorReadyToClose(eptr->door2))
3140
eptr->nextaction = ev_mts;
3143
eptr->state = ev_doorclosing;
3145
eptr->doorclosing = dn;
3146
#if (DEVELOPMENT == 1)
3147
#if (ELEVATORTEST == 1)
3148
Debug("\nCloseDoor %d",dn);
3151
if (doorobjlist[dn]->action != dr_closed)
3153
doorobjlist[dn]->flags |= DF_ELEVLOCKED;
3159
void OperateElevatorSwitch(objtype*ob,int elevnum,int checkx,int checky)
3161
doorobj_t *door1,*door2;
3163
eptr = &ELEVATOR[elevnum];
3165
if ((eptr->state == ev_mts) ||
3166
(eptr->state == ev_mtd))
3168
#if (DEVELOPMENT == 1)
3169
#if (ELEVATORTEST == 1)
3170
Debug("\nobj %d tried to use elevator %d switch while in use",ob->obclass,elevnum);
3176
door1 = doorobjlist[eptr->door1];
3177
door2 = doorobjlist[eptr->door2];
3179
if ((abs(ob->tilex-door1->tilex)<=1) && //switch at source
3180
(abs(ob->tiley-door1->tiley)<=1))
3181
{if (!SetNextAction(eptr,1)) // set next to dest
3183
#if (DEVELOPMENT == 1)
3184
#if (ELEVATORTEST == 1)
3185
Debug("\nswitch at src %d flipped",elevnum);
3190
else //switch at dest
3191
{if (!SetNextAction(eptr,0)) // set next to src
3193
#if (DEVELOPMENT == 1)
3194
#if (ELEVATORTEST == 1)
3195
Debug("\nswitch at dest %d flipped",elevnum);
3201
tilemap[checkx][checky] = (elevatorstart + 6) | 0x2000;
3202
SD_PlaySoundRTP(SD_TOUCHPLATESND,ob->x,ob->y);
3210
=====================
3214
= Called from PlayLoop
3216
=====================
3219
void MoveDoors (void)
3223
for (door = 0 ; door < doornum ; door++)
3224
switch (doorobjlist[door]->action)
3232
SD_PanRTP ( doorobjlist[door]->soundhandle, doorobjlist[door]->tilex<<16, doorobjlist[door]->tiley<<16 );
3237
SD_PanRTP ( doorobjlist[door]->soundhandle, doorobjlist[door]->tilex<<16, doorobjlist[door]->tiley<<16 );
3245
//===========================================================
3249
//===========================================================
3259
int GetAreaNumber ( int tilex, int tiley, int dir )
3263
up=MAPSPOT(tilex,tiley-1,0)-AREATILE;
3264
dn=MAPSPOT(tilex,tiley+1,0)-AREATILE;
3265
lt=MAPSPOT(tilex-1,tiley,0)-AREATILE;
3266
rt=MAPSPOT(tilex+1,tiley,0)-AREATILE;
3267
if ((up<=0) || (up>NUMAREAS)) up=0;
3268
if ((dn<=0) || (dn>NUMAREAS)) dn=0;
3269
if ((lt<=0) || (lt>NUMAREAS)) lt=0;
3270
if ((rt<=0) || (rt>NUMAREAS)) rt=0;
3307
Error("Cannot find an area number for tile at x=%ld y=%ld\n",tilex,tiley);
3319
void SpawnPushWall (int tilex, int tiley, int lock, int texture, int dir, int type)
3321
pwallobj_t * lastpwallobj;
3323
if (pwallnum==MAXPWALLS)
3324
Error ("MAXPWALLS on level!");
3326
pwallobjlist[pwallnum]=(pwallobj_t*)Z_LevelMalloc(sizeof(pwallobj_t),PU_LEVELSTRUCT,NULL);
3327
memset(pwallobjlist[pwallnum],0,sizeof(pwallobj_t));
3328
lastpwallobj=pwallobjlist[pwallnum];
3330
lastpwallobj->x = (tilex<<16)+0x8000;
3331
lastpwallobj->y = (tiley<<16)+0x8000;
3332
lastpwallobj->momentumx=0;
3333
lastpwallobj->momentumy=0;
3334
lastpwallobj->tilex = tilex;
3335
lastpwallobj->tiley = tiley;
3336
lastpwallobj->lock = lock;
3337
lastpwallobj->action = pw_npushed;
3338
lastpwallobj->which = PWALL;
3339
lastpwallobj->dir = dir;
3340
lastpwallobj->num = pwallnum;
3341
actorat[tilex][tiley] = (pwallobj_t*)(lastpwallobj); // consider it a solid wall
3343
if ( (MAPSPOT(tilex,tiley,0)==44) ||
3344
(MAPSPOT(tilex,tiley,0)==233)
3346
lastpwallobj->flags=PW_DAMAGE;
3348
lastpwallobj->texture = texture;
3349
if (!texture&0x1000)
3350
PreCacheLump(texture,PU_CACHEWALLS);
3351
lastpwallobj->areanumber = GetAreaNumber(tilex,tiley,lastpwallobj->dir);
3353
MAPSPOT (tilex, tiley, 0)=(word)(lastpwallobj->areanumber+AREATILE);
3360
lastpwallobj->speed = 2;
3364
lastpwallobj->speed = 4;
3367
Error("Illegal PushWall type passed into SpawnPushWall\n");
3372
tilemap[tilex][tiley] = 0;
3373
ActivateMoveWall(pwallnum);
3377
tilemap[tilex][tiley] = texture|0x800;
3378
if ((loadedgame==false) && (type==0))
3379
gamestate.secrettotal++;
3385
SD_PreCacheSoundGroup(SD_PUSHWALLSND,SD_TURBOWALLSND);
3391
=====================
3395
= The player wants to change the pushwall's direction
3397
=====================
3399
void OperatePushWall (int pwall, int dir, boolean localplayer )
3403
pw=pwallobjlist[pwall];
3410
AddMessage("This push wall appears to be locked...",MSG_DOOR);
3418
if ((dir!=pw->dir) && (pw->dir!=nodir))
3427
else if (localplayer && (gamestate.difficulty == gd_baby))
3428
AddMessage("Push Wall Activated.",MSG_GAME);
3430
pw->action=pw_pushing;
3432
SD_PlaySoundRTP ( SD_TOUCHPLATESND, pw->x, pw->y );
3433
ConnectPushWall(pwall);
3434
SetupPushWall(pwall);
3435
gamestate.secretcount++;
3448
=====================
3450
= ActivateAllPushWalls
3452
= A Push wall has beeen activated by a touch plate
3454
=====================
3457
void ActivateAllPushWalls(void)
3461
for(i=0;i<pwallnum;i++)
3463
if (pwallobjlist[i]->dir != nodir)
3465
ActivatePushWall(i);
3471
=====================
3475
= A Push wall has beeen activated by a touch plate
3477
=====================
3480
void ActivatePushWall (int pwall)
3484
pw=pwallobjlist[pwall];
3489
pw->action=pw_pushing;
3490
ConnectPushWall(pwall);
3491
SetupPushWall(pwall);
3492
gamestate.secretcount++;
3496
SD_Play( SD_BADTOUCHSND );
3502
=====================
3506
= A Push wall has beeen activated by a touch plate
3508
=====================
3511
void ActivateMoveWall (int pwall)
3515
pw=pwallobjlist[pwall];
3520
pw->action=pw_moving;
3521
SetupPushWall(pwall);
3524
SD_Play( SD_BADTOUCHSND );
3539
void ConnectPushWall (int pwall)
3548
pw=pwallobjlist[pwall];
3552
tilemap[checkx][checky] = 0;
3553
map = &MAPSPOT (checkx, checky, 0);
3555
area1 = *(map-mapwidth);
3556
area2 = *(map+mapwidth);
3564
if (((area1>0) && (area1<NUMAREAS)) &&
3565
((area2>0) && (area2<NUMAREAS)))
3567
areaconnect[area1][area2]++;
3568
areaconnect[area2][area1]++;
3570
if ((insetupgame==false) && (loadedgame==false))
3573
if (((area3>0) && (area3<NUMAREAS)) &&
3574
((area4>0) && (area4<NUMAREAS)))
3576
areaconnect[area3][area4]++;
3577
areaconnect[area4][area3]++;
3579
if ((insetupgame==false) && (loadedgame==false))
3592
void SetupPushWall (int pwall)
3597
pw=pwallobjlist[pwall];
3598
speed=pw->speed<<PUSHWALLSPEED;
3603
pw->momentumy=-speed;
3607
pw->momentumx=speed;
3612
pw->momentumx=speed;
3613
pw->momentumy=-speed;
3617
pw->momentumx=speed;
3618
pw->momentumy=speed;
3623
pw->momentumy=speed;
3627
pw->momentumx=-speed;
3632
pw->momentumx=-speed;
3633
pw->momentumy=-speed;
3637
pw->momentumx=-speed;
3638
pw->momentumy=speed;
3641
if (pw->action==pw_pushing)
3643
if (loadedgame==false)
3644
pw->soundhandle=SD_PlaySoundRTP ( SD_PUSHWALLSND, pw->x, pw->y );
3645
pw->state=(0x20000L/speed);
3647
if (pw->action==pw_moving)
3648
pw->state=(0x10000L/speed);
3653
=====================
3657
= Called from PlayLoop
3659
=====================
3662
void MovePWalls (void)
3666
for (pwall = 0 ; pwall < pwallnum ; pwall++)
3668
if (pwallobjlist[pwall]->action==pw_pushing)
3670
WallPushing (pwall);
3671
SD_PanRTP (pwallobjlist[pwall]->soundhandle, pwallobjlist[pwall]->x, pwallobjlist[pwall]->y );
3673
if (pwallobjlist[pwall]->action==pw_moving)
3676
SD_PanRTP (pwallobjlist[pwall]->soundhandle, pwallobjlist[pwall]->x, pwallobjlist[pwall]->y );
3682
void ClearActorat(pwallobj_t*pw)
3683
{int txhigh,txlow,tyhigh,tylow;
3690
txlow = (tryx - pwrad) >> 16;
3691
txhigh = (tryx + pwrad) >> 16;
3692
tylow = (tryy - pwrad) >> 16;
3693
tyhigh = (tryy + pwrad) >> 16;
3694
for(y=tylow;y<=tyhigh;y++)
3695
for(x=txlow;x<=txhigh;x++)
3696
{if (actorat[x][y] == pw)
3697
actorat[x][y] = NULL;
3701
void SetActorat(pwallobj_t*pw)
3702
{int txhigh,txlow,tyhigh,tylow;
3708
txlow = (tryx - pwrad) >> 16;
3709
txhigh = (tryx + pwrad) >> 16;
3710
tylow = (tryy - pwrad) >> 16;
3711
tyhigh = (tryy + pwrad) >> 16;
3713
for(y=tylow;y<=tyhigh;y++)
3714
for(x=txlow;x<=txhigh;x++)
3725
void FinishPushWall (pwallobj_t * pw)
3727
pw->action = pw_pushed;
3728
actorat[pw->tilex][pw->tiley] = (wall_t*)&walls[GetWallIndex(pw->texture)];
3729
tilemap[pw->tilex][pw->tiley] = pw->texture;
3739
void ResetPushWall (pwallobj_t * pw)
3742
tilemap[pw->tilex][pw->tiley] = pw->texture|0x800;
3752
void WallPushing (int pwall)
3758
pw=pwallobjlist[pwall];
3762
PushWallMove(pwall);
3763
pw->x+=pw->momentumx;
3764
pw->y+=pw->momentumy;
3771
pw->tilex=pw->x>>16;
3772
pw->tiley=pw->y>>16;
3774
if ((pw->tilex!=checkx) || (pw->tiley!=checky))
3777
int area = MAPSPOT(pw->tilex,pw->tiley,0)-AREATILE;
3779
if ((area<=0) || (area>NUMAREAS))
3781
area=pw->areanumber;
3782
MAPSPOT (pw->tilex, pw->tiley, 0)=(word)(pw->areanumber+AREATILE);
3784
// block crossed into a new block
3786
// the tile can now be walked into
3788
mapseen[checkx][checky] = 0;
3789
pw->areanumber = area;
3790
if (pw->momentumx>0)
3792
else if (pw->momentumx<0)
3796
if (pw->momentumy>0)
3798
else if (pw->momentumy<0)
3802
if (tilemap[pw->tilex+x][pw->tiley+y])
3804
pw->state=(0x8000L/(pw->speed<<PUSHWALLSPEED));
3806
if (actorat[pw->tilex+x][pw->tiley+y])
3807
ResolveDoorSpace(pw->tilex+x,pw->tiley+y);
3813
pw->x=(pw->tilex<<16)+0x8000;
3814
pw->y=(pw->tiley<<16)+0x8000;
3815
spot = MAPSPOT(pw->tilex,pw->tiley,1)-ICONARROWS;
3816
if ((spot >= 0) && (spot <= 7))
3818
pw->action = pw_npushed;
3823
pw->action=pw_pushing;
3824
ConnectPushWall(pwall);
3825
SetupPushWall(pwall);
3829
gamestate.secrettotal++;
3834
FinishPushWall (pw);
3849
void WallMoving (int pwall)
3855
pw=pwallobjlist[pwall];
3859
PushWallMove(pwall);
3860
pw->x+=pw->momentumx;
3861
pw->y+=pw->momentumy;
3868
pw->tilex=pw->x>>16;
3869
pw->tiley=pw->y>>16;
3871
if ((pw->tilex!=checkx) || (pw->tiley!=checky))
3873
int area = MAPSPOT(pw->tilex,pw->tiley,0)-AREATILE;
3875
if ((area<=0) || (area>NUMAREAS))
3877
area=pw->areanumber;
3878
MAPSPOT (pw->tilex, pw->tiley, 0)=(word)(pw->areanumber+AREATILE);
3880
// block crossed into a new block
3882
// the tile can now be walked into
3884
if (areabyplayer[area])
3887
pw->soundhandle=SD_PlaySoundRTP ( SD_GOWALLSND, pw->x, pw->y );
3889
pw->soundhandle=SD_PlaySoundRTP ( SD_TURBOWALLSND, pw->x, pw->y );
3892
if (actorat[pw->tilex][pw->tilex])
3893
ResolveDoorSpace(pw->tilex,pw->tiley);
3894
mapseen[checkx][checky] = 0;
3895
pw->areanumber = MAPSPOT (pw->tilex, pw->tiley, 0)-AREATILE;
3896
//actorat[pw->tilex][pw->tiley]=pw;
3897
if ( (pw->tilex==0) || (pw->tilex==127) ||
3898
(pw->tiley==0) || (pw->tiley==127) )
3900
if (W_CheckNumForName("imfree")>=0)
3904
LBM = (lbm_t *) W_CacheLumpNum (W_GetNumForName ("imfree"), PU_CACHE, Cvt_lbm_t, 1);
3905
VL_DecompressLBM (LBM,true);
3909
Error ("PushWall Attempting to escape off the edge of the map\nIt is located at x=%ld y=%ld\nI'm Free!!!!\n",
3910
pw->tilex, pw->tiley);
3915
pw->x=(pw->tilex<<16)+0x8000;
3916
pw->y=(pw->tiley<<16)+0x8000;
3917
spot = MAPSPOT(pw->tilex,pw->tiley,1)-ICONARROWS;
3918
if ((spot >= 0) && (spot <= 7))
3920
int area = MAPSPOT(pw->tilex,pw->tiley,0)-AREATILE;
3922
if ((area<=0) || (area>NUMAREAS))
3924
area=pw->areanumber;
3925
MAPSPOT (pw->tilex, pw->tiley, 0)=(word)(pw->areanumber+AREATILE);
3928
if (areabyplayer[area] && (abs(spot-pw->dir)==4))
3929
SD_PlaySoundRTP ( SD_PUSHWALLHITSND, pw->x, pw->y );
3932
SetupPushWall(pwall);
3947
void SavePushWalls(byte ** buf, int * sz)
3958
*buf=SafeMalloc(16);
3963
unitsize+=sizeof(pw->state);
3964
unitsize+=sizeof(pw->x);
3965
unitsize+=sizeof(pw->y);
3966
unitsize+=sizeof(pw->dir);
3967
unitsize+=sizeof(pw->speed);
3968
unitsize+=sizeof(pw->action);
3970
*sz=pwallnum*unitsize;
3972
*buf=SafeMalloc(*sz);
3975
for (i=0;i<pwallnum;i++)
3978
size=sizeof(pw->state);
3979
memcpy(bufptr,&(pw->state),size);
3983
memcpy(bufptr,&(pw->x),size);
3987
memcpy(bufptr,&(pw->y),size);
3990
size=sizeof(pw->dir);
3991
memcpy(bufptr,&(pw->dir),size);
3994
size=sizeof(pw->speed);
3995
memcpy(bufptr,&(pw->speed),size);
3998
size=sizeof(pw->action);
3999
memcpy(bufptr,&(pw->action),size);
4011
void LoadPushWalls(byte * bufptr, int sz)
4026
unitsize+=sizeof(pw->state);
4027
unitsize+=sizeof(pw->x);
4028
unitsize+=sizeof(pw->y);
4029
unitsize+=sizeof(pw->dir);
4030
unitsize+=sizeof(pw->speed);
4031
unitsize+=sizeof(pw->action);
4035
Error("Different number of Push Walls when trying to load a game\npwallnum=%ld num=%ld",pwallnum,num);
4037
for (i=0;i<pwallnum;i++)
4041
size=sizeof(new.state);
4042
memcpy(&(new.state),bufptr,size);
4046
memcpy(&(new.x),bufptr,size);
4050
memcpy(&(new.y),bufptr,size);
4053
size=sizeof(new.dir);
4054
memcpy(&(new.dir),bufptr,size);
4057
size=sizeof(new.speed);
4058
memcpy(&(new.speed),bufptr,size);
4061
size=sizeof(new.action);
4062
memcpy(&(new.action),bufptr,size);
4065
actorat[pw->tilex][pw->tiley] = 0;
4066
mapseen[pw->tilex][pw->tiley] = 0;
4068
new.tilex=new.x>>16;
4069
new.tiley=new.y>>16;
4071
if ((new.tilex!=pw->tilex) || (new.tiley!=pw->tiley))
4074
tilemap[pw->tilex][pw->tiley] = 0;
4075
if (pw->state!=pw_moving)
4080
if (tilemap[pw->tilex+1][pw->tiley]==0)
4082
else if (tilemap[pw->tilex-1][pw->tiley]==0)
4084
else if (tilemap[pw->tilex][pw->tiley+1]==0)
4094
// fixup area if needed
4096
area = MAPSPOT(new.tilex,new.tiley,0)-AREATILE;
4097
if ((area<=0) || (area>NUMAREAS))
4099
MAPSPOT (new.tilex, new.tiley, 0)=(word)(pw->areanumber+AREATILE);
4102
pw->tilex=new.tilex;
4103
pw->tiley=new.tiley;
4106
pw->action=new.action;
4108
pw->speed=new.speed;
4110
pw->state=new.state;
4112
pw->areanumber = MAPSPOT (pw->tilex, pw->tiley, 0)-AREATILE;
4114
if (pw->action==pw_pushed)
4116
FinishPushWall (pw);
4118
else if (pw->action==pw_npushed)
4140
void SaveMaskedWalls(byte ** buf, int * size)
4143
maskedwallobj_t * mw;
4151
*buf=SafeMalloc(16);
4156
unitsize+=sizeof(mw->flags);
4158
*size=maskednum*unitsize;
4160
*buf=SafeMalloc(*size);
4163
for (i=0;i<maskednum;i++)
4166
sz=sizeof(mw->flags);
4167
memcpy(bufptr,&(mw->flags),sz);
4179
void LoadMaskedWalls(byte * bufptr, int sz)
4182
maskedwallobj_t * mw;
4191
FixMaskedWallAreaNumbers();
4195
unitsize+=sizeof(mw->flags);
4199
Error("Different number of Masked Walls when trying to load a game\nmaskednum=%ld num=%ld",maskednum,num);
4201
for (i=0;i<maskednum;i++)
4206
size=sizeof(mw->flags);
4207
memcpy(&flags,bufptr,size);
4209
if (flags!=mw->flags)
4210
UpdateMaskedWall(i);
4211
if (mw->flags&MW_SWITCHON)
4225
void SaveDoors (byte ** buf, int * size)
4231
signed char dooreindex;
4239
*buf=SafeMalloc(16);
4244
// Size = (int + byte + byte) * numdoors
4248
unitsize+=sizeof(doorsave);
4249
unitsize+=sizeof(doorflag);
4250
unitsize+=sizeof(doorlocked);
4251
unitsize+=sizeof(doortime);
4252
unitsize+=sizeof(dooreindex);
4254
*size = unitsize*doornum;
4255
*buf = (byte *) SafeMalloc (*size);
4259
for (door = 0; door < doornum ; door++)
4261
doorsave = doorobjlist[door]->position & ~3;
4262
doorsave |= doorobjlist[door]->action;
4263
doorflag = doorobjlist[door]->flags;
4264
doorlocked = doorobjlist[door]->lock;
4265
doortime = doorobjlist[door]->ticcount;
4266
dooreindex = doorobjlist[door]->eindex;
4268
memcpy (ptr, &doorsave, sizeof (doorsave));
4269
ptr += sizeof (doorsave);
4270
memcpy (ptr, &doorflag, sizeof (doorflag));
4271
ptr += sizeof (doorflag);
4272
memcpy (ptr, &doorlocked, sizeof (doorlocked));
4273
ptr += sizeof (doorlocked);
4274
memcpy (ptr, &doortime, sizeof (doortime));
4275
ptr += sizeof (doortime);
4276
memcpy (ptr, &dooreindex, sizeof (dooreindex));
4277
ptr += sizeof (dooreindex);
4290
void LoadDoors (byte * buf, int size)
4296
signed char dooreindex;
4303
FixDoorAreaNumbers();
4307
unitsize+=sizeof(doorsave);
4308
unitsize+=sizeof(doorflag);
4309
unitsize+=sizeof(doorlocked);
4310
unitsize+=sizeof(doortime);
4311
unitsize+=sizeof(dooreindex);
4315
Error("Different number of Doors when trying to load a game\ndoornum=%ld num=%ld",doornum,num);
4317
for (door = 0; door < doornum; door++)
4319
memcpy (&doorsave, ptr, sizeof (doorsave));
4320
ptr += sizeof (doorsave);
4321
memcpy (&doorflag, ptr, sizeof (doorflag));
4322
ptr += sizeof (doorflag);
4323
memcpy (&doorlocked, ptr, sizeof (doorlocked));
4324
ptr += sizeof (doorlocked);
4325
memcpy (&doortime, ptr, sizeof (doortime));
4326
ptr += sizeof (doortime);
4327
memcpy (&dooreindex, ptr, sizeof (dooreindex));
4328
ptr += sizeof (dooreindex);
4330
doorobjlist[door]->action = doorsave & 3;
4334
if (doorobjlist[door]->action != dr_closed)
4337
doorobjlist[door]->action = doorsave & 3;
4338
doorobjlist[door]->position = doorsave;
4339
doorobjlist[door]->flags = doorflag;
4340
doorobjlist[door]->lock = doorlocked;
4341
doorobjlist[door]->ticcount = doortime;
4342
doorobjlist[door]->eindex = dooreindex;
4344
if (doorobjlist[door]->action == dr_open)
4345
doorobjlist[door]->position = 0xFFFF;
4347
else if (doorobjlist[door]->action == dr_closed)
4348
doorobjlist[door]->position = 0;
4351
(doorobjlist[door]->action == dr_closing) ||
4352
(doorobjlist[door]->action == dr_closed)
4355
actorat[doorobjlist[door]->tilex][doorobjlist[door]->tiley] = doorobjlist[door];
4357
doorobjlist[door]->texture = doorobjlist[door]->basetexture +
4358
((doorobjlist[door]->position+1)>>13);
4364
=====================
4369
=====================
4372
void SaveElevators(byte ** buffer,int *size)
4376
*size = _numelevators*sizeof(elevator_t);
4378
*buffer = (byte *)SafeMalloc(*size);
4381
for(i=0;i<_numelevators;i++)
4382
{memcpy(tptr,&ELEVATOR[i],sizeof(elevator_t));
4383
tptr += sizeof(elevator_t);
4389
=====================
4394
=====================
4397
void LoadElevators(byte * buffer,int size)
4400
_numelevators = size/sizeof(elevator_t);
4403
for(i=0;i<_numelevators;i++)
4404
{memcpy(&ELEVATOR[i],buffer,sizeof(elevator_t));
4405
buffer += sizeof(elevator_t);