Skip to content
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Donate
Collapse

Plutonium

  1. Home
  2. BO2 Modding Releases & Resources
  3. [ZM] Nightmare Mode

[ZM] Nightmare Mode

Scheduled Pinned Locked Moved BO2 Modding Releases & Resources
1 Posts 1 Posters 198 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Coronavirus-19undefined Offline
    Coronavirus-19undefined Offline
    Coronavirus-19
    wrote last edited by Coronavirus-19
    #1

    Zombies can either get challenging or scary — I think I achieved both!

    ONLY for the Tranzit Maps!

    This game mode introduces ultra fast zombies on round 100!

    Features of this mode:

    • You get one grace round, that being round 1, & during this gather perks, weapons, upgrade, etc.

    • The game forces Round 100.

    • Max Ammo Monitoring (50%) Drop System if players kill a zombie having no ammo! Empty weapon must be out for this to function.

    • All perks are given and are given back when revived, except Quick Revive!

    • Solo Quick Revive Function for Co-Op, Self Resurrection!

    • Quick Revive cost 6,000 Points.

    • Spawn in with the Ray Gun Mark II.

    • Base Health is 150 and with Juggernog it's 300 HP!

    Raw Code is highly descriptive — should be easy to make adjustments!
    #include maps\mp\_utility;
    #include maps\mp\zombies\_zm_utility;
    #include maps\mp\zombies\_zm_spawner;
    #include maps\mp\gametypes_zm\_hud_util;
    #include common_scripts\utility;
    
    init()
    {
        // Modify perk costs (Quick Revive, etc.)
        modifyPerkCosts();
    
        // Start the max ammo monitor
        level thread zombieMaxAmmoMonitor();
    }
    
    main()
    {
        // Override default zombie health calculation
        replacefunc(
            maps\mp\zombies\_zm::ai_calculate_health,
            ::ai_calculate_health
        );
    
        // Zombie systems
        thread force_round_system();
        thread force_zombie_speed();
    
        // Player systems
        level thread global_player_connect_handler();
    }
    
    global_player_connect_handler()
    {
        for(;;)
        {
            level waittill("connected", player);
    
            // make sure EVERY client gets the code
            player thread player_spawn_handler();
        }
    }
    
    player_spawn_handler()
    {
        self endon("disconnect");
        level endon("game_ended");
    
        for(;;)
        {
            self waittill("spawned_player");
    
            flag_wait("initial_blackscreen_passed");
    
            wait 0.2; // small safety delay
    
            self.jugActive = false;
            self.health_initialized = false;
    
            self thread give_start_weapon();
            self thread give_allowed_perks();
            self thread enforce_health_system();
            self thread monitor_perks();
            self thread revive_handler();
            self thread quick_revive_monitor();
            self thread force_fog_settings();
        }
    }
    
    // -------------------------
    // FORCE FOG SETTINGS
    // -------------------------
    force_fog_settings()
    {
        self endon("disconnect");
        level endon("game_ended");
    
        for(;;)
        {
            self setClientDvar("r_fog", 1);
            wait 1; // Re-apply every second in case the game resets it
        }
    }
    
    // -------------------------
    // SPAWN WITH THE RAY GUN MK II
    // -------------------------
    give_start_weapon()
    {
        self endon("disconnect");
        level endon("game_ended");
    
        wait 0.3; // give engine time to finish default loadout
    
        // Give Ray Gun Mark 2
        self giveWeapon("raygun_mark2_zm");
        self switchToWeapon("raygun_mark2_zm");
        self giveMaxAmmo("raygun_mark2_zm");
    
        self IPrintLnBold("^5Bonus Weapon Given");
    }
    
    // -------------------------
    // Quick Revive Price Change
    // -------------------------
    modifyPerkCosts()
    {
        level._custom_perks = [];
    
        level._custom_perks["specialty_quickrevive"] = spawnStruct();
        level._custom_perks["specialty_quickrevive"].cost = 6000;
        level._custom_perks["specialty_quickrevive"].hint_string = "^5Quick Revive ^7Cost: ";
    }
    
    // -------------------------
    // SPAWN WITH SPECIFIC PERKS (EXCEPTION QUICK REVIVE)
    // -------------------------
    give_allowed_perks()
    {
    	allowedPerks = [];
    
    	allowedPerks[0] = "specialty_armorvest";     // Jug
    	allowedPerks[1] = "specialty_rof";           // Double Tap
    	allowedPerks[2] = "specialty_longersprint";  // Stamin-Up
    	allowedPerks[3] = "specialty_fastreload";    // Speed Cola
    	allowedPerks[4] = "specialty_scavenger";     // Tombstone
    
    	foreach(perk in allowedPerks)
    	{
    		if(!(self hasperk(perk)))
    		{
    			self maps\mp\zombies\_zm_perks::give_perk(perk, 0);
    			wait 0.15;
    		}
    	}
    
    	// Map-specific extras via mods, would still be given PhD won't work FULLY!
    	if(level.script == "zm_transit")
    	{
    		extraPerks = [];
    		extraPerks[0] = "specialty_additionalprimaryweapon";  // MULE KICK
    		extraPerks[1] = "specialty_deadshot";              // DEADSHOT
    		extraPerks[2] = "specialty_flakjacket";               // PHD
    
    		foreach(perk in extraPerks)
    		{
    			if(!(self hasperk(perk)))
    			{
    				self maps\mp\zombies\_zm_perks::give_perk(perk, 0);
    				wait 0.15;
    			}
    		}
    	}
    }
    
    // -------------------------
    // ENFORCE HEALTH (RUNS EVERY 250ms)
    // -------------------------
    enforce_health_system()
    {
        self endon("disconnect");
        level endon("game_ended");
    
        for(;;)
        {
            wait 0.25;
    
            if (self.jugActive)
            {
                if (self.maxhealth != 300)
                {
                    self.maxhealth = 300;
                    self.health = self.maxhealth;
                }
            }
            else
            {
                if (self.maxhealth != 150)
                {
                    self.maxhealth = 150;
                    self.health = self.maxhealth;
                }
            }
        }
    }
    
    // -------------------------
    // PERK MONITOR
    // -------------------------
    monitor_perks()
    {
        self endon("disconnect");
        level endon("game_ended");
    
        for(;;)
        {
            wait 0.25;
    
            currentJug = self hasPerk("specialty_armorvest");
    
            if (!isDefined(self.jugActive) || currentJug != self.jugActive)
            {
                self.jugActive = currentJug;
    
                if (currentJug)
                {
                    self.maxhealth = 300;
                    self.health = self.maxhealth;
                    self IPrintLnBold("^2Juggernog: 300 HP");
                }
                else
                {
                    self.maxhealth = 150;
                    self.health = self.maxhealth;
                    self IPrintLnBold("^1Jug lost: 150 HP");
                }
            }
        }
    }
    
    // -------------------------
    // REVIVE HANDLER
    // -------------------------
    revive_handler()
    {
        self endon("disconnect");
        level endon("game_ended");
    
        for(;;)
        {
            self waittill("player_revived");
    
            wait 0.3; // allow engine to finish revive logic
    
            // Reset base health
            self.maxhealth = 150;
            self.health = self.maxhealth;
    
            self IPrintLnBold("^3Revived → HP reset to 150");
    
            // Restore allowed perks
            self thread give_allowed_perks();
        }
    }
    
    // -------------------------
    // QUICK REVIVE AUTO-REVIVE (COOP)
    // -------------------------
    quick_revive_monitor()
    {
        self endon("disconnect");
        level endon("game_ended");
    
        for(;;)
        {
            self waittill("player_downed");
    
            // Only works in coop (2+ players)
            if(level.players.size > 1 && self HasPerk("specialty_quickrevive"))
            {
                wait 1; // let downed animation finish
    
                maps\mp\zombies\_zm_laststand::auto_revive(self);
    
                self IPrintLnBold("^2Quick Revive Activated!");
            }
        }
    }
    
    zombieMaxAmmoMonitor()
    {
    	level endon("game_ended");
    
    	prev_count = 0;
    	level.forced_max_ammo = false;
    
    	for(;;)
    	{
    		players = get_players();
    		curr_count = GetAiArray("axis").size;
    
    		// Check if any player just hit 0 ammo
    		foreach(player in players)
    		{
    			if(!isDefined(player.prev_ammo))
    				player.prev_ammo = calculate_total_ammo(player);
    
    			current_ammo = calculate_total_ammo(player);
    
    			if(current_ammo == 0 && player.prev_ammo > 0)
    				level.forced_max_ammo = true;
    
    			player.prev_ammo = current_ammo;
    		}
    
    		// Detect zombie death
    		if(curr_count < prev_count)
    		{
    			min_perc = 1.0;
    
    			foreach(player in players)
    			{
    				total_left = calculate_total_ammo(player);
    				total_max = calculate_total_max(player);
    
    				if(total_max > 0)
    				{
    					perc = total_left / total_max;
    					if(perc < min_perc)
    						min_perc = perc;
    				}
    			}
    
    			drop = false;
    
    			// 100% if someone fully ran out
    			if(level.forced_max_ammo)
    			{
    				drop = true;
    				level.forced_max_ammo = false;
    			}
    			else
    			{
    				max_desp = 1.0 - min_perc;
    				chance = int(50 * (max_desp * max_desp)); // Adjustable (where [50] is & only on this line!)
    
    				if(randomInt(100) < chance)
    					drop = true;
    			}
    
    			if(drop && players.size)
    			{
    				player = players[randomInt(players.size)];
    
    				drop_origin = player.origin + (randomIntRange(-120,120), randomIntRange(-120,120), 50);
    				trace = bulletTrace(drop_origin + (0,0,100), drop_origin + (0,0,-400), 0, player);
    
    				level thread maps\mp\zombies\_zm_powerups::specific_powerup_drop("full_ammo", trace["position"]);
    			}
    		}
    
    		prev_count = curr_count;
    		wait 0.1;
    	}
    }
    
    calculate_total_ammo(player)
    {
    	weapons = player GetWeaponsList();
    	total = 0;
    
    	foreach(weapon in weapons)
    		total += player GetWeaponAmmoClip(weapon) + player GetWeaponAmmoStock(weapon);
    
    	return total;
    }
    
    calculate_total_max(player)
    {
    	weapons = player GetWeaponsList();
    	total = 0;
    
    	foreach(weapon in weapons)
    		total += WeaponClipSize(weapon) + WeaponMaxAmmo(weapon);
    
    	return total;
    }
    
    //
    // ===============================
    // FORCE ROUND TO 100
    // ===============================
    //
    
    force_round_system()
    {
        level endon("game_ended");
    
        wait 8; // allow map to fully initialize
    
        for(;;)
        {
            wait 0.2;
    
            if(!isDefined(level.round_number))
                continue;
    
            if(level.round_number < 99) // Adjustable
            {
                level.round_number++;
    
                // Properly update round display
                level notify("round_start");
    
                iprintlnbold("^1FORCED ROUND: ^7" + level.round_number);
            }
        }
    }
    
    //
    // ===============================
    // FORCE ZOMBIE ANIMATION (HARD LOOP)
    // ===============================
    //
    
    force_zombie_speed()
    {
        level endon("game_ended");
    
        // Wait for Round 1 to start
        level waittill("start_of_round");
    
        // Wait for Round 2 to start
        level waittill("start_of_round");
    
        for(;;)
        {
            wait 5;
    
            zombies = getAIArray(level.zombie_team);
    
            foreach(zombie in zombies)
            {
                if(isdefined(zombie) &&
                !(isdefined(zombie.is_traversing) && zombie.is_traversing) &&
                (isdefined(zombie.ai_state) && zombie.ai_state == "find_flesh") &&
                zombie.zombie_move_speed != "chase_bus")
                {
                    zombie set_zombie_run_cycle("chase_bus");
                }
            }
        }
    }
    
    //
    // ==================================================
    // ZOMBIE HEALTH + INSTAKILL
    // - No round cap
    // - HP Adjustments at 100+
    // ==================================================
    //
    
    ai_calculate_health( round_number )
    {
    	if ( round_number >= 100 )
    	{
    		level.zombie_health = 25000; // Adjustable
    		return;
    	}
    
    	level.zombie_health = level.zombie_vars["zombie_health_start"];
    	i = 2;
    
    	while ( i <= round_number )
    	{
    		if ( i >= 10 )
    		{
    			level.zombie_health += int(
    				level.zombie_health *
    				level.zombie_vars["zombie_health_increase_multiplier"]
    			);
    		}
    		else
    		{
    			level.zombie_health += level.zombie_vars["zombie_health_increase"];
    		}
    
    		i++;
    	}
    
    	// Overflow protection
    	if ( level.zombie_health <= 0 )
    	{
    		level.zombie_health = level.zombie_vars["zombie_health_start"];
    	}
    }
    

    Video | Script Download

    Path: Win + R "%localappdata%"

    • Plutonium/storage/t6/scripts/zm/zm_transit

    Credit:

    • https://forum.plutonium.pw/topic/39957/perk-mystery-box-cost-change

    • https://github.com/teh-bandit/Plutonium-T6ZM/tree/main

    • https://forum.plutonium.pw/topic/43790/release-zombies-zenkai-true-quick-revive-coop-more-max-ammo-no-limit-perk?_=1771420816625

    • Plutonium Discord Member: ivobardolf

    1 Reply Last reply
    2

    Hello! It looks like you're interested in this conversation, but you don't have an account yet.

    Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

    With your input, this post could be even better 💗

    Register Login
    Reply
    • Reply as topic
    Log in to reply
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes


    • Login

    • Don't have an account? Register

    • Login or register to search.
    • First post
      Last post
    0
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Donate