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