## XIII
Class XIIIPorte

source: C:\XIII\XIII\Classes\XIIIPorte.uc

    Core.Object
       |
       +--Engine.Actor
          |
          +--Engine.Mover
             |
             +--XIII.XIIIMover
                |
                +--XIII.XIIIPorte

Direct Known Subclasses:Porte

class XIIIPorte
extends XIII.XIIIMover

    //-----------------------------------------------------------
    //
    //-----------------------------------------------------------

Variables
`float` | `AutoCloseDelay` doorpoints utilises pour le recalage des basesoldiers
`Pawn` | `AutoCloseLastEventInstigator` doorpoints utilises pour le recalage des basesoldiers
`bool` | `AutoCloseMe` to force enemies to close door dehind them after opening
`int` | `CheckEncroachBack` to force enemies to close door dehind them after opening
`VECTOR` | `DoorDirection` to force enemies to close door dehind them after opening
`DoorPoint1,` | `DoorPoint2` doorpoints utilises pour le recalage des basesoldiers
`name` | `OpeningEvent` Time to unlock the door if locked (if initial state==locked)
`PosPositif,` | `PosNegatif` to force enemies to close door dehind them after opening
`ROTATOR` | `RotNegatif` to force enemies to close door dehind them after opening
`ROTATOR` | `RotPositif` to force enemies to close door dehind them after opening
`string` | `UnLockItemName` Item to use for unlocking the door
`name` | `UnlockEvent` Time to unlock the door if locked (if initial state==locked)
`string` | `UnlockItemCode` Item to use for unlocking the door
`bool` | `bCheckEncroach` to force enemies to close door dehind them after opening
`bool` | `bClimbAble` Player can climb on it (yes there are doors he can and other he can't, quite weirdos design but graphists want that :( )
`bool` | `bCloseDoor` to force enemies to close door dehind them after opening
`bool` | `bDansLes2Sens` the door can be opened from both side and rotate accordingly
`float` | `fUnlockTime` Time to unlock the door if locked (if initial state==locked)
`float` | `fUnlockTimer` to force enemies to close door dehind them after opening
`sound` | `hLockedSound` Item to use for unlocking the door
`sound` | `hUnlocksound` Item to use for unlocking the door

States
UnLocking

Function Summary
`void` | `Bump(Actor Other)`
    //____________________________________________________________________
`bool` | `CanBeOperated(Pawn EventInstigator)`
    //____________________________________________________________________
    // Used for doors that are openable on one side only
`void` | `DoAutoClose()`
    //____________________________________________________________________
    // Close the mover. but don't play closing sound
`void` | `DoOpen()`
    // Open the mover.
`bool` | `EncroachingOn(Actor Other)`
    //____________________________________________________________________
`void` | `FinishedClosing()`
    //____________________________________________________________________
    // Handle when the mover finishes opening.
`void` | `FinishedOpening()`
    //____________________________________________________________________
    // Handle when the mover finishes opening.
`void` | `PlayerTrigger(Actor Other, Pawn EventInstigator)`
`void` | `PostBeginPlay()`
    //____________________________________________________________________
`void` | `Trigger(Actor Other, Pawn EventInstigator)`
    //____________________________________________________________________

State UnLocking Function Summary
`void` | `UnTrigger(Actor Other, Pawn EventInstigator)`
`void` | `Trigger(Actor Other, Pawn EventInstigator)`
`void` | `PlayerTrigger(Actor Other, Pawn EventInstigator)`
`bool` | `CanBeOperated(Pawn EventInstigator)`
`void` | `BeginState()`
    //____________________________________________________________________
    // ELR Add PlayerTrigger
`void` | `Tick(float dT)`
`void` | `UnTrigger(Actor Other, Pawn EventInstigator)`

Source Code

    00001	//-----------------------------------------------------------
    00002	//
    00003	//-----------------------------------------------------------
    00004	class XIIIPorte extends XIIIMover
    00005	  abstract;
    00006
    00007	VAR() bool bDansLes2Sens;       // the door can be opened from both side and rotate accordingly
    00008	VAR() bool bClimbAble;          // Player can climb on it (yes there are doors he can and other he can't, quite weirdos design but graphists want that :( )
    00009	VAR() bool bCloseDoor;          // to force enemies to close door dehind them after opening
    00010	VAR() bool AutoCloseMe;
    00011	VAR() bool bCheckEncroach;
    00012	VAR() int CheckEncroachBack;
    00013	VAR ROTATOR RotPositif;
    00014	VAR ROTATOR RotNegatif;
    00015	VAR VECTOR PosPositif, PosNegatif;
    00016	VAR VECTOR DoorDirection;
    00017	VAR float fUnlockTimer;
    00018	VAR() float fUnlockTime;        // Time to unlock the door if locked (if initial state==locked)
    00019	VAR() name UnlockEvent;
    00020	VAR() name OpeningEvent;
    00021	VAR() string UnLockItemName;  // Item to use for unlocking the door
    00022	VAR() string UnlockItemCode;
    00023	VAR() sound hUnlocksound;
    00024	VAR() sound hLockedSound;
    00025	VAR navigationpoint DoorPoint1, DoorPoint2;        //doorpoints utilises pour le recalage des basesoldiers
    00026	VAR() float AutoCloseDelay;
    00027	VAR Pawn AutoCloseLastEventInstigator;
    00028
    00029	//____________________________________________________________________
    00030	function PostBeginPlay()
    00031	{
    00032	    local int a1,a2;
    00033	    local rotator R1,R2;
    00034	    local navigationpoint DP,BestDP1,BestDP2;
    00035
    00036	    Super.PostBeginPlay();
    00037	    if (bDansLes2Sens)
    00038	    {
    00039	      a1 = ((KeyRot[1].Yaw+32768)&65535)-32768;
    00040	      a2 = ((KeyRot[2].Yaw+32768)&65535)-32768;
    00041	      if ((a1<0) && (a2>0))
    00042	      {
    00043	        RotPositif=KeyRot[2];
    00044	        RotNegatif=KeyRot[1];
    00045	        PosPositif=KeyPos[2];
    00046	        PosNegatif=KeyPos[1];
    00047	      }
    00048	      else if ((a1>0) && (a2<0))
    00049	      {
    00050	        RotPositif=KeyRot[1];
    00051	        RotNegatif=KeyRot[2];
    00052	        PosPositif=KeyPos[1];
    00053	        PosNegatif=KeyPos[2];
    00054	      }
    00055	      else
    00056	      {
    00057	//        PlayerController(Level.ControllerList).MyHud.LocalizedMessage(class'XIIISoloMessage',0, none,none,none,"Probleme sur la Porte '"@Name@"', Passage en mode classique.");
    00058	//        Log("Probleme sur la Porte '"@Name@"', Passage en mode classique.");
    00059	        bDansLes2Sens=false;
    00060	      }
    00061	      if ( KeyNum == 2 )
    00062	      {
    00063	        R1 = KeyRot[2];
    00064	        KeyRot[2] = KeyRot[1];
    00065	        KeyRot[1] = R1;
    00066	        KeyNum = 1;
    00067	      }
    00068	    }
    00069	    if (KeyNum != 0)
    00070	    { // ELR Try to make doors able to be initiated at key != 0
    00071	      bOpened=true;
    00072	      bClosed=false;
    00073	    }
    00074	    PrevKeyNum = KeyNum;
    00075
    00076	/*
    00077	    if ( KeyNum == 0 )
    00078	      vPawnPushdir = normal(vector(rotation) cross vect(0,0,1));
    00079	    else
    00080	      vPawnPushdir = normal(vector(rotation));
    00081	*/
    00082
    00083	    //cherche doorpoints
    00084	     BestDP1=none;
    00085	     foreach RadiusActors(class 'NavigationPoint', DP, 350)  // les doorspoints a moins de 4.5 m
    00086	     {
    00087	        if (DP.IsA('doorpoint'))
    00088	        {
    00089	             if (BestDP1==none || vsize(BestDP1.location-self.location)>vsize(DP.location-self.location))
    00090	             {
    00091	                bestdp2=bestDP1;
    00092	                BestDP1=DP;
    00093	             }
    00094	             else if (BestDP2==none || vsize(BestDP2.location-self.location)>vsize(DP.location-self.location))
    00095	                 BestDP2=DP;
    00096	        }
    00097	     }
    00098	     if (bestDP1!=none && bestDP2!=none)
    00099	     {
    00100	         DoorPoint1=bestDP1;
    00101	         DoorPoint2=bestDP2;
    00102	     }
    00103
    00104	   //unlock time is 0 if lockpick is not necessary
    00105	   if (UnlockItemCode != "LockPick")
    00106	     {
    00107	       fUnlockTime = 0;
    00108	   }
    00109	}
    00110
    00111
    00112	// Open the mover.
    00113	function DoOpen()
    00114	{
    00115	  if ( !bOpening )
    00116	    TriggerEvent( OpeningEvent, self, none );
    00117
    00118	  Super.DoOpen();
    00119	}
    00120
    00121	//____________________________________________________________________
    00122	event Timer()
    00123	{
    00124	//    Log(self@"Timer bOpening"@bOpening@"bOpened"@bOpened@"bClosed"@bClosed@"bWarnSoldiers"@bWarnSoldiers@"bAlertIfSeenOpen"@bAlertIfSeenOpen);
    00125	    if ( bCheckEncroach && !bOpened && !bClosed )
    00126	    {
    00127	      CheckEncroachBack ++;
    00128	      if ( CheckEncroachBack >= 2 )
    00129	      {
    00130	        if ( bOpening )
    00131	//          DoClose();
    00132	          GotoState(GetStateName(), 'Close');
    00133	        else
    00134	//          DoOpen();
    00135	          GotoState(GetStateName(), 'Open');
    00136	        bCheckEncroach = false;
    00137	        CheckEncroachBack = 0;
    00138	        if ( !bWarnSoldiers )
    00139	        {
    00140	          SetTimer(0.0, false);
    00141	          return;
    00142	        }
    00143	      }
    00144	    }
    00145	    else
    00146	    {
    00147	      bCheckEncroach = false;
    00148	      CheckEncroachBack = 0;
    00149	      if ( !bWarnSoldiers )
    00150	      {
    00151	        SetTimer(0.0, false);
    00152	        return;
    00153	      }
    00154	    }
    00155	    if ( bWarnSoldiers )
    00156	      Super.Timer();
    00157	}
    00158
    00159	//____________________________________________________________________
    00160	// Handle when the mover finishes opening.
    00161	function FinishedOpening()
    00162	{
    00163	    bCheckEncroach = false;
    00164	    Super.FinishedOpening();
    00165	}
    00166
    00167	//____________________________________________________________________
    00168	// Handle when the mover finishes opening.
    00169	function FinishedClosing()
    00170	{
    00171	    bCheckEncroach = false;
    00172	    Super.FinishedClosing();
    00173	}
    00174
    00175	//____________________________________________________________________
    00176	function bool EncroachingOn( actor Other )
    00177	{
    00178	    if ( !bCheckEncroach )
    00179	    {
    00180	//      Log(self@"EncroachingOn"@other@"set timer to auto-close");
    00181	      bCheckEncroach = true;
    00182	      SetTimer(2.0, true);
    00183	    }
    00184	    if ( Other.IsA('InteractiveCan') )
    00185	      Other.TakeDamage(100, AutoCloseLastEventInstigator, Location, 200.0 * (Other.Location - Location + vect(0,0,1)), class'Crushed');
    00186	    return true;
    00187	}
    00188
    00189	//____________________________________________________________________
    00190	function Bump( actor Other )
    00191	{
    00192	    if (bDansLes2Sens)
    00193	    {
    00194	      If (Other.Velocity != vect(0,0,0))
    00195	      {
    00196	        if ((Other.Velocity cross (BasePos - Other.Location)).z>0)
    00197	        {
    00198	          KeyRot[1]=RotPositif;
    00199	          KeyPos[1]=PosPositif;
    00200	        }
    00201	        else
    00202	        {
    00203	          KeyRot[1]=RotNegatif;
    00204	          KeyPos[1]=PosNegatif;
    00205	        }
    00206	      }
    00207	      else
    00208	      {
    00209	        if ((vector(Other.rotation) cross (BasePos - Other.Location)).z>0)
    00210	        {
    00211	          KeyRot[1]=RotPositif;
    00212	          KeyPos[1]=PosPositif;
    00213	        }
    00214	        else
    00215	        {
    00216	          KeyRot[1]=RotNegatif;
    00217	          KeyPos[1]=PosNegatif;
    00218	        }
    00219	      }
    00220	    }
    00221	    super.Bump(other);
    00222	}
    00223
    00224	//____________________________________________________________________
    00225	// Close the mover. but don't play closing sound
    00226	function DoAutoClose()
    00227	{
    00228	    bOpening = false;
    00229	    bOpened = false;
    00230	    bDelaying = false;
    00231	    InterpolateTo( Max(0,KeyNum-1), MoveTime );
    00232	//    PlaySound( ClosingSound );
    00233	    if ( !bMusicOnlyOnce || !bAlreadyClosing )
    00234	    {
    00235	      bAlreadyClosing = true;
    00236	      PlayMusic( ClosingMusic );
    00237	    }
    00238	    UntriggerEvent(Event, self, Instigator);
    00239	    PlaySound(MoveAmbientSound);
    00240	}
    00241
00242 //____________________________________________________________________ 00243 // Used for doors that are openable on one side only 00244 function bool CanBeOperated(Pawn EventInstigator) 00245 { 00246 return true; 00247 } 00248 00249 00250 //____________________________________________________________________ 00251 state() Locked 00252 { 00253 ignores bump, UnTrigger; 00254 00255 function Trigger( actor Other, pawn EventInstigator ) 00256 { 00257 // Log(")))"@self@"Trigger other "$Other$" instigator "$EventInstigator); 00258 if ( (Other == none) || (Inventory(Other) == none) || (EventInstigator == none) ) 00259 return; 00260 if ( (Caps(UnLockItemName) == Caps(inventory(Other).ItemName)) || (Caps(UnlockItemCode) == Caps(Keys(Other).KeyCodeName)) ) 00261 { 00262 if ( (EventInstigator.FindInventorykind('PickLockSkill') == none) || (UnLockItemName!="LockPick") ) 00263 fUnlockTimer = fUnlockTime; 00264 else 00265 fUnlockTimer = fUnlockTime/3.0; 00266 //::DBUG:: 00267 // Log(")))"@self@"Time Before Opening Door="$fUnlockTimer); 00268 if ( fUnlockTimer > 0 ) 00269 XIIIPlayerController(EventInstigator.controller).MyHud.LocalizedMessage(class'XIIISoloMessage', 1); 00270 if ( fUnlockTimer > 0.0 ) 00271 GotoState('UnLocking'); 00272 else 00273 { // instant unlock 00274 gotostate('PlayerTriggerToggle'); 00275 PlaySound(hUnlockSound); 00276 if (UnlockEvent!='') 00277 TriggerEvent(UnlockEvent,self,none); 00278 } 00279 } 00280 else 00281 { 00282 //::DBUG:: 00283 // Log(")))"@self@"Trying to be unlocked with "$Caps(Keys(Other).KeyCodeName)$" (should be "$Caps(UnlockItemCode)$")"); 00284 00285 if ( LockPick(Other) != none ) 00286 XIIIPlayerController(EventInstigator.controller).MyHud.LocalizedMessage(class'XIIISoloMessage', 12); 00287 else 00288 XIIIPlayerController(EventInstigator.controller).MyHud.LocalizedMessage(class'XIIISoloMessage', 6); 00289 } 00290 } 00291 00292 function PlayerTrigger( actor Other, pawn EventInstigator ) 00293 { 00294 PlaySound(hLockedSound); 00295 } 00296 } 00297 00298 //____________________________________________________________________ 00299 state UnLocking 00300 { 00301 ignores Bump, Trigger; 00302 00303 function UnTrigger( actor Other, pawn EventInstigator ) 00304 { 00305 fUnlockTimer=0.0; 00306 XIIIPlayerController(EventInstigator.controller).MyHud.LocalizedMessage(class'XIIISoloMessage', 7); 00307 GotoState('Locked'); 00308 } 00309 00310 function Tick( float dT ) 00311 { 00312 fUnlockTimer -= dT; 00313 if (fUnlockTimer <= 0.0 ) 00314 { 00315 gotostate('PlayerTriggerToggle'); 00316 PlaySound(hUnlockSound); 00317 if (UnlockEvent!='') 00318 TriggerEvent(UnlockEvent,self,none); 00319 } 00320 } 00321 00322 } 00323 00324 //____________________________________________________________________ 00325 // ELR Add PlayerTrigger 00326 state() PlayerTriggerToggle 00327 { 00328 ignores bump; 00329 00330 FUNCTION BeginState() 00331 { 00332 LOCAL BOX BBox; 00333 00334 Super.BeginState(); 00335 disable('tick'); 00336 00337 BBox = GetBoundingBox(); 00338 DoorDirection = ( 0.5 * ( BBox.Min + BBox.Max ) - Location)<<KeyRot[KeyNum]; 00339 DoorDirection.Z = 0; 00340 } 00341 00342 EVENT Trigger( actor Other, pawn EventInstigator ) 00343 { 00344 PlayerTrigger( Other, EventInstigator ); 00345 } 00346 00347 function bool CanBeOperated(Pawn EventInstigator) 00348 { 00349 local vector vTemp; 00350 local bool bBlocked; 00351 00352 if ( (KeyNum != 0) || !bClosed ) 00353 return true; 00354 00355 if ( bDansLes2Sens ) 00356 { 00357 vTemp = BasePos - EventInstigator.Location; 00358 vTemp.Z = 0; 00359 if ( ( DoorDirection cross vTemp ).Z > 0 ) 00360 { 00361 KeyRot[1]=RotPositif; 00362 KeyPos[1]=PosPositif; 00363 bBlocked= (BloqueePourLeJoueur==SensPositif)||(BloqueePourLeJoueur==Les2Sens); 00364 } 00365 else 00366 { 00367 KeyRot[1]=RotNegatif; 00368 KeyPos[1]=PosNegatif; 00369 bBlocked= (BloqueePourLeJoueur==SensNegatif)||(BloqueePourLeJoueur==Les2Sens) ; 00370 } 00371 } 00372 else 00373 { 00374 if ( (vector(EventInstigator.rotation) cross (BasePos - EventInstigator.Location)).z>0 ) 00375 { 00376 bBlocked= (BloqueePourLeJoueur==SensPositif)||(BloqueePourLeJoueur==Les2Sens) ; 00377 } 00378 else 00379 { 00380 bBlocked= (BloqueePourLeJoueur==SensNegatif)||(BloqueePourLeJoueur==Les2Sens) ; 00381 } 00382 } 00383 bBlocked = bBlocked && EventInstigator.IsPlayerPawn(); 00384 return !bBlocked; 00385 } 00386 FUNCTION PlayerTrigger( actor Other, pawn EventInstigator ) 00387 { 00388 LOCAL VECTOR vTemp; 00389 local bool bBlocked; 00390 00391 if (bOpened || bClosed) 00392 { 00393 SavedTrigger = Other; 00394 Instigator = EventInstigator; 00395 AutoCloseLastEventInstigator = EventInstigator; 00396 if ( SavedTrigger != None ) 00397 SavedTrigger.BeginEvent(); 00398 if( KeyNum==0 ) 00399 { 00400 if ( bDansLes2Sens ) 00401 { 00402 vTemp = BasePos - EventInstigator.Location; 00403 vTemp.Z = 0; 00404 if ( ( DoorDirection cross vTemp ).Z > 0 ) 00405 { 00406 KeyRot[1]=RotPositif; 00407 KeyPos[1]=PosPositif; 00408 bBlocked= (BloqueePourLeJoueur==SensPositif)||(BloqueePourLeJoueur==Les2Sens); 00409 } 00410 else 00411 { 00412 KeyRot[1]=RotNegatif; 00413 KeyPos[1]=PosNegatif; 00414 bBlocked= (BloqueePourLeJoueur==SensNegatif)||(BloqueePourLeJoueur==Les2Sens) ; 00415 } 00416 } 00417 else 00418 { 00419 if ( (vector(EventInstigator.rotation) cross (BasePos - EventInstigator.Location)).z>0 ) 00420 { 00421 bBlocked= (BloqueePourLeJoueur==SensPositif)||(BloqueePourLeJoueur==Les2Sens) ; 00422 } 00423 else 00424 { 00425 bBlocked= (BloqueePourLeJoueur==SensNegatif)||(BloqueePourLeJoueur==Les2Sens) ; 00426 } 00427 } 00428 bBlocked = bBlocked && EventInstigator.IsPlayerPawn(); 00429 if (!bBlocked) 00430 { 00431 if ( bAlertIfSeenOpen && EventInstigator.IsPlayerPawn()) 00432 { 00433 SetTimer(2.0,true); 00434 bWarnSoldiers = true; 00435 } 00436 GotoState( 'PlayerTriggerToggle', 'Open' ); 00437 } 00438 } 00439 else 00440 { 00441 if ( bAlertIfSeenOpen && EventInstigator.IsPlayerPawn()) 00442 { 00443 SetTimer(2.0,true); 00444 bWarnSoldiers = true; 00445 } 00446 GotoState( 'PlayerTriggerToggle', 'Close' ); 00447 } 00448 } 00449 } 00450 00451 event Timer2() 00452 { 00453 local vector tV; 00454 00455 00456 tV = AutoCloseLastEventInstigator.Location - Location; 00457 // tV.Z = 0.0; 00458 // if ( bOpened && (vSize(tV) > 200.0) && (vector(AutoCloseLastEventInstigator.rotation) dot tV > 0.0) ) 00459 // optimize 2 lines above 00460 if ( bOpened && ((tV.X*tv.X+tV.Y*tV.y) > 40000.0) && (Level.TimeSeconds - LastRenderTime > 1.0) ) 00461 GotoState( 'PlayerTriggerToggle', 'AutoClose' ); 00462 else if ( bClosed ) 00463 SetTimer2(1.0, false); 00464 // PlayerTrigger(none, AutoCloseLastEventInstigator); 00465 } 00466 Open: 00467 bClosed = false; 00468 DoOpen(); 00469 FinishInterpolation(); 00470 FinishedOpening(); 00471 if ( SavedTrigger != None ) 00472 SavedTrigger.EndEvent(); 00473 if( bTriggerOnceOnly ) 00474 { 00475 bInteractive = false; 00476 GotoState(''); 00477 stop; 00478 } 00479 if ( AutoCloseMe ) 00480 SetTimer2(AutoCloseDelay, false); 00481 Stop; 00482 Close: 00483 SetTimer2(0.0, false); 00484 DoClose(); 00485 FinishInterpolation(); 00486 FinishedClosing(); 00487 if( bTriggerOnceOnly ) 00488 { 00489 bInteractive = false; 00490 GotoState(''); 00491 } 00492 stop; 00493 AutoClose: 00494 SetTimer2(0.0, false); 00495 DoAutoClose(); 00496 FinishInterpolation(); 00497 FinishedClosing(); 00498 if( bTriggerOnceOnly ) 00499 { 00500 bInteractive = false; 00501 GotoState(''); 00502 } 00503 stop; 00504 } 00505 00506 state() AnyTriggerToggle 00507 { 00508 function Trigger( actor Other, pawn EventInstigator ) 00509 { 00510 SavedTrigger = Other; 00511 Instigator = EventInstigator; 00512 if ( SavedTrigger != None ) 00513 SavedTrigger.BeginEvent(); 00514 if( KeyNum==0 || KeyNum<PrevKeyNum ) 00515 GotoState( 'AnyTriggerToggle', 'Open' ); 00516 else 00517 GotoState( 'AnyTriggerToggle', 'Close' ); 00518 } 00519 function UnTrigger( actor Other, pawn EventInstigator ) 00520 { 00521 Trigger( Other, EventInstigator ); 00522 } 00523 Open: 00524 bClosed = false; 00525 if ( DelayTime > 0 ) 00526 { 00527 bDelaying = true; 00528 Sleep(DelayTime); 00529 } 00530 DoOpen(); 00531 FinishInterpolation(); 00532 FinishedOpening(); 00533 if ( SavedTrigger != None ) 00534 SavedTrigger.EndEvent(); 00535 Stop; 00536 Close: 00537 DoClose(); 00538 FinishInterpolation(); 00539 FinishedClosing(); 00540 } 00541 00542 00543 00544 00545 defaultproperties 00546 { 00547 bDansLes2Sens=True 00548 AutoCloseMe=True 00549 UnLockItemName="LockPick" 00550 UnlockItemCode="LockPick" 00551 hUnlocksound=Sound'XIIIsound.Items.LockSucc1' 00552 AutoCloseDelay=15.000000 00553 InitialState="PlayerTriggerToggle" 00554 }

End Source Code