1 #include "3dc.h"
2 #include "inline.h"
3 #include "module.h"
4 #include "stratdef.h"
5 #include "gamedef.h"
6 #include "bh_types.h"
7
8 #include "weapons.h"
9 #include "comp_shp.h"
10 #include "inventry.h"
11 #include "triggers.h"
12 #include "huddefs.h"
13
14 #include "dynblock.h"
15 #include "dynamics.h"
16
17 #define UseLocalAssert Yes
18
19 #include "ourasert.h"
20
21 #include "pmove.h"
22 #include "pvisible.h"
23 #include "bh_swdor.h"
24 #include "load_shp.h"
25 #include "lighting.h"
26 #include "bh_lnksw.h"
27 #include "bh_binsw.h"
28 #include "bh_lift.h"
29
30 #include "psnd.h"
31
32 /* for win95 net game support */
33 #include "pldghost.h"
34
35 extern int NormalFrameTime;
36 // stuff for environment changing
37
38 extern void IntegrateNewEnvironment();
39 extern int NumActiveBlocks;
40
41 // Globals we are going to export
42
43 int RequestEnvChangeViaLift = 0;
44 int RequestEnvChangeViaAirlock = 0;
45
46 LIFT_CONTROL_BLOCK EC_Lift_Ctrl;
47 MODULE Old_Pos_Module;
48
49
50
51 static void TeleportFloorSwitches(MODULE* dest, MODULE* src, LIFT_CONTROL_BLOCK* liftCtrl);
52
53
54
55 /*********************** CLOSED TELEPORT LIFTS INIT ***************/
56
LiftBehaveInit(void * bhdata,STRATEGYBLOCK * sbptr)57 void * LiftBehaveInit(void* bhdata, STRATEGYBLOCK* sbptr)
58 {
59
60 LIFT_BEHAV_BLOCK *lift_bhv;
61 LIFT_STATION* lift_stn;
62 LIFT_TOOLS_TEMPLATE* lift_tt;
63 MODULE * my_mod;
64
65 GLOBALASSERT(sbptr);
66 lift_bhv = (LIFT_BEHAV_BLOCK*)AllocateMem(sizeof(LIFT_BEHAV_BLOCK));
67 if(!lift_bhv)
68 {
69 memoryInitialisationFailure = 1;
70 return ((void *)NULL);
71 }
72
73 lift_bhv->bhvr_type = I_BehaviourLift;
74
75 lift_stn = &lift_bhv->lift_station;
76 lift_tt = (LIFT_TOOLS_TEMPLATE*)bhdata;
77
78 // Copy the name over
79 COPY_NAME (sbptr->SBname, lift_tt->nameID);
80
81
82 // Setup module ref if not external
83 if (lift_tt->environment == (int)AvP.CurrentEnv)
84 {
85 {
86 MREF mref=lift_tt->my_module;
87 ConvertModuleNameToPointer (&mref, MainSceneArray[0]->sm_marray);
88
89 my_mod = mref.mref_ptr;
90 }
91 GLOBALASSERT (my_mod);
92
93 my_mod->m_sbptr = sbptr;
94 sbptr->SBmoptr = my_mod;
95 sbptr->SBmomptr = my_mod->m_mapptr;
96 sbptr->SBflags.no_displayblock = 1;
97 }
98
99 // loaded data - first the station
100
101 COPY_NAME(lift_stn->lift_call_switch_name, lift_tt->call_switch_name);
102 COPY_NAME(lift_stn->lift_door_name, lift_tt->lift_door_name);
103 COPY_NAME(lift_stn->lift_floor_switch_name, lift_tt->lift_floor_switch_name);
104 COPY_NAME(lift_stn->my_sb_name, lift_tt->my_module_name);
105
106 lift_stn->env = lift_tt->environment;
107 lift_stn->num_floor = lift_tt->num_floor;
108 lift_stn->orient = lift_tt->orient;
109
110 // fill in the rest of the stn data;
111
112 lift_stn->lift_call_switch = NULL;
113 lift_stn->lift_door = NULL;
114 lift_stn->lift_floor_switch = NULL;
115 lift_stn->lift_module = sbptr->SBmoptr;
116 if(lift_tt->lift_flags & LiftFlag_Here)
117 lift_stn->starting_station = 1;
118 else
119 lift_stn->starting_station = 0;
120
121 lift_stn->called = 0;
122
123 // fill in the behaviour block
124
125 lift_bhv->control_sb = NULL;
126 lift_bhv->controller = lift_tt->controller;
127 COPY_NAME(lift_bhv->control_sb_name, lift_tt->control_sb_name);
128
129 if(lift_bhv->controller)
130 {
131 LIFT_CONTROL_BLOCK* lcont = AllocateMem(sizeof(LIFT_CONTROL_BLOCK));
132 if(!lcont)
133 {
134 memoryInitialisationFailure = 1;
135 return ((void *)NULL);
136 }
137
138 lift_bhv->lift_control = lcont;
139
140 // fill in the number of floors
141
142 lcont->num_stations = lift_tt->num_stations;
143 lcont->lift_stations = (LIFT_STATION**)AllocateMem(sizeof(LIFT_STATION*)*lcont->num_stations);
144
145 if(!lcont->lift_stations)
146 {
147 memoryInitialisationFailure = 1;
148 return ((void *)NULL);
149 }
150
151 //and init that array
152 {
153 int i=0;
154 while(i < lcont->num_stations)
155 {
156 *(lcont->lift_stations + i) = NULL;
157 i++;
158 }
159 }
160 // fill in the rest of the data
161
162 *(lcont->lift_stations + lift_stn->num_floor) = lift_stn;
163 lcont->dest_station = -1;
164 lcont->delay_at_floor = 0;
165 lcont->delay_between_floors = 0;
166 lcont->motion = I_going_down;
167 lcont->state = I_ls_waiting;
168 lcont->curr_station = -1;
169 lcont->prev_station = -1;
170 lcont->SoundHandle = SOUND_NOACTIVEINDEX;
171
172
173 if(lift_tt->lift_flags & LiftFlag_NoTel)
174 lcont->floor_switches_fixed=1;
175 else
176 lcont->floor_switches_fixed=0;
177
178 }
179
180
181 return((void*)lift_bhv);
182 }
183
184
185 // this function reposts anything that would prevent
186 // The palyer most be in the module and nothing
187 // else can be
188
189
BadGuyInModuleOrNoPlayer()190 BOOL BadGuyInModuleOrNoPlayer()
191 {
192 return(0);
193 }
194
195 /*************************** LIFT CONTROL *****************************/
196
LiftBehaveFun(STRATEGYBLOCK * sbptr)197 void LiftBehaveFun(STRATEGYBLOCK* sbptr)
198 {
199 LIFT_BEHAV_BLOCK *lift_bhv;
200 LIFT_CONTROL_BLOCK *lift_ctrl;
201 LIFT_STATION *curr_stn;
202 I_AVP_ENVIRONMENTS dest_env;
203
204 GLOBALASSERT(sbptr);
205 lift_bhv = (LIFT_BEHAV_BLOCK*)sbptr->SBdataptr;
206 GLOBALASSERT((lift_bhv->bhvr_type == I_BehaviourLift));
207
208 curr_stn = &lift_bhv->lift_station;
209 GLOBALASSERT(curr_stn);
210
211 lift_ctrl = lift_bhv->lift_control;
212
213
214 /* ALL the lift modules have a Strategy block that contains inforamtion
215 about that particular location. Only one points to the LIFT CONTROL
216 BLOCK
217 */
218
219 /* the lifts will work between envs as well as on the same env
220 so the control of the doors in the other envs sin't actually set,
221 but a record of the postion is maintained
222 */
223
224
225
226 if(lift_bhv->controller)
227 {
228
229 // HACK - RWH - if this is true the data is broken and this fix won't always work
230
231 if(lift_ctrl->curr_station == -1)
232 lift_ctrl->curr_station = 0;
233
234 switch(lift_ctrl->state)
235 {
236 case I_ls_waiting:
237 {
238 /*** find dest and set movement direction this is always the
239 same even if the lift is on a different floor ***/
240 int lower_station = -1;
241 int upper_station = -1;
242 int i;
243 LIFT_STATION *lift_stn;
244
245 /**** find the nearest floors selected ****/
246
247 // search up and down
248 for(i = lift_ctrl->curr_station; (i >= 0) && (lower_station == -1); i --)
249 {
250 lift_stn = lift_ctrl->lift_stations[i];
251
252 if(lift_stn->called)
253 upper_station = i; // higher floors have lower nums
254 }
255 for(i = lift_ctrl->curr_station; (i < lift_ctrl->num_stations) && (upper_station == -1); i ++)
256 {
257 lift_stn = lift_ctrl->lift_stations[i];
258
259 if(lift_stn->called)
260 lower_station = i; // lower floors have higher nums
261 }
262
263 /****** set the destination and the motion direction ****/
264
265 if(lift_ctrl->motion == I_going_down)// higher nums
266 {
267 if(lower_station != -1)
268 {
269 lift_ctrl->dest_station = lower_station;
270 }
271 else
272 {
273 lift_ctrl->dest_station = upper_station;
274 lift_ctrl->motion =I_going_up;
275 }
276 }
277 else if(lift_ctrl->motion == I_going_up) // lower nums
278 {
279 if(upper_station != -1)
280 {
281 lift_ctrl->dest_station = upper_station;
282 }
283 else
284 {
285 lift_ctrl->dest_station = lower_station;
286 lift_ctrl->motion =I_going_down;
287 }
288 }
289
290 // now we have a station to go to, we start the lift in motion
291 // unless we have just pressed the current floor switch again
292
293 if(lift_ctrl->dest_station == lift_ctrl->curr_station)
294 {
295 // we have just called the lift to the same place
296 lift_ctrl->dest_station = -1;
297 lift_stn = lift_ctrl->lift_stations[lift_ctrl->curr_station];
298 lift_stn->called = 0;
299 }
300 else if(lift_ctrl->dest_station != -1)
301 {
302 // if there is a dest, set the lift to go
303 // close current stations
304 lift_stn = lift_ctrl->lift_stations[lift_ctrl->curr_station];
305
306 lift_ctrl->prev_station = lift_ctrl->curr_station;
307 if(lift_stn->lift_door)
308 {
309 // no door - must be on another env
310 RequestState(lift_stn->lift_door, 0, 0);
311 }
312 lift_ctrl->state = I_ls_closing_door;
313 }
314
315 break;
316 }
317 case I_ls_closing_door:
318 {
319 // lift station for the current lift position has to
320 // have a closed door
321
322 BOOL door_state;
323 LIFT_STATION *pos_stn = lift_ctrl->lift_stations[lift_ctrl->curr_station];
324 MODULE* mptr;
325
326 mptr = pos_stn->lift_module;
327
328 // deal with the fact that the lift is in a different env
329
330 // same env - normal code
331 // called from us to another env - normal code
332 // called from another env to us - jump the close door
333
334 if(pos_stn->env != AvP.CurrentEnv)
335 {
336 lift_ctrl->state = I_ls_moving;
337 lift_ctrl->delay_between_floors = LIFT_MOVE_DELAY;
338 break;
339 }
340
341 // otherwise run normal code
342 // close the door before we change state to moving
343
344 door_state = GetState(pos_stn->lift_door);
345
346 if(!door_state)
347 {
348 // turn off the current lift position station call switches
349 // run only when pos_stn is in our own env POSSIBLE BUG -
350 // lift wont be called to our floor if there is an Alien in it
351
352 if(BadGuyInModuleOrNoPlayer())
353 {
354 lift_ctrl->state = I_ls_opening_door;
355 lift_ctrl->dest_station = -1;
356 lift_ctrl->delay_between_floors = -1;
357 RequestState(pos_stn->lift_door, 1, 0);
358 }
359 else
360 {
361
362 lift_ctrl->state = I_ls_moving;
363 lift_ctrl->delay_between_floors = LIFT_MOVE_DELAY;
364
365 RequestState(pos_stn->lift_call_switch, 0, 0);
366 if(pos_stn->lift_floor_switch)
367 RequestState(pos_stn->lift_floor_switch, 0, 0);
368
369 //what if there is a bad guy in the lift - if there is open the door
370 //and reset all the switches and stations
371
372 if (lift_ctrl->SoundHandle==SOUND_NOACTIVEINDEX)
373 {
374 GLOBALASSERT(mptr);
375 Sound_Play(SID_LIFT_START,"dh",&mptr->m_world);
376 Sound_Play(SID_LIFT_LOOP,"delh",&mptr->m_world, &lift_ctrl->SoundHandle);
377 }
378 }
379
380 }
381 break;
382 }
383
384 case I_ls_moving:
385 {
386 int curr_station_num = lift_ctrl->curr_station;
387 LIFT_STATION *pos_stn = lift_ctrl->lift_stations[lift_ctrl->curr_station];
388 MODULE* mptr;
389 mptr = pos_stn->lift_module;
390
391
392
393 dest_env = lift_ctrl->lift_stations[lift_ctrl->dest_station]->env;
394
395 lift_ctrl->delay_between_floors -= NormalFrameTime;
396
397 // TRAP CHANGE OF ENVIRONMENT
398 // we need to trap it here so we don't have the delay
399 // between floors. However. The trap should make sure it is the nex array pos
400
401 if(AvP.CurrentEnv != dest_env)
402 {
403 // have to load an env - can we do it next - is the
404 // new env the next floor in the array??
405
406 if(lift_ctrl->motion == I_going_up)
407 {
408 curr_station_num --;
409 }
410 else
411 {
412 curr_station_num ++;
413 }
414 lift_ctrl->curr_station=curr_station_num;
415 if(curr_station_num == lift_ctrl->dest_station)
416 {
417 // OKAY chnage Environment VIA LIFT
418 // we need a copy of our current module pos
419 // (for the teleport), a copy of the
420 // SBs in our module and a copy of the lift
421 // control block
422
423 LIFT_STATION *lift_stn_old;
424 EC_Lift_Ctrl = *lift_ctrl;
425
426 lift_stn_old = EC_Lift_Ctrl.lift_stations[EC_Lift_Ctrl.prev_station];
427 Old_Pos_Module = *lift_stn_old->lift_module;
428
429 InitPreservedSBs();
430 PreserveStBlocksInModule(&Old_Pos_Module);
431
432 EC_Lift_Ctrl.curr_station = curr_station_num;
433 RequestEnvChangeViaLift = 1;
434
435 // we now do the rest of the SBs. before we
436 // can chack the env - note that NOTHING can move
437 // into the lift now.
438
439 }
440
441 }
442
443 // else do normal code
444
445 else if((lift_ctrl->delay_between_floors < 0))
446 {
447 if(lift_ctrl->motion == I_going_up)
448 {
449 lift_ctrl->curr_station --;
450 }
451 else
452 {
453 lift_ctrl->curr_station ++;
454 }
455
456
457
458 LOCALASSERT(lift_ctrl->curr_station >= 0);
459
460
461
462 if(lift_ctrl->curr_station == lift_ctrl->dest_station)
463 {
464 // at destination
465 LIFT_STATION *lift_stn_new = lift_ctrl->lift_stations[lift_ctrl->curr_station];
466 LIFT_STATION *lift_stn_old = lift_ctrl->lift_stations[lift_ctrl->prev_station];
467 MODULE *new_pos, *old_pos;
468
469 new_pos = lift_stn_new->lift_module;
470 old_pos = lift_stn_old->lift_module;
471
472 lift_ctrl->dest_station = -1;
473 lift_ctrl->state = I_ls_opening_door;
474
475 /* roxby: i have taken this out - patrick */
476 /* GLOBALASSERT(mptr); */
477 Sound_Play(SID_LIFT_END,"h");
478 Sound_Stop(lift_ctrl->SoundHandle);
479
480 // door open
481
482 RequestState(lift_stn_new->lift_door, 1, 0);
483
484 lift_stn_new->called = 0;
485
486 if(old_pos)
487 {
488 // if we don't have an old pos, we must
489 // be coming from another env
490 TeleportContents(new_pos, old_pos,lift_ctrl->floor_switches_fixed);
491 }
492 }
493
494 else
495 {
496 // interrupt monment to stop at new floor
497 //this should never happen in a seperate env
498 LIFT_STATION *lift_stn_new = lift_ctrl->lift_stations[lift_ctrl->curr_station];
499 LIFT_STATION *lift_stn_old = lift_ctrl->lift_stations[lift_ctrl->prev_station];
500 MODULE* old_pos, *new_pos;
501 // to trap button presses when moving between floors -
502 // not really ness and it complecates things
503 old_pos = lift_stn_old->lift_module;
504 new_pos = lift_stn_new->lift_module;
505 #if 0
506
507 if(lift_stn_new->called)
508 {
509 lift_ctrl->state = I_ls_opening_door;
510 RequestState(lift_stn_new->lift_call_switch, 0, 0);
511 if(lift_stn_new->lift_floor_switch)
512 RequestState(lift_stn_new->lift_floor_switch, 0, 0);
513 RequestState(lift_stn_new->lift_door, 1, 0);
514
515 if(old_pos)
516 {
517 // if we don't have an old pos, we must
518 // be coming from another env
519 TeleportContents(new_pos, old_pos,lift_ctrl->floor_switches_fixed);
520 }
521
522 lift_stn_new->called = 0;
523
524 }
525 else
526 #endif
527 {
528 // futher to go - move along now
529 lift_ctrl->delay_between_floors += LIFT_MOVE_DELAY;
530 }
531 }
532 }
533
534 break;
535 }
536 case I_ls_opening_door:
537 {
538 LIFT_STATION *lift_stn_new = lift_ctrl->lift_stations[lift_ctrl->curr_station];
539 BOOL door_state = GetState(lift_stn_new->lift_door);
540
541 if(door_state)
542 {
543 lift_ctrl->state = I_ls_delay_at_floor;
544 lift_ctrl->delay_at_floor = LIFT_FLOOR_DELAY;
545 }
546 break;
547 }
548 case I_ls_delay_at_floor:
549 {
550 lift_ctrl->delay_at_floor -= NormalFrameTime;
551
552 if(lift_ctrl->delay_at_floor < 0)
553 {
554 LIFT_STATION *lift_stn;
555
556 // turn on the floor lights
557 lift_stn = lift_ctrl->lift_stations[lift_ctrl->curr_station];
558
559 RequestState(lift_stn->lift_call_switch, 1, 0);
560 if(lift_stn->lift_floor_switch_name[0] || lift_stn->lift_floor_switch_name[4])
561 RequestState(lift_stn->lift_floor_switch, 1, 0);
562
563
564 lift_ctrl->state = I_ls_waiting;
565 lift_ctrl->dest_station = -1;
566
567 }
568 break;
569 }
570
571 default:
572
573 GLOBALASSERT(2<1);
574 }
575 }
576
577 }
578
579
TeleportContents(MODULE * new_pos,MODULE * old_pos,BOOL floor_switches_fixed)580 void TeleportContents(MODULE* new_pos, MODULE* old_pos,BOOL floor_switches_fixed)
581 {
582 // this used within level - find objects in module
583 // all will have sbs
584
585 int i;
586 int max_x, min_x, max_y, min_y, max_z, min_z;
587 int dest_max_x, dest_min_x, dest_max_y, dest_min_y, dest_max_z, dest_min_z;
588 VECTORCH mod_offset;
589
590 mod_offset.vx = new_pos->m_world.vx - old_pos->m_world.vx;
591 mod_offset.vy = new_pos->m_world.vy - old_pos->m_world.vy;
592 mod_offset.vz = new_pos->m_world.vz - old_pos->m_world.vz;
593
594 max_x = old_pos->m_maxx + old_pos->m_world.vx;
595 min_x = old_pos->m_minx + old_pos->m_world.vx;
596 max_y = old_pos->m_maxy + old_pos->m_world.vy;
597 min_y = old_pos->m_miny + old_pos->m_world.vy;
598 max_z = old_pos->m_maxz + old_pos->m_world.vz;
599 min_z = old_pos->m_minz + old_pos->m_world.vz;
600
601 dest_max_x = new_pos->m_maxx + new_pos->m_world.vx -200;
602 dest_min_x = new_pos->m_minx + new_pos->m_world.vx +200;
603 dest_max_y = new_pos->m_maxy + new_pos->m_world.vy -200;
604 dest_min_y = new_pos->m_miny + new_pos->m_world.vy +200;
605 dest_max_z = new_pos->m_maxz + new_pos->m_world.vz -200;
606 dest_min_z = new_pos->m_minz + new_pos->m_world.vz +200;
607
608 for(i = 0; i < NumActiveStBlocks; i++)
609 {
610 VECTORCH obj_world;
611 STRATEGYBLOCK *sbptr;
612 DYNAMICSBLOCK *dynptr;
613
614 sbptr = ActiveStBlockList[i];
615
616 if(!(dynptr = sbptr->DynPtr))
617 continue;
618
619 if(floor_switches_fixed)
620 {
621 if(sbptr->I_SBtype==I_BehaviourBinarySwitch || sbptr->I_SBtype==I_BehaviourLinkSwitch)
622 continue;
623 else if(sbptr->I_SBtype==I_BehaviourInanimateObject && ((INANIMATEOBJECT_STATUSBLOCK*)sbptr->SBdataptr)->typeId==0)
624 continue;
625 }
626 obj_world = dynptr->Position;
627
628 if(obj_world.vx < max_x)
629 if(obj_world.vx > min_x)
630 if(obj_world.vz < max_z)
631 if(obj_world.vz > min_z)
632 if(obj_world.vy < max_y)
633 if(obj_world.vy > min_y)
634 {
635
636 dynptr->Position.vx += mod_offset.vx;
637 dynptr->Position.vy += mod_offset.vy;
638 dynptr->Position.vz += mod_offset.vz;
639
640 dynptr->PrevPosition.vx += mod_offset.vx;
641 dynptr->PrevPosition.vy += mod_offset.vy;
642 dynptr->PrevPosition.vz += mod_offset.vz;
643
644 //make sure new location is inside destination module
645 if(!dynptr->IsStatic)
646 {
647 if(dynptr->Position.vx<dest_min_x) dynptr->Position.vx=dest_min_x;
648 if(dynptr->Position.vy<dest_min_y) dynptr->Position.vy=dest_min_y;
649 if(dynptr->Position.vz<dest_min_z) dynptr->Position.vz=dest_min_z;
650 if(dynptr->Position.vx>dest_max_x) dynptr->Position.vx=dest_max_x;
651 if(dynptr->Position.vy>dest_max_y) dynptr->Position.vy=dest_max_y;
652 if(dynptr->Position.vz>dest_max_z) dynptr->Position.vz=dest_max_z;
653
654 if(dynptr->PrevPosition.vx<dest_min_x) dynptr->PrevPosition.vx=dest_min_x;
655 if(dynptr->PrevPosition.vy<dest_min_y) dynptr->PrevPosition.vy=dest_min_y;
656 if(dynptr->PrevPosition.vz<dest_min_z) dynptr->PrevPosition.vz=dest_min_z;
657 if(dynptr->PrevPosition.vx>dest_max_x) dynptr->PrevPosition.vx=dest_max_x;
658 if(dynptr->PrevPosition.vy>dest_max_y) dynptr->PrevPosition.vy=dest_max_y;
659 if(dynptr->PrevPosition.vz>dest_max_z) dynptr->PrevPosition.vz=dest_max_z;
660 }
661
662 if(sbptr->maintainVisibility)
663 {
664 sbptr->containingModule = new_pos;
665 }
666 }
667 }
668 }
669
670
CleanUpLiftControl()671 void CleanUpLiftControl()
672 {
673 // okay - we have selected a new env AND it is the
674 // next env in the list - lets go with the load
675 // we need a copu list of strat blocks that WE DO NOT
676 // DEALLOCATE the behaviour / dyn blocks for. We then
677 // reinitialise AFTER these have been inserted into the
678
679
680 // ActiveStBlockList
681 LIFT_STATION *lift_stn = EC_Lift_Ctrl.lift_stations[EC_Lift_Ctrl.dest_station];
682
683 char dest_mod_name[8];
684 MODULE *new_pos_module;
685 int orient_diff;
686
687 STRATEGYBLOCK* new_loc_sbptr;
688
689 COPY_NAME(dest_mod_name, lift_stn->my_sb_name);
690
691 orient_diff = EC_Lift_Ctrl.lift_stations[EC_Lift_Ctrl.dest_station]->orient
692 - EC_Lift_Ctrl.lift_stations[EC_Lift_Ctrl.prev_station]->orient;
693
694
695 // DESTROYS ALL OUR OLD DATA - ONLY OUR
696 // COPIES REMAIN
697
698 ChangeEnvironmentToEnv(lift_stn->env);
699
700 IntegrateNewEnvironment();
701
702 // find where we have teleported to
703
704 new_loc_sbptr = FindSBWithName(dest_mod_name);
705 GLOBALASSERT(new_loc_sbptr);
706 new_pos_module = new_loc_sbptr->SBmoptr;
707
708 // teleport the bastrads
709 TeleportPreservedSBsToNewEnvModule(new_pos_module, &Old_Pos_Module,orient_diff);
710 AddPreservedSBsToActiveList();
711
712 // find the new control block anc copy our preserved one in
713 // need to recalc lift_station_new
714
715 {
716 LIFT_BEHAV_BLOCK *lift_bhv;
717 LIFT_CONTROL_BLOCK *lift_ctrl;
718 LIFT_STATION *lift_stn_new;
719
720 lift_bhv = (LIFT_BEHAV_BLOCK*)new_loc_sbptr->SBdataptr;
721 GLOBALASSERT((lift_bhv->bhvr_type == I_BehaviourLift));
722
723 lift_ctrl = lift_bhv->lift_control;
724
725 GLOBALASSERT(lift_ctrl->num_stations == EC_Lift_Ctrl.num_stations);
726
727 // copy over the vital bits
728
729 lift_ctrl->curr_station = EC_Lift_Ctrl.curr_station;
730 lift_ctrl->prev_station = EC_Lift_Ctrl.prev_station;
731 lift_ctrl->motion = EC_Lift_Ctrl.motion;
732
733 // and get into the right state
734
735 lift_ctrl->state = I_ls_opening_door;
736 lift_ctrl->dest_station = -1;
737
738 // and get the periphs into their right states
739 // get the new lift station
740 lift_stn_new = lift_ctrl->lift_stations[lift_ctrl->curr_station];
741
742 //set all the other station switches to off to overdide
743 // the starting_station init in AssignAllSBNames
744
745 {
746 int i;
747 LIFT_STATION *liftStnPtr;
748
749 for(i=0; i < lift_ctrl->num_stations; i++)
750 {
751 liftStnPtr = lift_ctrl->lift_stations[i];
752 if(liftStnPtr->env == AvP.CurrentEnv)
753 {
754 RequestState(liftStnPtr->lift_call_switch, 0, 0);
755 RequestState(liftStnPtr->lift_floor_switch, 0, 0);
756 RequestState(liftStnPtr->lift_door, 0, 0);
757 }
758 }
759 }
760
761 // set our current stations periphs into the correct
762 // state
763
764
765 RequestState(lift_stn_new->lift_call_switch, 1, 0);
766 RequestState(lift_stn_new->lift_floor_switch, 1, 0);
767 RequestState(lift_stn_new->lift_door, 1, 0);
768
769 TeleportFloorSwitches
770 (
771 lift_stn_new->lift_module,
772 lift_stn_new->lift_floor_switch->containingModule,
773 lift_ctrl
774 );
775
776 InitPreservedSBs();
777
778 UpdateWeaponShape(); // so we get the correct shape in the MSL
779 }
780 }
781
782
783
784
785
TeleportFloorSwitches(MODULE * dest,MODULE * src,LIFT_CONTROL_BLOCK * liftCtrl)786 static void TeleportFloorSwitches
787 (
788 MODULE* dest,
789 MODULE* src,
790 LIFT_CONTROL_BLOCK * liftCtrl
791 )
792 {
793 if(dest != src)
794 {
795 TeleportContents(dest, src, 0);
796 }
797 }
798