Last active
April 3, 2026 04:26
-
-
Save LeftoverAtoms/835a0e5aca5402f8fa24fe2812a6c5c9 to your computer and use it in GitHub Desktop.
BO4 Zombie Health for WaW/BO1/BO2 Zombies
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| ┌─────────────────────────────────────────────────────────┐ | |
| │ BO4 Health Cap for WaW/BO1/BO2 Zombies │ | |
| └─────────────────────────────────────────────────────────┘ | |
| ┌─────────────────────────────────────────────────────────┐ | |
| │ INSTALLATION INSTRUCTIONS │ | |
| ├─────────────────────────────────────────────────────────┤ | |
| │ https://plutonium.pw/docs/modding/loading-mods/ │ | |
| └─────────────────────────────────────────────────────────┘ | |
| ┌─────────────────────────────────────────────────────────┐ | |
| │ WHAT DOES THIS SCRIPT DO? │ | |
| ├─────────────────────────────────────────────────────────┤ | |
| │ Replaces standard zombie health with the one from BO4 │ | |
| │ │ | |
| │ Max health for standard zombies is 11,272 at round 35 │ | |
| │ │ | |
| │ Hellhounds, Pentagon Thief, George Romero, Avogadro, │ | |
| │ Jumping Jacks, Warden, Witches, and Panzer Soldat │ | |
| │ remain unchanged. │ | |
| │ │ | |
| │ Maximum health for special zombies by player count: │ | |
| │ Astronaut: 180,352 \ 135,264 \ 90,176 \ 45,088 │ | |
| │ Napalm: 180,352 \ 135,264 \ 90,176 \ 45,088 │ | |
| │ Sonic: 112,720 \ 84,540 \ 56,360 \ 28,180 │ | |
| └─────────────────────────────────────────────────────────┘ | |
| ┌─────────────────────────────────────────────────────────┐ | |
| │ CHANGE NOTES │ | |
| ├─────────────────────────────────────────────────────────┤ | |
| │ [v1.1.5] │ | |
| │ - Added WaW support. │ | |
| │ [v1.1.4] │ | |
| │ - Reimplemented campaign difficulty health modifiers. │ | |
| │ - Fixed undefined variables. │ | |
| │ [v1.1.3] │ | |
| │ - Removed dependencies for easier installation. │ | |
| │ - Hide logs behind developer mode. │ | |
| │ [v1.1.2] │ | |
| │ - Fixed BO1 error due to BO2 include. │ | |
| │ [v1.1.1] │ | |
| │ - Incorrect value fix. │ | |
| │ [v1.1.0] │ | |
| │ - Added BO2 support. │ | |
| │ - Removed campaign difficulty health modifiers. │ | |
| └─────────────────────────────────────────────────────────┘ | |
| ┌─────────────────────────────────────────────────────────┐ | |
| │ CREDITS │ | |
| ├─────────────────────────────────────────────────────────┤ | |
| │ - [LeftoverAtoms] creator. │ | |
| │ - [All0utWar] motivation / just a chill guy. │ | |
| │ - [ate47] atian-cod-tools were used to extract scripts. │ | |
| └─────────────────────────────────────────────────────────┘ | |
| */ | |
| main() | |
| { | |
| level thread zombie_health_monitor(); | |
| } | |
| zombie_health_monitor() | |
| { | |
| // These variables must be defined. | |
| while ( !IsDefined( level.gameSkill ) || !IsDefined( level.round_number ) || !IsDefined( level.zombie_health ) ) | |
| { | |
| wait_network_frame(); | |
| } | |
| while ( true ) | |
| { | |
| zombie_health_changed(); | |
| // Reduce unnecessary updates. | |
| while ( level.zombie_health_old == level.zombie_health ) | |
| { | |
| wait_network_frame(); | |
| } | |
| } | |
| } | |
| zombie_health_changed() | |
| { | |
| // Default. (Round-Based) | |
| round_number = level.round_number; | |
| // Override. (Time-Based | No Man's Land) | |
| if ( IsDefined( level.nml_timer ) && is_false( level.on_the_moon ) ) | |
| { | |
| round_number = level.nml_timer; | |
| } | |
| level.zombie_health = ai_calculate_health( get_zombie_base_health(), round_number ); | |
| level.zombie_health_old = level.zombie_health; | |
| /# IPrintLn( "[RR] Set Zombie Health to ", level.zombie_health ); #/ | |
| // Zombie health dynamically increases on Moon in No Man's Land. | |
| if ( IsDefined( level.nml_timer ) && is_false( level.on_the_moon ) ) | |
| { | |
| update_zombie_health(); | |
| } | |
| } | |
| // Referenced "scripts\core_common\ai\zombie_utility::ai_calculate_health" from BO4. | |
| ai_calculate_health( base_health, round_number ) | |
| { | |
| // Exclusively used during the Ancient Evil bossfight to bypass the health cap. | |
| // if ( isdefined( level.var_5d1805c4 ) ) | |
| // { | |
| // health = [[ level.var_5d1805c4 ]]( base_health, round_number ); | |
| // | |
| // if ( health >= 0 ) | |
| // { | |
| // return health; | |
| // } | |
| // } | |
| if ( level.gameSkill < 2 && round_number > 35 ) | |
| { | |
| round_number = 35; | |
| } | |
| health = base_health; | |
| for ( i = 2; i <= round_number; i++ ) | |
| { | |
| if ( i >= 10 ) | |
| { | |
| old_health = health; | |
| health = health + int( health * get_zombie_health_increase_multiplier() ); | |
| if ( health < old_health ) | |
| { | |
| health = old_health; | |
| return; | |
| } | |
| } | |
| else | |
| health = int( health + get_zombie_health_increase() ); | |
| } | |
| return health; | |
| } | |
| // Designed specifically for Moon in No Man's Land. Do not use on other maps! | |
| update_zombie_health() | |
| { | |
| zombies = GetAISpeciesArray( "axis", "zombie" ); | |
| count = 0; | |
| for ( i = 0; i < zombies.size; i++ ) | |
| { | |
| // Received damage. | |
| if ( zombies[i].health != level.zombie_health ) | |
| { | |
| continue; | |
| } | |
| if( is_true( zombies[i].gibbed ) ) | |
| { | |
| continue; | |
| } | |
| if ( is_true( zombies[i].head_gibbed ) ) | |
| { | |
| continue; | |
| } | |
| zombies[i].health = level.zombie_health; | |
| count++; | |
| } | |
| /# IPrintLn( "[RR] Updated Health of ", count, "/", zombies.size, " Zombies to ", level.zombie_health ); #/ | |
| } | |
| // Referenced "scriptbundle/zmdifficultysettings/zm_base_difficulty.json" | |
| get_zombie_base_health() | |
| { | |
| switch( level.gameSkill ) | |
| { | |
| case 0: | |
| return 100; // Recruit/Casual | |
| case 1: | |
| return 150; // Regular/Normal <-- Default | |
| case 2: | |
| return 150; // Hardened/Hardcore | |
| case 3: | |
| return 400; // Veteran/Realistic | |
| } | |
| } | |
| get_zombie_health_increase_multiplier() | |
| { | |
| switch( level.gameSkill ) | |
| { | |
| case 0: | |
| return 0.08; // Recruit/Casual | |
| case 1: | |
| return 0.10; // Regular/Normal <-- Default | |
| case 2: | |
| return 0.10; // Hardened/Hardcore | |
| case 3: | |
| return 0.21; // Veteran/Realistic | |
| } | |
| } | |
| get_zombie_health_increase() | |
| { | |
| switch( level.gameSkill ) | |
| { | |
| case 0: | |
| return 75; // Recruit/Casual | |
| case 1: | |
| return 100; // Regular/Normal <-- Default | |
| case 2: | |
| return 100; // Hardened/Hardcore | |
| case 3: | |
| return 250; // Veteran/Realistic | |
| } | |
| } | |
| // Each game has a different location for this function, copied to eliminate dependencies. | |
| wait_network_frame() | |
| { | |
| if ( NumRemoteClients() ) | |
| { | |
| snapshot_ids = getsnapshotindexarray(); | |
| acked = undefined; | |
| while ( !IsDefined( acked ) ) | |
| { | |
| level waittill( "snapacknowledged" ); | |
| acked = snapshotacknowledged( snapshot_ids ); | |
| } | |
| } | |
| else | |
| { | |
| wait(0.1); | |
| } | |
| } | |
| is_true( check ) | |
| { | |
| return( IsDefined( check ) && check ); | |
| } | |
| is_false( check ) | |
| { | |
| return( IsDefined( check ) && !check ); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment