Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ################################################################################
- # Nuzlocke Permadeath v1.1
- # by NettoHikari
- #
- # June 16, 2020
- #
- # NOTE: This is the v17.2 version of Nuzlocke Permadeath. If you are using
- # v18, you will need to get the updated version.
- #
- # This script allows the developer to enable a Nuzlocke-style permadeath for
- # Pokemon battles, where any Pokemon that faints is immediately removed from the
- # player's party. The difference between this and other Nuzlocke scripts is that
- # Pokemon get removed DURING battle instead of after.
- #
- # Credits MUST BE GIVEN to NettoHikari
- # You should also credit the authors of Pokemon Essentials itself.
- #
- #-------------------------------------------------------------------------------
- # INSTALLATION
- #-------------------------------------------------------------------------------
- # Copy this script, place it somewhere between "Compiler" and "Main" in the
- # script sections, and name it "Nuzlocke Permadeath".
- #
- # Before using this script, make sure to start a new save file when testing.
- # Since it adds new stored data, the script will probably throw errors when used
- # with saves where the script wasn't present before. In addition, if you decide
- # to release your game in segments, it is important to have this script
- # installed in the very first version itself, so as not to cause any problems to
- # the player.
- #
- #-------------------------------------------------------------------------------
- # SCRIPT USAGE
- #-------------------------------------------------------------------------------
- # This script offers two types of permadeath modes: SOFT and NUZLOCKE. In SOFT
- # mode, any Pokemon that faint are sent to the Pokemon Storage after the battle,
- # while in NUZLOCKE mode, they are lost forever (except for their held items).
- # To switch between permadeath modes, call "pbSetPermadeath(mode)" at the start
- # of your game (it is set to NORMAL by default at the beginning), replacing
- # "mode" with one of three modes: :NORMAL, :SOFT, or :NUZLOCKE. For example,
- # to enable the standard permadeath mode, use:
- #
- # pbSetPermadeath(:NUZLOCKE)
- #
- # and to disable it, use:
- #
- # pbSetPermadeath(:NORMAL)
- #
- # These can be called at anytime throughout your game, so for example, you can
- # change modes for specific event battles. To find out if the current permadeath
- # mode is either SOFT or NUZLOCKE use the function "pbPermadeathActive?". To
- # find out if a specific mode is enabled, use the function
- # "pbPermadeathModeIs?(mode)", replacing "mode" with what you're checking for.
- #
- # I highly suggest reading the "Additional Notes" section below for more
- # information on what the script does.
- #
- #-------------------------------------------------------------------------------
- # ADDITIONAL NOTES
- #-------------------------------------------------------------------------------
- # - On the outside, every time a Pokemon faints in SOFT or NUZLOCKE mode, it
- # LOOKS like it's been removed from the party immediately. However, what
- # happens internally is that all fainted Pokemon are hidden from the player's
- # view until the end of the round (so technically, they are still part of the
- # player's party). Then, at the end of each round, the player's party is
- # swept for fainted Pokemon, and they are removed and placed into another
- # list called "@faintedlist" (defined in PokeBattle_Battle below). Think of
- # this list as a sort of "purgatory", meaning that the Pokemon here still
- # exist as long as the battle is active, just not in the main party.
- # - At the very end of the battle in SOFT mode, @faintedlist is swept and all
- # Pokemon in it are stored in the Pokemon Storage (unless the storage is full,
- # in which case they are simply lost like NUZLOCKE mode).
- # - Any battles marked as "can lose", meaning that the game will continue
- # even if the player loses the battle, automatically have NORMAL mode on.
- # - When a Pokemon dies in NUZLOCKE mode, it drops its held item into the
- # player's bag.
- # - Pokemon can die from fainting in field due to poison if both NUZLOCKE and
- # POISONINFIELD are enabled. For SOFT mode, the Pokemon get stored in the
- # Pokemon Storage.
- # - When the player loses a battle with permadeath enabled, meaning that the
- # trainer's entire party is dead, the game simply returns to the title screen
- # with a "GAME OVER" screen, going back to the player's last save.
- #
- #-------------------------------------------------------------------------------
- # I hope you enjoy this script!
- # - NettoHikari
- ################################################################################
- module PBPermadeath
- NORMAL = 0 # Standard mode
- SOFT = 1 # "Soft" nuzlocke (fainted Pokemon get transferred to Pokemon Storage)
- NUZLOCKE = 2 # "Hard" nuzlocke (fainted Pokemon get deleted at the end of battle)
- end
- class PokemonGlobalMetadata
- # Sets battles to NORMAL, SOFT, or NUZLOCKE
- attr_accessor :permadeathmode
- end
- def pbSetPermadeath(mode)
- if mode.is_a?(Symbol)
- mode = getConst(PBPermadeath, mode)
- end
- return if mode < 0 || mode > 2
- $PokemonGlobal.permadeathmode = mode
- end
- def pbPermadeathModeIs?(mode)
- if mode.is_a?(Symbol)
- mode = getConst(PBPermadeath, mode)
- end
- return $PokemonGlobal.permadeathmode == mode
- end
- def pbPermadeathActive?
- return !pbPermadeathModeIs?(:NORMAL)
- end
- class PokeBattle_Battle
- # Keeps track of whether or not battle can be lost
- attr_accessor :canlose
- # Stores fainted Pokemon until end of battle (like a "purgatory")
- attr_accessor :faintedlist
- alias permadeath_pbStartBattle pbStartBattle
- def pbStartBattle(canlose=false)
- @canlose = canlose
- @faintedlist = []
- permadeath_pbStartBattle(canlose)
- end
- alias permadeath_pbReplace pbReplace
- def pbReplace(index,newpoke,batonpass=false)
- oldpoke=@battlers[index].pokemonIndex
- permadeath_pbReplace(index,newpoke,batonpass)
- # Party order is already changed in pbFaint, so undo party order change here
- if pbPermadeathBattle? && pbOwnedByPlayer?(index) &&
- oldpoke < $Trainer.party.length && $Trainer.party[oldpoke].fainted?
- bpo=-1; bpn=@party1order.length-1
- for i in 0...6
- bpo=i if @party1order[i] > 5 && @party1order[i] < 12
- end
- p=@party1order[bpo]; @party1order[bpo]=@party1order[bpn]; @party1order[bpn]=p
- end
- end
- alias permadeath_pbEndOfRoundPhase pbEndOfRoundPhase
- def pbEndOfRoundPhase
- # Cancel effect of Future Sight from dead Pokemon
- if pbPermadeathBattle?
- priority = pbPriority
- for i in priority
- next if !i || i.fainted?
- next if i.effects[PBEffects::FutureSightUserPos] < 0
- next if pbIsOpposing?(i.effects[PBEffects::FutureSightUserPos])
- attacker = @party1[i.effects[PBEffects::FutureSightUser]]
- if attacker.fainted?
- i.effects[PBEffects::FutureSight] = 0
- i.effects[PBEffects::FutureSightMove] = 0
- i.effects[PBEffects::FutureSightUser] = -1
- i.effects[PBEffects::FutureSightUserPos] = -1
- end
- end
- end
- permadeath_pbEndOfRoundPhase
- pbRemoveFainted
- end
- alias permadeath_pbEndOfBattle pbEndOfBattle
- def pbEndOfBattle(canlose=false)
- pbRemoveFainted
- permadeath_pbEndOfBattle(canlose)
- if pbPermadeathBattle? && pbPermadeathModeIs?(:SOFT)
- for i in @faintedlist
- storedbox = $PokemonStorage.pbStoreCaught(i)
- end
- end
- end
- def pbPermadeathBattle?
- return pbPermadeathActive? && !@canlose
- end
- def pbRemoveFainted
- return if !pbPermadeathBattle?
- pokeindex = 0
- # Loop through Trainer's party
- loop do
- break if pokeindex >= $Trainer.party.length
- if @party1[pokeindex] && @party1[pokeindex].isFainted?
- # Begin by deleting Pokemon from party entirely
- @faintedlist.push($Trainer.party[pokeindex])
- $Trainer.party.delete_at(pokeindex)
- $PokemonTemp.evolutionLevels.delete_at(pokeindex)
- $PokemonTemp.heartgauges.delete_at(pokeindex) if $PokemonTemp.heartgauges
- # Remove from double battle party as well
- if @doublebattle && $PokemonGlobal.partner
- @party1[pokeindex] = nil
- for i in pokeindex...5
- @party1[i] = @party1[i + 1]
- end
- @party1[5] = nil
- end
- # Fix party positions of current battlers
- if @battlers[0].pokemonIndex == pokeindex
- @battlers[0].pokemonIndex = $Trainer.party.length
- elsif @battlers[0].pokemonIndex > pokeindex
- @battlers[0].pokemonIndex -= 1
- end
- if @doublebattle && !$PokemonGlobal.partner
- if @battlers[2].pokemonIndex == pokeindex
- @battlers[2].pokemonIndex = $Trainer.party.length
- @battlers[2].pokemonIndex += 1 if @battlers[2].pokemonIndex == @battlers[0].pokemonIndex
- elsif @battlers[2].pokemonIndex > pokeindex
- @battlers[2].pokemonIndex -= 1
- end
- end
- # Fix participants for exp gains
- for i in [1, 3]
- next if !@battlers[i]
- participants = @battlers[i].participants
- for j in 0...participants.length
- next if !participants[j]
- participants[j] -= 1 if participants[j] > pokeindex
- end
- end
- pokeindex -= 1
- end
- pokeindex += 1
- end
- # Reset party order as shown on summary screen
- for i in 0...6
- @party1order[i] = i
- end
- # Put left side (or only) battler in first spot
- if @battlers[0].pokemonIndex != @party1order[0] &&
- @battlers[0].pokemonIndex < $Trainer.party.length
- oldpokeindex = @party1order.index(@battlers[0].pokemonIndex)
- oldpoke = @party1order[0]
- @party1order[0] = @battlers[0].pokemonIndex
- @party1order[oldpokeindex] = oldpoke
- end
- # If right side battler exists, put in second spot
- # unless left side battler is gone, then put in first spot
- if @doublebattle && !$PokemonGlobal.partner
- poi = $Trainer.ablePokemonCount > 1 ? 1 : 0
- if @battlers[2].pokemonIndex != @party1order[poi] &&
- @battlers[2].pokemonIndex < $Trainer.party.length
- oldpokeindex = @party1order.index(@battlers[2].pokemonIndex)
- oldpoke = @party1order[poi]
- @party1order[poi] = @battlers[2].pokemonIndex
- @party1order[oldpokeindex] = oldpoke
- end
- end
- # End battle if player's entire party is gone
- @decision = 2 if $Trainer.ablePokemonCount == 0
- end
- end
- class PokeBattle_Battler
- alias permadeath_pbFaint pbFaint
- def pbFaint(showMessage=true)
- return true if @fainted || !fainted?
- ret = permadeath_pbFaint(showMessage)
- if @battle.pbPermadeathBattle? && @battle.pbOwnedByPlayer?(@index)
- if showMessage && pbPermadeathModeIs?(:NUZLOCKE)
- if @battle.party1[@pokemonIndex].hasItem?
- # Informs player that fainted's held item was transferred to bag
- @battle.pbDisplayPaused(_INTL("{1} is dead! You picked up its {2}.",
- pbThis, PBItems.getName(@battle.party1[@pokemonIndex].item)))
- else
- @battle.pbDisplayPaused(_INTL("{1} is dead!",pbThis))
- end
- end
- # Remove fainted from party order
- pokeindex = @battle.party1order.index(@pokemonIndex)
- for i in pokeindex...5
- @battle.party1order[i] = @battle.party1order[i + 1]
- end
- @battle.party1order[5] = 100
- # Remove fainted from opposing participants arrays
- @battle.battlers[1].participants.delete(@pokemonIndex)
- if @battle.doublebattle && @battle.battlers[3].participants
- @battle.battlers[3].participants.delete(@pokemonIndex)
- end
- # Add held item to bag
- if @battle.party1[@pokemonIndex].hasItem? && pbPermadeathModeIs?(:NUZLOCKE)
- $PokemonBag.pbStoreItem(@battle.party1[@pokemonIndex].item)
- end
- end
- return ret
- end
- end
- # Removes Pokemon fainted by poison
- Events.onStepTakenTransferPossible+=proc {|sender,e|
- if $PokemonGlobal.stepcount%4==0 && POISONINFIELD
- $Trainer.party.delete_if{|poke|
- if pbPermadeathActive? && poke.fainted?
- if pbPermadeathModeIs?(:SOFT)
- $PokemonStorage.pbStoreCaught(poke)
- else
- if poke.hasItem?
- # Informs player that fainted's held item was transferred to bag
- Kernel.pbMessage(_INTL("{1} is dead... You picked up its {2}.",
- poke.name, PBItems.getName(poke.item)))
- else
- Kernel.pbMessage(_INTL("{1} is dead...",poke.name))
- end
- $PokemonBag.pbStoreItem(poke.item) if poke.hasItem?
- end
- true
- end
- }
- end
- }
- # Sends player back to title screen if all Pokemon lost
- module Kernel
- class << Kernel
- alias permadeath_pbStartOver pbStartOver
- end
- def self.pbStartOver(gameover=false)
- if pbPermadeathActive?
- if pbInBugContest?
- Kernel.pbBugContestStartOver
- return
- end
- Kernel.pbMessage(_INTL("\\w[]\\wm\\c[8]\\l[3]GAME OVER!"))
- Kernel.pbCancelVehicles
- pbRemoveDependencies
- $game_temp.to_title = true
- else
- self.permadeath_pbStartOver(gameover)
- end
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement