| | 1 | #include "system.h" |
| | 2 | #include "stratdef.h" |
| | 3 | #include "npc_alien.h" |
| | 4 | #include "npc_marine.h" |
| | 5 | #include "generator.h" |
| | 6 | #include "pheromon.h" |
| | 7 | #include "bh_far.h" |
| | 8 | #include "pldghost.h" |
| | 9 | #include <assert.h> |
| | 10 | #include <stdlib.h> |
| | 11 | #include <stdio.h> |
| | 12 | |
| | 13 | HIVE_DATA NPCHive; |
| | 14 | |
| | 15 | //generator details that are initialised with in setup_generators in the rif load |
| | 16 | |
| | 17 | static struct |
| | 18 | { |
| | 19 | int maxGeneratorNPCs; |
| | 20 | int generatorNPCsPerMinute; |
| | 21 | int deltaGeneratorNPCsPerMinute; |
| | 22 | int hiveStateBaseTime; |
| | 23 | |
| | 24 | } LoadedHiveData; |
| | 25 | |
| | 26 | int NearAliens; |
| | 27 | int FarAliens; |
| | 28 | int ShowHiveState = 0; |
| | 29 | |
| | 30 | void InitGenerator(void *bhdata, STRATEGYBLOCK *sbPtr) |
| | 31 | { |
| | 32 | GENERATOR_BLOCK *genBlock = malloc(sizeof(GENERATOR_BLOCK)); |
| | 33 | |
| | 34 | if (genBlock) |
| | 35 | { |
| | 36 | GENERATOR_BLOCK *toolsData = (GENERATOR_BLOCK *)bhdata; |
| | 37 | *genBlock = *toolsData; |
| | 38 | genBlock->Timer = 0; |
| | 39 | genBlock->RateIncreaseTimer = 60*ONE_FIXED; |
| | 40 | |
| | 41 | if(genBlock->GenerationRate <= 0) |
| | 42 | genBlock->GenerationRate = 1; |
| | 43 | |
| | 44 | sbPtr->dataptr = (void *)genBlock; |
| | 45 | |
| | 46 | sbPtr->containingModule = ModuleFromPosition(&genBlock->Position, NULL); |
| | 47 | assert(sbPtr->containingModule); |
| | 48 | NPCHive.numGenerators++; |
| | 49 | /* init generator times to something quite small... |
| | 50 | so that we get some npcs in the env quickly */ |
| | 51 | genBlock->Timer = ONE_FIXED; |
| | 52 | |
| | 53 | //work out which types of alien can be generated on this level (for multiplayer) |
| | 54 | |
| | 55 | if(genBlock->Alien_Wt) |
| | 56 | NPCHive.AliensCanBeGenerated = 1; |
| | 57 | |
| | 58 | if(genBlock->PredAlien_Wt) |
| | 59 | NPCHive.PredAliensCanBeGenerated = 1; |
| | 60 | |
| | 61 | if(genBlock->Praetorian_Wt) |
| | 62 | NPCHive.PraetoriansCanBeGenerated = 1; |
| | 63 | } |
| | 64 | else |
| | 65 | { |
| | 66 | RemoveBehaviourStrategy(sbPtr); |
| | 67 | } |
| | 68 | } |
| | 69 | |
| | 70 | static int NumNPCsFromThisGenerator(STRATEGYBLOCK* gen_sbptr) |
| | 71 | { |
| | 72 | int sbIndex = 0; |
| | 73 | int numOfNPCs = 0; |
| | 74 | |
| | 75 | while(sbIndex < NumActiveStBlocks) |
| | 76 | { |
| | 77 | STRATEGYBLOCK *sbPtr = ActiveStBlockList[sbIndex++]; |
| | 78 | |
| | 79 | switch(sbPtr->type) |
| | 80 | { |
| | 81 | case I_BehaviourAlien: |
| | 82 | { |
| | 83 | ALIEN_STATUS_BLOCK* status_block = (ALIEN_STATUS_BLOCK*)sbPtr->dataptr; |
| | 84 | |
| | 85 | if(status_block->generator_sbptr == gen_sbptr) |
| | 86 | numOfNPCs++; |
| | 87 | } |
| | 88 | break; |
| | 89 | case I_BehaviourMarine: |
| | 90 | { |
| | 91 | MARINE_STATUS_BLOCK* status_block = (MARINE_STATUS_BLOCK*)sbPtr->dataptr; |
| | 92 | |
| | 93 | if(status_block->generator_sbptr == gen_sbptr) |
| | 94 | numOfNPCs++; |
| | 95 | } |
| | 96 | default: |
| | 97 | break; |
| | 98 | } |
| | 99 | } |
| | 100 | |
| | 101 | return numOfNPCs; |
| | 102 | } |
| | 103 | |
| | 104 | static int NumGeneratorNPCsInEnv() |
| | 105 | { |
| | 106 | int sbIndex = 0; |
| | 107 | int numOfNPCs = 0; |
| | 108 | |
| | 109 | while(sbIndex < NumActiveStBlocks) |
| | 110 | { |
| | 111 | STRATEGYBLOCK *sbPtr = ActiveStBlockList[sbIndex++]; |
| | 112 | |
| | 113 | switch(sbPtr->type) |
| | 114 | { |
| | 115 | case I_BehaviourAlien: |
| | 116 | case I_BehaviourMarine: |
| | 117 | { |
| | 118 | //All placed bad guys will have the last character of the sbname as 0 |
| | 119 | //generated badguys shoud have a non-zero last character. |
| | 120 | |
| | 121 | if(sbPtr->SBname[SB_NAME_LENGTH-1]) |
| | 122 | numOfNPCs++; |
| | 123 | } |
| | 124 | default: |
| | 125 | break; |
| | 126 | } |
| | 127 | } |
| | 128 | |
| | 129 | return numOfNPCs; |
| | 130 | } |
| | 131 | |
| | 132 | void GeneratorBehaviour(STRATEGYBLOCK *sbPtr) |
| | 133 | { |
| | 134 | GENERATOR_BLOCK *genBlock = (GENERATOR_BLOCK *)sbPtr->dataptr; |
| | 135 | |
| | 136 | /* don't do this for a net game */ |
| | 137 | |
| | 138 | switch(AvP.PlayMode) |
| | 139 | { |
| | 140 | case NetworkHost: |
| | 141 | case NetworkPeer: |
| | 142 | return; |
| | 143 | default: |
| | 144 | break; |
| | 145 | } |
| | 146 | |
| | 147 | /* if our number of generators/minute is not > 0, the generator system is |
| | 148 | effectively turned off... */ |
| | 149 | |
| | 150 | if(!(NPCHive.generatorNPCsPerMinute > 0) || !genBlock->Active) |
| | 151 | return; |
| | 152 | |
| | 153 | /* if generator is visible, do not create a new NPC */ |
| | 154 | if(ModuleCurrVisArray[sbPtr->containingModule->m_index]) |
| | 155 | return; |
| | 156 | |
| | 157 | /*if generator is using its own rate values , check for rate increase */ |
| | 158 | |
| | 159 | if(genBlock->use_own_rate_values) |
| | 160 | { |
| | 161 | genBlock->RateIncreaseTimer -= NormalFrameTime; |
| | 162 | |
| | 163 | if(genBlock->RateIncreaseTimer < 0) |
| | 164 | { |
| | 165 | genBlock->RateIncreaseTimer = ONE_FIXED*60; |
| | 166 | genBlock->GenerationRate += genBlock->GenerationRateIncrease; |
| | 167 | genBlock->GenerationRate = min(genBlock->GenerationRate, GENSPERMINUTE_MAX*100); |
| | 168 | genBlock->GenerationRate = max(genBlock->GenerationRate, GENSPERMINUTE_MIN*100); |
| | 169 | } |
| | 170 | } |
| | 171 | |
| | 172 | /* if there are too many npcs in the env, do not create a new one */ |
| | 173 | if(genBlock->use_own_max_npc) |
| | 174 | { |
| | 175 | //check npcs from this generator |
| | 176 | if (NumNPCsFromThisGenerator(sbPtr) > genBlock->MaxGenNPCs) |
| | 177 | return; |
| | 178 | } |
| | 179 | else if (NumGeneratorNPCsInEnv() > NPCHive.maxGeneratorNPCs) |
| | 180 | { |
| | 181 | return; |
| | 182 | } |
| | 183 | |
| | 184 | genBlock->Timer -= NormalFrameTime; |
| | 185 | |
| | 186 | if(genBlock->Timer > 0) |
| | 187 | return; |
| | 188 | |
| | 189 | if(genBlock->use_own_rate_values) |
| | 190 | { |
| | 191 | assert(genBlock->GenerationRate); |
| | 192 | genBlock->Timer = (60 * ONE_FIXED *100)/genBlock->GenerationRate; |
| | 193 | } |
| | 194 | else |
| | 195 | { |
| | 196 | /* if we get here, there must be at least one generator, and some kind of generator rate */ |
| | 197 | assert(NPCHive.numGenerators > 0); |
| | 198 | assert(NPCHive.generatorNPCsPerMinute > 0); |
| | 199 | |
| | 200 | /* set the timer */ |
| | 201 | genBlock->Timer = ((60 * ONE_FIXED) / NPCHive.generatorNPCsPerMinute) * NPCHive.numGenerators; |
| | 202 | } |
| | 203 | |
| | 204 | /* randomise +- an eighth */ |
| | 205 | genBlock->Timer = ((genBlock->Timer * 7) / 8) + (FastRandom() % (genBlock->Timer / 4)); |
| | 206 | |
| | 207 | if(genBlock->Timer > GENERATORTIME_MAX) |
| | 208 | genBlock->Timer = GENERATORTIME_MAX; |
| | 209 | else if(genBlock->Timer < GENERATORTIME_MIN) |
| | 210 | genBlock->Timer = GENERATORTIME_MIN; |
| | 211 | |
| | 212 | /* at this point, we have reset the timer, and are set to |
| | 213 | generate a new npc: however, some things can still |
| | 214 | prevent this: eg if the module is visible, or there are too |
| | 215 | many generator npcs in the environment */ |
| | 216 | |
| | 217 | /*If in a network game , must also make sure the module isn't visible by other players*/ |
| | 218 | |
| | 219 | /* |
| | 220 | if(AvP.Network != I_No_Network) |
| | 221 | { |
| | 222 | // go through the strategy blocks looking for players |
| | 223 | int sbIndex = 0; |
| | 224 | |
| | 225 | for(; sbIndex < NumActiveStBlocks; sbIndex++) |
| | 226 | { |
| | 227 | STRATEGYBLOCK *playerSbPtr = ActiveStBlockList[sbIndex]; |
| | 228 | |
| | 229 | if(I_BehaviourNetGhost == playerSbPtr->type) |
| | 230 | { |
| | 231 | NETGHOSTDATABLOCK *ghostData = (NETGHOSTDATABLOCK *)playerSbPtr->dataptr; |
| | 232 | |
| | 233 | switch(ghostData->type) |
| | 234 | { |
| | 235 | case I_BehaviourAlienPlayer: |
| | 236 | case I_BehaviourMarinePlayer: |
| | 237 | case I_BehaviourPredatorPlayer: |
| | 238 | { |
| | 239 | //this is another player |
| | 240 | if(playerSbPtr->containingModule && IsModuleVisibleFromModule(playerSbPtr->containingModule, sbPtr->containingModule)) |
| | 241 | return; //Another player can see this generator's module |
| | 242 | } |
| | 243 | default: |
| | 244 | break; |
| | 245 | } |
| | 246 | } |
| | 247 | } |
| | 248 | } |
| | 249 | */ |
| | 250 | |
| | 251 | /* ok... create an NPC, then */ |
| | 252 | assert(genBlock->WeightingTotal); |
| | 253 | |
| | 254 | { |
| | 255 | int random = FastRandom() % genBlock->WeightingTotal; |
| | 256 | |
| | 257 | if(random < 0) |
| | 258 | random = -random; |
| | 259 | |
| | 260 | if(random < genBlock->Alien_Wt) |
| | 261 | { |
| | 262 | CreateAlienDynamic(sbPtr, Standard); |
| | 263 | return; |
| | 264 | } |
| | 265 | |
| | 266 | random -= genBlock->Alien_Wt; |
| | 267 | |
| | 268 | if(random < genBlock->PredAlien_Wt) |
| | 269 | { |
| | 270 | CreateAlienDynamic(sbPtr, Predalien); |
| | 271 | return; |
| | 272 | } |
| | 273 | |
| | 274 | random -= genBlock->PredAlien_Wt; |
| | 275 | |
| | 276 | if(random < genBlock->Praetorian_Wt) |
| | 277 | { |
| | 278 | CreateAlienDynamic(sbPtr, Praetorian); |
| | 279 | return; |
| | 280 | } |
| | 281 | |
| | 282 | random -= genBlock->Praetorian_Wt; |
| | 283 | |
| | 284 | if(random < genBlock->PulseMarine_Wt) |
| | 285 | { |
| | 286 | CreateMarineDynamic(sbPtr, MNPCW_PulseRifle); |
| | 287 | return; |
| | 288 | } |
| | 289 | |
| | 290 | random -= genBlock->PulseMarine_Wt; |
| | 291 | |
| | 292 | if(random < genBlock->PistolMarine_Wt) |
| | 293 | { |
| | 294 | CreateMarineDynamic(sbPtr, MNPCW_PistolMarine); |
| | 295 | return; |
| | 296 | } |
| | 297 | |
| | 298 | random -= genBlock->PistolMarine_Wt; |
| | 299 | |
| | 300 | if(random < genBlock->FlameMarine_Wt) |
| | 301 | { |
| | 302 | CreateMarineDynamic(sbPtr, MNPCW_Flamethrower); |
| | 303 | return; |
| | 304 | } |
| | 305 | |
| | 306 | random -= genBlock->FlameMarine_Wt; |
| | 307 | |
| | 308 | if(random < genBlock->SmartMarine_Wt) |
| | 309 | { |
| | 310 | CreateMarineDynamic(sbPtr, MNPCW_Smartgun); |
| | 311 | return; |
| | 312 | } |
| | 313 | |
| | 314 | random -= genBlock->SmartMarine_Wt; |
| | 315 | |
| | 316 | if(random < genBlock->SadarMarine_Wt) |
| | 317 | { |
| | 318 | CreateMarineDynamic(sbPtr, MNPCW_SADAR); |
| | 319 | return; |
| | 320 | } |
| | 321 | |
| | 322 | random -= genBlock->SadarMarine_Wt; |
| | 323 | |
| | 324 | if(random < genBlock->GrenadeMarine_Wt) |
| | 325 | { |
| | 326 | CreateMarineDynamic(sbPtr, MNPCW_GrenadeLauncher); |
| | 327 | return; |
| | 328 | } |
| | 329 | |
| | 330 | random -= genBlock->GrenadeMarine_Wt; |
| | 331 | |
| | 332 | if(random < genBlock->MinigunMarine_Wt) |
| | 333 | { |
| | 334 | CreateMarineDynamic(sbPtr, MNPCW_Minigun); |
| | 335 | return; |
| | 336 | } |
| | 337 | |
| | 338 | random -= genBlock->MinigunMarine_Wt; |
| | 339 | |
| | 340 | if(random < genBlock->ShotgunCiv_Wt) |
| | 341 | { |
| | 342 | CreateMarineDynamic(sbPtr, MNPCW_CivilianShotgun); |
| | 343 | return; |
| | 344 | } |
| | 345 | |
| | 346 | random -= genBlock->ShotgunCiv_Wt; |
| | 347 | |
| | 348 | if(random < genBlock->PistolCiv_Wt) |
| | 349 | { |
| | 350 | CreateMarineDynamic(sbPtr, MNPCW_CivilianPistol); |
| | 351 | return; |
| | 352 | } |
| | 353 | |
| | 354 | random -= genBlock->PistolCiv_Wt; |
| | 355 | |
| | 356 | if(random < genBlock->FlameCiv_Wt) |
| | 357 | { |
| | 358 | CreateMarineDynamic(sbPtr, MNPCW_CivilianFlamer); |
| | 359 | return; |
| | 360 | } |
| | 361 | |
| | 362 | random -= genBlock->FlameCiv_Wt; |
| | 363 | |
| | 364 | if(random < genBlock->UnarmedCiv_Wt) |
| | 365 | { |
| | 366 | CreateMarineDynamic(sbPtr, MNPCW_MUnarmed); |
| | 367 | return; |
| | 368 | } |
| | 369 | |
| | 370 | random -= genBlock->UnarmedCiv_Wt; |
| | 371 | |
| | 372 | if(random < genBlock->MolotovCiv_Wt) |
| | 373 | { |
| | 374 | CreateMarineDynamic(sbPtr, MNPCW_MMolotov); |
| | 375 | return; |
| | 376 | } |
| | 377 | |
| | 378 | random -= genBlock->MolotovCiv_Wt; |
| | 379 | |
| | 380 | assert(0=="Failed to select generator badguy"); |
| | 381 | } |
| | 382 | } |
| | 383 | |
| | 384 | static void ResetHiveStateTime() |
| | 385 | { |
| | 386 | /* set the timer, +- an eighth */ |
| | 387 | int baseTime = LoadedHiveData.hiveStateBaseTime; |
| | 388 | NPCHive.hiveStateTimer = ((baseTime * 7)/8) + (FastRandom() % (baseTime / 4)); |
| | 389 | } |
| | 390 | |
| | 391 | void DeActivateHive() |
| | 392 | { |
| | 393 | NPCHive.genRateTimer = 0; |
| | 394 | NPCHive.maxGeneratorNPCs = 0; |
| | 395 | NPCHive.generatorNPCsPerMinute = 0; |
| | 396 | NPCHive.deltaGeneratorNPCsPerMinute = 0; |
| | 397 | } |
| | 398 | |
| | 399 | void ActivateHive() |
| | 400 | { |
| | 401 | /* Placed in for Jules's level... CDF 1/12/97, Deadline day! */ |
| | 402 | |
| | 403 | NPCHive.maxGeneratorNPCs = LoadedHiveData.maxGeneratorNPCs; |
| | 404 | NPCHive.generatorNPCsPerMinute = LoadedHiveData.generatorNPCsPerMinute; |
| | 405 | NPCHive.deltaGeneratorNPCsPerMinute = LoadedHiveData.deltaGeneratorNPCsPerMinute; |
| | 406 | NPCHive.genRateTimer = 60 * ONE_FIXED; |
| | 407 | |
| | 408 | /* validate these parameters */ |
| | 409 | if(NPCHive.maxGeneratorNPCs > MAXGENNPCS_MAX) |
| | 410 | NPCHive.maxGeneratorNPCs = MAXGENNPCS_MAX; |
| | 411 | |
| | 412 | if(NPCHive.maxGeneratorNPCs < MAXGENNPCS_MIN) |
| | 413 | NPCHive.maxGeneratorNPCs = MAXGENNPCS_MIN; |
| | 414 | |
| | 415 | if(NPCHive.generatorNPCsPerMinute > GENSPERMINUTE_MAX) |
| | 416 | NPCHive.generatorNPCsPerMinute = GENSPERMINUTE_MAX; |
| | 417 | |
| | 418 | if(NPCHive.generatorNPCsPerMinute < GENSPERMINUTE_MIN) |
| | 419 | NPCHive.generatorNPCsPerMinute = GENSPERMINUTE_MIN; |
| | 420 | |
| | 421 | if(NPCHive.deltaGeneratorNPCsPerMinute > INCREASEGENSPERMINUTE_MAX) |
| | 422 | NPCHive.deltaGeneratorNPCsPerMinute = INCREASEGENSPERMINUTE_MAX; |
| | 423 | |
| | 424 | if(NPCHive.deltaGeneratorNPCsPerMinute < INCREASEGENSPERMINUTE_MIN) |
| | 425 | NPCHive.deltaGeneratorNPCsPerMinute = INCREASEGENSPERMINUTE_MIN; |
| | 426 | |
| | 427 | ResetHiveStateTime(); |
| | 428 | } |
| | 429 | |
| | 430 | void InitHive() |
| | 431 | { |
| | 432 | NPCHive.currentState = HS_Attack; |
| | 433 | NPCHive.numGenerators = 0; |
| | 434 | NPCHive.hiveStateTimer = 0; |
| | 435 | NPCHive.genRateTimer = 0; |
| | 436 | NPCHive.maxGeneratorNPCs = 0; |
| | 437 | NPCHive.generatorNPCsPerMinute = 0; |
| | 438 | NPCHive.deltaGeneratorNPCsPerMinute = 0; |
| | 439 | NPCHive.AliensCanBeGenerated = 0; |
| | 440 | NPCHive.PredAliensCanBeGenerated = 0; |
| | 441 | NPCHive.PraetoriansCanBeGenerated = 0; |
| | 442 | NearAliens = FarAliens = 0; |
| | 443 | } |
| | 444 | |
| | 445 | /*---------------------Patrick 21/1/97------------------------ |
| | 446 | Do hive management: |
| | 447 | generator time is decreased at the start of an attack phase |
| | 448 | ------------------------------------------------------------*/ |
| | 449 | void DoHive() |
| | 450 | { |
| | 451 | NPCHive.hiveStateTimer -= NormalFrameTime; |
| | 452 | |
| | 453 | if(NPCHive.hiveStateTimer <= 0) |
| | 454 | { |
| | 455 | NPCHive.currentState = (NPCHive.currentState == HS_Attack) ? HS_Regroup : HS_Attack; |
| | 456 | ResetHiveStateTime(); |
| | 457 | } |
| | 458 | |
| | 459 | NPCHive.genRateTimer -= NormalFrameTime; |
| | 460 | |
| | 461 | if(NPCHive.genRateTimer <= 0) |
| | 462 | { |
| | 463 | /* increase frequency */ |
| | 464 | NPCHive.generatorNPCsPerMinute += NPCHive.deltaGeneratorNPCsPerMinute; |
| | 465 | |
| | 466 | if(NPCHive.generatorNPCsPerMinute > GENSPERMINUTE_MAX) |
| | 467 | NPCHive.generatorNPCsPerMinute = GENSPERMINUTE_MAX; |
| | 468 | else if(NPCHive.generatorNPCsPerMinute < GENSPERMINUTE_MIN) |
| | 469 | NPCHive.generatorNPCsPerMinute = GENSPERMINUTE_MIN; |
| | 470 | |
| | 471 | NPCHive.genRateTimer = ONE_FIXED * 60; |
| | 472 | } |
| | 473 | |
| | 474 | if (ShowHiveState) |
| | 475 | { |
| | 476 | if(NPCHive.currentState == HS_Attack) |
| | 477 | printf("Hive Attacking %d...\n", NPCHive.hiveStateTimer); |
| | 478 | else |
| | 479 | printf("Hive Retreating %d...\n", NPCHive.hiveStateTimer); |
| | 480 | |
| | 481 | printf("Near Aliens = %d\nFar Aliens = %d\n", NearAliens,FarAliens); |
| | 482 | |
| | 483 | NearAliens = FarAliens = 0; |
| | 484 | } |
| | 485 | } |
| | 486 | |
| | 487 | int NumGeneratorNPCsVisible() |
| | 488 | { |
| | 489 | int sbIndex = 0; |
| | 490 | int numOfVisNPCs = 0; |
| | 491 | |
| | 492 | while(sbIndex < NumActiveStBlocks) |
| | 493 | { |
| | 494 | STRATEGYBLOCK *sbPtr = ActiveStBlockList[sbIndex++]; |
| | 495 | |
| | 496 | switch(sbPtr->type) |
| | 497 | { |
| | 498 | case I_BehaviourAlien: |
| | 499 | case I_BehaviourMarine: |
| | 500 | if(sbPtr->DisplayBlock) |
| | 501 | numOfVisNPCs++; |
| | 502 | default: |
| | 503 | break; |
| | 504 | } |
| | 505 | } |
| | 506 | |
| | 507 | return numOfVisNPCs; |
| | 508 | } |
| | 509 | |
| | 510 | void ForceAGenerator() |
| | 511 | { |
| | 512 | int sbIndex = 0; |
| | 513 | |
| | 514 | while(sbIndex < NumActiveStBlocks) |
| | 515 | { |
| | 516 | STRATEGYBLOCK *sbPtr = ActiveStBlockList[sbIndex++]; |
| | 517 | |
| | 518 | if(sbPtr->type == I_BehaviourGenerator) |
| | 519 | { |
| | 520 | GENERATOR_BLOCK *genBlock = (GENERATOR_BLOCK *)sbPtr->dataptr; |
| | 521 | |
| | 522 | if(genBlock->Timer > 0) |
| | 523 | { |
| | 524 | /* found a generator with timer > 0, so set it to zero and return */ |
| | 525 | genBlock->Timer = 0; |
| | 526 | return; |
| | 527 | } |
| | 528 | } |
| | 529 | } |
| | 530 | } |
| | 531 | |
| | 532 | void SetHiveParamaters(int max,int genpermin,int deltagenpermin,int time) |
| | 533 | { |
| | 534 | LoadedHiveData.maxGeneratorNPCs = max; |
| | 535 | LoadedHiveData.generatorNPCsPerMinute = genpermin; |
| | 536 | LoadedHiveData.deltaGeneratorNPCsPerMinute = deltagenpermin; |
| | 537 | LoadedHiveData.hiveStateBaseTime = time; |
| | 538 | } |
| | 539 | |
| | 540 | /*--------------------** |
| | 541 | ** Loading and Saving ** |
| | 542 | **--------------------*/ |
| | 543 | #include "savegame.h" |
| | 544 | |
| | 545 | typedef struct generator_save_block |
| | 546 | { |
| | 547 | SAVE_BLOCK_STRATEGY_HEADER header; |
| | 548 | |
| | 549 | int Timer; |
| | 550 | int Active; |
| | 551 | |
| | 552 | int GenerationRate; //scaled up by 100 |
| | 553 | int RateIncreaseTimer; |
| | 554 | |
| | 555 | } GENERATOR_SAVE_BLOCK; |
| | 556 | |
| | 557 | //defines for load/save macros |
| | 558 | #define SAVELOAD_BLOCK block |
| | 559 | #define SAVELOAD_BEHAV genBlock |
| | 560 | |
| | 561 | void LoadStrategy_Generator(SAVE_BLOCK_STRATEGY_HEADER* header) |
| | 562 | { |
| | 563 | GENERATOR_SAVE_BLOCK* block = (GENERATOR_SAVE_BLOCK*) header; |
| | 564 | |
| | 565 | //check the size of the save block |
| | 566 | if(header->size == sizeof(*block)) |
| | 567 | { |
| | 568 | STRATEGYBLOCK* sbPtr = FindSBWithName(header->SBname); |
| | 569 | |
| | 570 | if(NULL != sbPtr) |
| | 571 | { |
| | 572 | if(I_BehaviourGenerator == sbPtr->type) |
| | 573 | { |
| | 574 | GENERATOR_BLOCK *genBlock = (GENERATOR_BLOCK*)sbPtr->dataptr; |
| | 575 | |
| | 576 | COPYELEMENT_LOAD(Timer) |
| | 577 | COPYELEMENT_LOAD(Active) |
| | 578 | COPYELEMENT_LOAD(GenerationRate) |
| | 579 | COPYELEMENT_LOAD(RateIncreaseTimer) |
| | 580 | } |
| | 581 | } |
| | 582 | } |
| | 583 | } |
| | 584 | |
| | 585 | void SaveStrategy_Generator(STRATEGYBLOCK* sbPtr) |
| | 586 | { |
| | 587 | GENERATOR_SAVE_BLOCK *block; |
| | 588 | GENERATOR_BLOCK *genBlock = (GENERATOR_BLOCK*)sbPtr->dataptr; |
| | 589 | |
| | 590 | GET_STRATEGY_SAVE_BLOCK(block,sbPtr); |
| | 591 | |
| | 592 | //start copying stuff |
| | 593 | |
| | 594 | COPYELEMENT_SAVE(Timer) |
| | 595 | COPYELEMENT_SAVE(Active) |
| | 596 | COPYELEMENT_SAVE(GenerationRate) |
| | 597 | COPYELEMENT_SAVE(RateIncreaseTimer) |
| | 598 | } |
| | 599 | |
| | 600 | typedef struct hive_save_block |
| | 601 | { |
| | 602 | SAVE_BLOCK_HEADER header; |
| | 603 | |
| | 604 | HIVE_STATE currentState; |
| | 605 | int hiveStateTimer; |
| | 606 | int genRateTimer; |
| | 607 | int generatorNPCsPerMinute; |
| | 608 | |
| | 609 | } HIVE_SAVE_BLOCK; |
| | 610 | |
| | 611 | #undef SAVELOAD_BLOCK |
| | 612 | #undef SAVELOAD_BEHAV |
| | 613 | //defines for load/save macros |
| | 614 | #define SAVELOAD_BLOCK block |
| | 615 | #define SAVELOAD_BEHAV (&NPCHive) |
| | 616 | |
| | 617 | void LoadHiveSettings(SAVE_BLOCK_HEADER* header) |
| | 618 | { |
| | 619 | HIVE_SAVE_BLOCK* block = (HIVE_SAVE_BLOCK*) header; |
| | 620 | |
| | 621 | if(header->size == sizeof(*block)) |
| | 622 | { |
| | 623 | COPYELEMENT_LOAD(currentState) |
| | 624 | COPYELEMENT_LOAD(hiveStateTimer) |
| | 625 | COPYELEMENT_LOAD(genRateTimer) |
| | 626 | COPYELEMENT_LOAD(generatorNPCsPerMinute) |
| | 627 | } |
| | 628 | } |
| | 629 | |
| | 630 | void SaveHiveSettings() |
| | 631 | { |
| | 632 | HIVE_SAVE_BLOCK* block; |
| | 633 | GET_SAVE_BLOCK_POINTER(block); |
| | 634 | |
| | 635 | //fill in the header |
| | 636 | block->header.type = SaveBlock_GlobalHive; |
| | 637 | block->header.size = sizeof(*block); |
| | 638 | |
| | 639 | COPYELEMENT_SAVE(currentState) |
| | 640 | COPYELEMENT_SAVE(hiveStateTimer) |
| | 641 | COPYELEMENT_SAVE(genRateTimer) |
| | 642 | COPYELEMENT_SAVE(generatorNPCsPerMinute) |
| | 643 | } |