| | 1 | #include "system.h" |
| | 2 | #include "prototyp.h" |
| | 3 | #include "stratdef.h" |
| | 4 | #include "weapons.h" |
| | 5 | #include "platformlift.h" |
| | 6 | #include "pldghost.h" |
| | 7 | #include "bh_types.h" |
| | 8 | #include <stdlib.h> |
| | 9 | #include <assert.h> |
| | 10 | |
| | 11 | static void SquashingSomething_for_sure(DYNAMICSBLOCK *dynPtr) |
| | 12 | { |
| | 13 | struct collisionreport *nextReport = dynPtr->CollisionReportPtr; |
| | 14 | |
| | 15 | while(nextReport) |
| | 16 | { |
| | 17 | STRATEGYBLOCK *sbPtr = nextReport->ObstacleSBPtr; |
| | 18 | |
| | 19 | if(sbPtr) |
| | 20 | { |
| | 21 | sbPtr->DamageBlock.Indestructable = 0; |
| | 22 | CauseDamageToObject(sbPtr, &damage_profiles[FALLINGDAMAGE], (100*NormalFrameTime), NULL); |
| | 23 | } |
| | 24 | |
| | 25 | nextReport = nextReport->NextCollisionReportPtr; |
| | 26 | } |
| | 27 | } |
| | 28 | |
| | 29 | static void SquashingSomething(DYNAMICSBLOCK *dynPtr) |
| | 30 | { |
| | 31 | struct collisionreport *nextReport = dynPtr->CollisionReportPtr; |
| | 32 | |
| | 33 | /* walk the collision report list, looking for collisions against objects */ |
| | 34 | while(nextReport) |
| | 35 | { |
| | 36 | STRATEGYBLOCK *sbPtr = nextReport->ObstacleSBPtr; |
| | 37 | |
| | 38 | if(sbPtr) |
| | 39 | { |
| | 40 | if(nextReport->ObstacleNormal.vy < -46340) |
| | 41 | { |
| | 42 | /* squish! */ |
| | 43 | sbPtr->DamageBlock.Indestructable = 0; |
| | 44 | CauseDamageToObject(sbPtr, &damage_profiles[FALLINGDAMAGE], (100*NormalFrameTime), NULL); |
| | 45 | } |
| | 46 | else if (nextReport->ObstacleNormal.vy > 46340) |
| | 47 | { |
| | 48 | DYNAMICSBLOCK *objDynPtr = sbPtr->DynPtr; |
| | 49 | |
| | 50 | if (objDynPtr && (objDynPtr->LinImpulse.vy < PLATFORMLIFT_SPEED)) |
| | 51 | objDynPtr->LinImpulse.vy += PLATFORMLIFT_SPEED; |
| | 52 | } |
| | 53 | } |
| | 54 | |
| | 55 | nextReport = nextReport->NextCollisionReportPtr; |
| | 56 | } |
| | 57 | } |
| | 58 | |
| | 59 | static int PlayerIsNearOtherTerminal(STRATEGYBLOCK *sbPtr) |
| | 60 | { |
| | 61 | PLATFORMLIFT_BEHAVIOUR_BLOCK *platformliftdata = (PLATFORMLIFT_BEHAVIOUR_BLOCK *)sbPtr->dataptr; |
| | 62 | assert(platformliftdata->state == PLBS_AtRest); |
| | 63 | DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr; |
| | 64 | |
| | 65 | int averageHeight = (platformliftdata->upHeight + platformliftdata->downHeight)/2; |
| | 66 | |
| | 67 | if(dynPtr->Position.vy > averageHeight) |
| | 68 | { |
| | 69 | if (PlayerStatus.sbptr->DynPtr->Position.vy < averageHeight) |
| | 70 | return 1; |
| | 71 | } |
| | 72 | else |
| | 73 | { |
| | 74 | if (PlayerStatus.sbptr->DynPtr->Position.vy > averageHeight) |
| | 75 | return 1; |
| | 76 | } |
| | 77 | |
| | 78 | return 0; |
| | 79 | } |
| | 80 | |
| | 81 | static int ActivatedByPlayer(DYNAMICSBLOCK *dynPtr) |
| | 82 | { |
| | 83 | struct collisionreport *nextReport = dynPtr->CollisionReportPtr; |
| | 84 | |
| | 85 | /* walk the collision report list, looking for collisions against objects */ |
| | 86 | while(nextReport) |
| | 87 | { |
| | 88 | //printf("collision with %p\n",nextReport->ObstacleSBPtr); |
| | 89 | if(nextReport->ObstacleSBPtr == PlayerStatus.sbptr) |
| | 90 | return 1; |
| | 91 | |
| | 92 | nextReport = nextReport->NextCollisionReportPtr; |
| | 93 | } |
| | 94 | |
| | 95 | return 0; |
| | 96 | } |
| | 97 | |
| | 98 | static int PLiftIsNearerUpThanDown(STRATEGYBLOCK *sbPtr) |
| | 99 | { |
| | 100 | assert(sbPtr); |
| | 101 | PLATFORMLIFT_BEHAVIOUR_BLOCK *platformliftdata = (PLATFORMLIFT_BEHAVIOUR_BLOCK *)sbPtr->dataptr; |
| | 102 | assert(sbPtr->DynPtr); |
| | 103 | |
| | 104 | int upDist = sbPtr->DynPtr->Position.vy - platformliftdata->upHeight; |
| | 105 | int downDist = platformliftdata->downHeight - sbPtr->DynPtr->Position.vy; |
| | 106 | |
| | 107 | return (upDist < downDist); |
| | 108 | } |
| | 109 | |
| | 110 | /* returns 1 if the player or a remote player is within 5 m of the other end of the lift track...*/ |
| | 111 | static int NetPlayerAtOtherTerminal(STRATEGYBLOCK *sbPtr) |
| | 112 | { |
| | 113 | int sbIndex = 0; |
| | 114 | VECTORCH otherTerminal; |
| | 115 | |
| | 116 | assert(sbPtr); |
| | 117 | PLATFORMLIFT_BEHAVIOUR_BLOCK *platformliftdata = (PLATFORMLIFT_BEHAVIOUR_BLOCK *)sbPtr->dataptr; |
| | 118 | assert(platformliftdata); |
| | 119 | assert(platformliftdata->state == PLBS_AtRest); |
| | 120 | DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr; |
| | 121 | assert(dynPtr); |
| | 122 | |
| | 123 | if(PLiftIsNearerUpThanDown(sbPtr)) |
| | 124 | { |
| | 125 | otherTerminal = dynPtr->Position; |
| | 126 | otherTerminal.vy = platformliftdata->downHeight; |
| | 127 | } |
| | 128 | else |
| | 129 | { |
| | 130 | otherTerminal = dynPtr->Position; |
| | 131 | otherTerminal.vy = platformliftdata->upHeight; |
| | 132 | } |
| | 133 | |
| | 134 | while(sbIndex < NumActiveStBlocks) |
| | 135 | { |
| | 136 | STRATEGYBLOCK *sbPtr = ActiveStBlockList[sbIndex++]; |
| | 137 | |
| | 138 | if(sbPtr->type == I_BehaviourNetGhost) |
| | 139 | { |
| | 140 | NETGHOSTDATABLOCK *ghostData = ghostData = (NETGHOSTDATABLOCK *)sbPtr->dataptr; |
| | 141 | assert(ghostData); |
| | 142 | |
| | 143 | switch(ghostData->type) |
| | 144 | { |
| | 145 | case I_BehaviourMarinePlayer: |
| | 146 | case I_BehaviourAlienPlayer: |
| | 147 | case I_BehaviourPredatorPlayer: |
| | 148 | { |
| | 149 | /* remote player */ |
| | 150 | assert(sbPtr->DynPtr); |
| | 151 | if(VectorDistance(&(sbPtr->DynPtr->Position),&(otherTerminal)) < 5000) |
| | 152 | return 1; |
| | 153 | } |
| | 154 | default: |
| | 155 | break; |
| | 156 | } |
| | 157 | } |
| | 158 | else if(sbPtr == PlayerStatus.sbptr) |
| | 159 | { |
| | 160 | /* local player */ |
| | 161 | assert(sbPtr->DynPtr); |
| | 162 | if(VectorDistance(&sbPtr->DynPtr->Position, &otherTerminal) < 5000) |
| | 163 | return 1; |
| | 164 | } |
| | 165 | } |
| | 166 | return 0; |
| | 167 | } |
| | 168 | |
| | 169 | static void StopPlatformLift(STRATEGYBLOCK *sbPtr) |
| | 170 | { |
| | 171 | PLATFORMLIFT_BEHAVIOUR_BLOCK *platformliftdata = (PLATFORMLIFT_BEHAVIOUR_BLOCK *)sbPtr->dataptr; |
| | 172 | assert(platformliftdata); |
| | 173 | |
| | 174 | sbPtr->DynPtr->Displacement.vx = sbPtr->DynPtr->Displacement.vy = sbPtr->DynPtr->Displacement.vz = 0; |
| | 175 | platformliftdata->state = PLBS_AtRest; |
| | 176 | |
| | 177 | /* just to stop drift... */ |
| | 178 | /* |
| | 179 | if(PLiftIsNearerUpThanDown(sbPtr)) |
| | 180 | sbPtr->DynPtr->Position.vy = platformliftdata->upHeight; |
| | 181 | else |
| | 182 | sbPtr->DynPtr->Position.vy = platformliftdata->downHeight; |
| | 183 | */ |
| | 184 | |
| | 185 | platformliftdata->netMsgCount = PLATFORMLIFT_NUMNETMESSAGES; |
| | 186 | |
| | 187 | //stop sound if the lift has any |
| | 188 | if(platformliftdata->sound) |
| | 189 | Stop_Track_Sound(platformliftdata->sound); |
| | 190 | |
| | 191 | //start end sound if lift has any |
| | 192 | if(platformliftdata->end_sound) |
| | 193 | Start_Track_Sound(platformliftdata->end_sound,&sbPtr->DynPtr->Position); |
| | 194 | } |
| | 195 | |
| | 196 | static void SendPlatformLiftUp(STRATEGYBLOCK *sbPtr) |
| | 197 | { |
| | 198 | PLATFORMLIFT_BEHAVIOUR_BLOCK *platformliftdata = (PLATFORMLIFT_BEHAVIOUR_BLOCK *)sbPtr->dataptr; |
| | 199 | assert(platformliftdata); |
| | 200 | |
| | 201 | platformliftdata->state = PLBS_GoingUp; |
| | 202 | sbPtr->DynPtr->Displacement.vx = sbPtr->DynPtr->Displacement.vz = 0; |
| | 203 | platformliftdata->netMsgCount = PLATFORMLIFT_NUMNETMESSAGES; |
| | 204 | |
| | 205 | sbPtr->DynPtr->Displacement.vy = -MUL_FIXED(PLATFORMLIFT_SPEED, NormalFrameTime); |
| | 206 | { |
| | 207 | int d = platformliftdata->upHeight - sbPtr->DynPtr->Position.vy; |
| | 208 | |
| | 209 | if (d > sbPtr->DynPtr->Displacement.vy) |
| | 210 | sbPtr->DynPtr->Displacement.vy = d; |
| | 211 | } |
| | 212 | } |
| | 213 | |
| | 214 | static void SendPlatformLiftDown(STRATEGYBLOCK *sbPtr) |
| | 215 | { |
| | 216 | PLATFORMLIFT_BEHAVIOUR_BLOCK *platformliftdata = (PLATFORMLIFT_BEHAVIOUR_BLOCK *)sbPtr->dataptr; |
| | 217 | assert(platformliftdata); |
| | 218 | |
| | 219 | platformliftdata->state = PLBS_GoingDown; |
| | 220 | sbPtr->DynPtr->Displacement.vx = sbPtr->DynPtr->Displacement.vz = 0; |
| | 221 | platformliftdata->netMsgCount = PLATFORMLIFT_NUMNETMESSAGES; |
| | 222 | |
| | 223 | sbPtr->DynPtr->Displacement.vy = MUL_FIXED(PLATFORMLIFT_SPEED, NormalFrameTime); |
| | 224 | { |
| | 225 | int d = platformliftdata->downHeight - sbPtr->DynPtr->Position.vy; |
| | 226 | |
| | 227 | if (d < sbPtr->DynPtr->Displacement.vy) |
| | 228 | sbPtr->DynPtr->Displacement.vy = d; |
| | 229 | } |
| | 230 | } |
| | 231 | |
| | 232 | void PlatformLiftBehaviour(STRATEGYBLOCK *sbPtr) |
| | 233 | { |
| | 234 | assert(sbPtr); |
| | 235 | PLATFORMLIFT_BEHAVIOUR_BLOCK *platformliftdata = (PLATFORMLIFT_BEHAVIOUR_BLOCK *)sbPtr->dataptr; |
| | 236 | assert(platformliftdata); |
| | 237 | DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr; |
| | 238 | assert(dynPtr); |
| | 239 | |
| | 240 | switch(platformliftdata->state) |
| | 241 | { |
| | 242 | case PLBS_AtRest: |
| | 243 | { |
| | 244 | switch(AvP.PlayMode) |
| | 245 | { |
| | 246 | case NetworkHost: |
| | 247 | { |
| | 248 | if(NetPlayerAtOtherTerminal(sbPtr)) |
| | 249 | { |
| | 250 | if(platformliftdata->Enabled) |
| | 251 | ActivatePlatformLift(sbPtr); |
| | 252 | } |
| | 253 | else if(sbPtr->DisplayBlock) |
| | 254 | { |
| | 255 | /* check for activation by this player*/ |
| | 256 | if(ActivatedByPlayer(dynPtr)) |
| | 257 | { |
| | 258 | if (platformliftdata->Enabled) |
| | 259 | ActivatePlatformLift(sbPtr); |
| | 260 | } |
| | 261 | } |
| | 262 | } |
| | 263 | break; |
| | 264 | case NetworkPeer: |
| | 265 | { |
| | 266 | if(ActivatedByPlayer(dynPtr)) |
| | 267 | AddNetMsg_RequestPlatformLiftActivate(sbPtr); |
| | 268 | } |
| | 269 | break; |
| | 270 | default: |
| | 271 | { |
| | 272 | /* single player */ |
| | 273 | if(sbPtr->DisplayBlock) |
| | 274 | { |
| | 275 | /* check for activation */ |
| | 276 | if(ActivatedByPlayer(dynPtr) || PlayerIsNearOtherTerminal(sbPtr)) |
| | 277 | { |
| | 278 | if (platformliftdata->Enabled) |
| | 279 | ActivatePlatformLift(sbPtr); |
| | 280 | } |
| | 281 | } |
| | 282 | } |
| | 283 | } |
| | 284 | //printf("Platform state: at rest\n"); |
| | 285 | } |
| | 286 | break; |
| | 287 | case PLBS_Activating: |
| | 288 | { |
| | 289 | if(NetworkPeer != AvP.PlayMode) |
| | 290 | { |
| | 291 | if(platformliftdata->activationDelayTimer > 0) |
| | 292 | platformliftdata->activationDelayTimer -= NormalFrameTime; |
| | 293 | |
| | 294 | if(platformliftdata->activationDelayTimer <= 0) |
| | 295 | { |
| | 296 | //play start sound if the lift has any |
| | 297 | if(platformliftdata->start_sound) |
| | 298 | Start_Track_Sound(platformliftdata->start_sound,&sbPtr->DynPtr->Position); |
| | 299 | |
| | 300 | platformliftdata->activationDelayTimer = 0; |
| | 301 | |
| | 302 | if(dynPtr->Position.vy > ((platformliftdata->upHeight+platformliftdata->downHeight) / 2)) |
| | 303 | SendPlatformLiftUp(sbPtr); |
| | 304 | else |
| | 305 | SendPlatformLiftDown(sbPtr); |
| | 306 | } |
| | 307 | } |
| | 308 | //printf("Platform state: activating\n"); |
| | 309 | //printf("Platform timer: %d\n",platformliftdata->activationDelayTimer); |
| | 310 | } |
| | 311 | break; |
| | 312 | case PLBS_GoingUp: |
| | 313 | { |
| | 314 | if(dynPtr->Position.vy <= platformliftdata->upHeight) |
| | 315 | { |
| | 316 | /* finished */ |
| | 317 | StopPlatformLift(sbPtr); |
| | 318 | if (platformliftdata->OneUse) |
| | 319 | platformliftdata->Enabled = 0; |
| | 320 | } |
| | 321 | else |
| | 322 | { |
| | 323 | sbPtr->DynPtr->Displacement.vy = -MUL_FIXED(PLATFORMLIFT_SPEED, NormalFrameTime); |
| | 324 | |
| | 325 | { |
| | 326 | int d = platformliftdata->upHeight - sbPtr->DynPtr->Position.vy; |
| | 327 | |
| | 328 | if (d > sbPtr->DynPtr->Displacement.vy) |
| | 329 | sbPtr->DynPtr->Displacement.vy = d; |
| | 330 | } |
| | 331 | |
| | 332 | if(dynPtr->Position.vy == dynPtr->PrevPosition.vy) |
| | 333 | { |
| | 334 | if(NetworkPeer != AvP.PlayMode) |
| | 335 | SquashingSomething_for_sure(dynPtr); |
| | 336 | } |
| | 337 | } |
| | 338 | |
| | 339 | //printf("Platform state: going up\n"); |
| | 340 | } |
| | 341 | break; |
| | 342 | case PLBS_GoingDown: |
| | 343 | { |
| | 344 | if(dynPtr->Position.vy >= platformliftdata->downHeight) |
| | 345 | { |
| | 346 | /* finished */ |
| | 347 | StopPlatformLift(sbPtr); |
| | 348 | if (platformliftdata->OneUse) |
| | 349 | platformliftdata->Enabled = 0; |
| | 350 | } |
| | 351 | else |
| | 352 | { |
| | 353 | sbPtr->DynPtr->Displacement.vy = MUL_FIXED(PLATFORMLIFT_SPEED, NormalFrameTime); |
| | 354 | |
| | 355 | { |
| | 356 | int d = platformliftdata->downHeight - sbPtr->DynPtr->Position.vy; |
| | 357 | |
| | 358 | if (d < sbPtr->DynPtr->Displacement.vy) |
| | 359 | sbPtr->DynPtr->Displacement.vy = d; |
| | 360 | } |
| | 361 | |
| | 362 | if(NetworkPeer != AvP.PlayMode) |
| | 363 | SquashingSomething(dynPtr); |
| | 364 | } |
| | 365 | //printf("Platform state: going down\n"); |
| | 366 | } |
| | 367 | break; |
| | 368 | default: |
| | 369 | assert(1==0); |
| | 370 | } |
| | 371 | |
| | 372 | //update sound |
| | 373 | switch(platformliftdata->state) |
| | 374 | { |
| | 375 | case PLBS_GoingUp: |
| | 376 | case PLBS_GoingDown: |
| | 377 | { |
| | 378 | int mainSoundShouldBePlaying = 1; |
| | 379 | |
| | 380 | //the main sound should be started if there is no start sound , or the start sound has |
| | 381 | //almost finished |
| | 382 | if(platformliftdata->start_sound && platformliftdata->start_sound->playing) |
| | 383 | { |
| | 384 | Update_Track_Sound(platformliftdata->start_sound,&dynPtr->Position); |
| | 385 | mainSoundShouldBePlaying = 0; |
| | 386 | } |
| | 387 | |
| | 388 | if(platformliftdata->sound) |
| | 389 | { |
| | 390 | if(platformliftdata->sound->playing) |
| | 391 | { |
| | 392 | Update_Track_Sound(platformliftdata->sound,&dynPtr->Position); |
| | 393 | } |
| | 394 | else if(mainSoundShouldBePlaying) |
| | 395 | { |
| | 396 | Start_Track_Sound(platformliftdata->sound,&sbPtr->DynPtr->Position); |
| | 397 | } |
| | 398 | } |
| | 399 | } |
| | 400 | default: |
| | 401 | break; |
| | 402 | } |
| | 403 | |
| | 404 | //printf("Platform pos: %d / %d / %d\n",platformliftdata->upHeight,dynPtr->Position.vy,platformliftdata->downHeight); |
| | 405 | |
| | 406 | /* send state messages in net game */ |
| | 407 | if(NetworkHost == AvP.PlayMode) |
| | 408 | { |
| | 409 | if(platformliftdata->netMsgCount > 0) |
| | 410 | { |
| | 411 | /* don't send at rest messages: peers detect end of movement locally. */ |
| | 412 | if(platformliftdata->state != PLBS_AtRest) |
| | 413 | AddNetMsg_PlatformLiftState(sbPtr); |
| | 414 | |
| | 415 | platformliftdata->netMsgCount--; |
| | 416 | } |
| | 417 | } |
| | 418 | } |
| | 419 | |
| | 420 | void InitialisePlatformLift(void* bhdata, STRATEGYBLOCK *sbPtr) |
| | 421 | { |
| | 422 | PLATFORMLIFT_TOOLS_TEMPLATE *toolsData = (PLATFORMLIFT_TOOLS_TEMPLATE *)bhdata; |
| | 423 | |
| | 424 | /* create, initialise and attach a data block */ |
| | 425 | PLATFORMLIFT_BEHAVIOUR_BLOCK* platformliftdata = malloc(sizeof(PLATFORMLIFT_BEHAVIOUR_BLOCK)); |
| | 426 | |
| | 427 | if(!platformliftdata) |
| | 428 | { |
| | 429 | RemoveBehaviourStrategy(sbPtr); |
| | 430 | return; |
| | 431 | } |
| | 432 | |
| | 433 | sbPtr->dataptr = platformliftdata; |
| | 434 | platformliftdata->homePosition = toolsData->position; |
| | 435 | platformliftdata->activationDelayTimer = 0; |
| | 436 | platformliftdata->state = PLBS_AtRest; |
| | 437 | platformliftdata->netMsgCount = 0; |
| | 438 | |
| | 439 | if(toolsData->travel < 0) |
| | 440 | { |
| | 441 | platformliftdata->upHeight = platformliftdata->homePosition.vy + toolsData->travel; |
| | 442 | platformliftdata->downHeight = platformliftdata->homePosition.vy; |
| | 443 | } |
| | 444 | else |
| | 445 | { |
| | 446 | platformliftdata->upHeight = platformliftdata->homePosition.vy; |
| | 447 | platformliftdata->downHeight = platformliftdata->homePosition.vy + toolsData->travel; |
| | 448 | } |
| | 449 | |
| | 450 | assert(platformliftdata->upHeight < platformliftdata->downHeight); |
| | 451 | |
| | 452 | platformliftdata->sound = toolsData->sound; |
| | 453 | platformliftdata->start_sound = toolsData->start_sound; |
| | 454 | platformliftdata->end_sound = toolsData->end_sound; |
| | 455 | platformliftdata->Enabled = toolsData->Enabled; |
| | 456 | platformliftdata->OneUse = toolsData->OneUse; |
| | 457 | |
| | 458 | DYNAMICSBLOCK *dynPtr = AllocateDynamicsBlock(DYNAMICS_TEMPLATE_STATIC); |
| | 459 | |
| | 460 | if(NULL != dynPtr) |
| | 461 | { |
| | 462 | int i; |
| | 463 | dynPtr->GravityOn = 0; |
| | 464 | //dynPtr->StopOnCollision = 1; |
| | 465 | dynPtr->IsStatic = 0; |
| | 466 | dynPtr->OnlyCollideWithObjects = 1; |
| | 467 | dynPtr->UseDisplacement = 1; |
| | 468 | sbPtr->DynPtr = dynPtr; |
| | 469 | dynPtr->PrevPosition = dynPtr->Position = toolsData->position; |
| | 470 | dynPtr->LinVelocity.vx = dynPtr->LinVelocity.vy = dynPtr->LinVelocity.vz = 0; |
| | 471 | dynPtr->OrientEuler = toolsData->orientation; |
| | 472 | CreateEulerMatrix(&dynPtr->OrientEuler, &dynPtr->OrientMat); |
| | 473 | TransposeMatrixCH(&dynPtr->OrientMat); |
| | 474 | |
| | 475 | for(i=0; i < SB_NAME_LENGTH; i++) |
| | 476 | sbPtr->SBname[i] = toolsData->nameID[i]; |
| | 477 | |
| | 478 | sbPtr->maintainVisibility = 1; |
| | 479 | sbPtr->containingModule = ModuleFromPosition(&sbPtr->DynPtr->Position, NULL); |
| | 480 | |
| | 481 | if(NULL == sbPtr->containingModule) |
| | 482 | { |
| | 483 | //printf("no valid containing module for platforlift\n"); |
| | 484 | RemoveBehaviourStrategy(sbPtr); |
| | 485 | } |
| | 486 | } |
| | 487 | else |
| | 488 | { |
| | 489 | RemoveBehaviourStrategy(sbPtr); |
| | 490 | } |
| | 491 | } |
| | 492 | |
| | 493 | /*------------------------------Patrick 2/4/97----------------------------------- |
| | 494 | State change functions: these are alos used by network message processing fns |
| | 495 | --------------------------------------------------------------------------------*/ |
| | 496 | void ActivatePlatformLift(STRATEGYBLOCK *sbPtr) |
| | 497 | { |
| | 498 | PLATFORMLIFT_BEHAVIOUR_BLOCK *platformliftdata = (PLATFORMLIFT_BEHAVIOUR_BLOCK *)sbPtr->dataptr; |
| | 499 | assert(platformliftdata); |
| | 500 | |
| | 501 | platformliftdata->state = PLBS_Activating; |
| | 502 | platformliftdata->activationDelayTimer = PLATFORMLIFT_ACTIVATIONTIME; |
| | 503 | platformliftdata->netMsgCount = PLATFORMLIFT_NUMNETMESSAGES; |
| | 504 | } |
| | 505 | |
| | 506 | void NetworkPeerChangePlatformLiftState(STRATEGYBLOCK* sbPtr,PLATFORMLIFT_STATES new_state) |
| | 507 | { |
| | 508 | assert(sbPtr); |
| | 509 | PLATFORMLIFT_BEHAVIOUR_BLOCK *platformliftdata = (PLATFORMLIFT_BEHAVIOUR_BLOCK *)sbPtr->dataptr; |
| | 510 | assert(platformliftdata); |
| | 511 | assert(sbPtr->DynPtr); |
| | 512 | |
| | 513 | //check to see if this is a new state , and change any sound playing as necessary |
| | 514 | |
| | 515 | switch(new_state) |
| | 516 | { |
| | 517 | case PLBS_Activating: |
| | 518 | /* |
| | 519 | ignore this state change , since only the host does anything while the lift is |
| | 520 | activating , and this will prevent the lift from stopping at the ends correctly |
| | 521 | */ |
| | 522 | return; |
| | 523 | case PLBS_GoingUp: |
| | 524 | case PLBS_GoingDown: |
| | 525 | switch(platformliftdata->state) |
| | 526 | { |
| | 527 | case PLBS_GoingUp: |
| | 528 | case PLBS_GoingDown: |
| | 529 | break; |
| | 530 | default: |
| | 531 | { |
| | 532 | //platform lift has started moving |
| | 533 | if(platformliftdata->start_sound) |
| | 534 | Start_Track_Sound(platformliftdata->start_sound,&sbPtr->DynPtr->Position); |
| | 535 | } |
| | 536 | } |
| | 537 | default: |
| | 538 | break; |
| | 539 | } |
| | 540 | |
| | 541 | platformliftdata->state = new_state; |
| | 542 | } |
| | 543 | |
| | 544 | /*--------------------** |
| | 545 | ** Loading and Saving ** |
| | 546 | **--------------------*/ |
| | 547 | #include "savegame.h" |
| | 548 | typedef struct platform_lift_save_block |
| | 549 | { |
| | 550 | SAVE_BLOCK_STRATEGY_HEADER header; |
| | 551 | |
| | 552 | DYNAMICSBLOCK dynamics; |
| | 553 | |
| | 554 | int activationDelayTimer; |
| | 555 | PLATFORMLIFT_STATES state; |
| | 556 | |
| | 557 | int Enabled; |
| | 558 | int OneUse; //if set ,lift becomes disabled after changing position once |
| | 559 | |
| | 560 | } PLATFORM_LIFT_SAVE_BLOCK; |
| | 561 | |
| | 562 | //defines for load/save macros |
| | 563 | #define SAVELOAD_BLOCK block |
| | 564 | #define SAVELOAD_BEHAV platformliftdata |
| | 565 | |
| | 566 | void LoadStrategy_PlatformLift(SAVE_BLOCK_STRATEGY_HEADER* header) |
| | 567 | { |
| | 568 | PLATFORM_LIFT_SAVE_BLOCK* block = (PLATFORM_LIFT_SAVE_BLOCK*) header; |
| | 569 | |
| | 570 | //check the size of the save block |
| | 571 | if(header->size != sizeof(*block)) |
| | 572 | return; |
| | 573 | |
| | 574 | //find the existing strategy block |
| | 575 | STRATEGYBLOCK* sbPtr = FindSBWithName(header->SBname); |
| | 576 | |
| | 577 | if(!sbPtr) |
| | 578 | return; |
| | 579 | |
| | 580 | //make sure the strategy found is of the right type |
| | 581 | if(sbPtr->type != I_BehaviourPlatform) |
| | 582 | return; |
| | 583 | |
| | 584 | PLATFORMLIFT_BEHAVIOUR_BLOCK *platformliftdata = (PLATFORMLIFT_BEHAVIOUR_BLOCK*)sbPtr->dataptr; |
| | 585 | |
| | 586 | //start copying stuff |
| | 587 | |
| | 588 | COPYELEMENT_LOAD(activationDelayTimer) |
| | 589 | COPYELEMENT_LOAD(state) |
| | 590 | COPYELEMENT_LOAD(Enabled) |
| | 591 | COPYELEMENT_LOAD(OneUse) |
| | 592 | |
| | 593 | *sbPtr->DynPtr = block->dynamics; |
| | 594 | } |
| | 595 | |
| | 596 | void SaveStrategy_PlatformLift(STRATEGYBLOCK* sbPtr) |
| | 597 | { |
| | 598 | PLATFORM_LIFT_SAVE_BLOCK *block; |
| | 599 | PLATFORMLIFT_BEHAVIOUR_BLOCK *platformliftdata = (PLATFORMLIFT_BEHAVIOUR_BLOCK*)sbPtr->dataptr; |
| | 600 | |
| | 601 | GET_STRATEGY_SAVE_BLOCK(block,sbPtr); |
| | 602 | |
| | 603 | COPYELEMENT_SAVE(activationDelayTimer) |
| | 604 | COPYELEMENT_SAVE(state) |
| | 605 | COPYELEMENT_SAVE(Enabled) |
| | 606 | COPYELEMENT_SAVE(OneUse) |
| | 607 | |
| | 608 | block->dynamics = *sbPtr->DynPtr; |
| | 609 | block->dynamics.CollisionReportPtr = 0; |
| | 610 | } |