ChooseFoes XP - kyonides - 02-18-2026
ChooseFoes XP
by Kyonides
Introduction
This scriptlet allows you to open a simple menu where you can choose your enemy's troops based on the current map's random enemy encounter list.
It will use the map's battleback picture as its backdrop. Don't worry about this, it will cover the whole RMXP game screen by default. 
You are encouraged to set a custom BGM, otherwise the scene will remain silent until you have finished picking a foe.
AVAILABLE MODES
Accessory Mode
By the way, setting a specific "Choose Foe" accessory is mandatory here!
Actors' Level Average Mode
You must set a default level plus any specific map's average level.
Optional Script Calls
Change Mode:
Code: $game_party.choose_foes_mode = :your_mode
Replace the Current Map's Encounter List:
Code: $game_party.new_map_troops(TroopID1, etc.)
The Script
Version 1.0.0
Code: # * ChooseFoes XP * #
# Not Exactly a Plug-n-Play Script
# Scripter : Kyonides
# 1.0.0 - 2026-05-10
# Aliased Methods: Game_Party#initialize, Scene_Map#call_battle
# This scriptlet allows you to open a simple menu where you can choose your
# enemy's troops based on the current map's random enemy encounter list.
# They will be displayed on screen!
# The new MAP_ID_EXTRA_TROOP hash allows you to set a key-value pair of
# MapID => TroopID to add any given troop found in the Troops DB to that map.
# You can replace the TroopID with a :highest or :lowest or :random symbol.
# Notice: This is entirely optional. Use it only for maps that truly need it.
# Thanks to DerVVulfman's evil suggestion, your players might now face a whole
# new set of foes by using a very specific script call. Feel free to change
# the encounter list as many times as needed. Mwahahaha!!
# - AVAILABLE MODES: :accessory and :levels
# * Accessory Mode * #
# Setting a specific "Choose Foe" accessory is mandatory here!
# * Average Level Mode * #
# You must set a default level plus any specific map's average level.
# * Optional Script Calls * #
# * Change Current Mode:
# $game_party.choose_foes_mode = :your_mode
# * Replace Curent Map's Troop ID's:
# $game_party.new_map_troops(TroopID1, etc.)
module ChooseFoes
MODE = :levels
ACCESSORY_ID = 33
MAP_ACTOR_LVL = {}
MAP_ACTOR_LVL.default = 5
MAP_ACTOR_LVL[1] = 4
# MapID => [TroopID1, etc.] or [:highest] or [:lowest] or [:random]
MAP_ID_EXTRA_TROOPS = {}
MAP_ID_EXTRA_TROOPS.default = []
MAP_ID_EXTRA_TROOPS[1] = [10, 11]
TITLE = "Pick Your Foe"
EXTRA_TROOP = "Special Troop"
# ["Name", Volume or nil, Pitch or nil]
BGM = ["052-Negative01", nil, nil]
class TroopWindow < Window_Selectable
def initialize(width, commands)
line_max = [commands.size, 4].min + 1
@commands = commands
super(0, 0, width, line_max * 32)
@item_max = commands.size
@cw = width - 32
@rect = Rect.new(4, 0, @cw - 8, 32)
self.contents = Bitmap.new(@cw, @item_max * 32)
refresh
self.index = 0
@last_index = 0
end
def refresh
self.contents.clear
@item_max.times {|n| draw_item(n, normal_color) }
end
def draw_item(n, color)
self.contents.font.color = color
@rect.y = 32 * n
self.contents.draw_text(@rect, @commands[n])
end
def update
super
@change_troop = false
if @index != @last_index
@last_index = @index
@change_troop = true
end
end
attr_reader :change_troop
end
class Scene
def initialize(cb, replace_troops)
@callback = cb
@trooper_max = 8
@troop_max = $data_troops.size - 1
map_id = $game_map.map_id
if replace_troops
@list = $game_party.map_troop_ids[map_id]
@commands = @list.map {|n| $data_troops[n].name }
n = rand(@list.size)
@troop_id = @list[n]
else
@list = $game_map.encounter_list.dup
@commands = @list.map {|n| $data_troops[n].name }
troop_ids = MAP_ID_EXTRA_TROOPS[map_id]
if MAP_ID_EXTRA_TROOPS.has_key?(map_id)
troop_ids.each {|n| set_extra_troops(n) }
end
@troop_id = $game_temp.battle_troop_id
end
@troop = Game_Troop.new
@troop.setup(@troop_id)
$game_system.se_play($data_system.battle_start_se)
$game_system.bgm_stop
bgm = BGM.compact
bgm = RPG::AudioFile.new(*bgm)
Audio.play_anon_bgm(bgm)
end
def set_extra_troops(troop_id)
@commands << EXTRA_TROOP
case troop_id
when :lowest
@list << $game_party.lowest_troop_id
when :highest
@list << $game_party.highest_troop_id
when :random
@list << $game_party.random_troop_id
when 1..troop_id
n = [@troop_max, troop_id].min
@list << n
end
end
def main
@stage = true
fn = $game_map.battleback_name
bb = RPG::Cache.battleback(fn)
battle_bit = Bitmap.new(640, 480)
battle_bit.stretch_blt(battle_bit.rect, bb, bb.rect)
enemies = @troop.enemies
@backdrop = Sprite.new
@backdrop.bitmap = battle_bit
@vp = Viewport.new(0, 0, 640, 320)
@vp.z = 200
@battlers = []
@trooper_max.times do |n|
battler = Sprite_Battler.new(@vp, enemies[n])
battler.change(enemies[n])
@battlers << battler
end
@help_window = Window_Help.new
@help_window.set_text(TITLE, 1)
@command_window = TroopWindow.new(240, @commands)
@command_window.x = 200
@command_window.y = 320
@command_window.index = @list.index(@troop_id)
Input.update
Graphics.transition(Graphics.frame_rate)
while @stage
Graphics.update
Input.update
update
end
Graphics.freeze
dispose
end
def update
@command_window.update
if @command_window.change_troop
i = @command_window.index
@troop.setup(@list[i])
enemies = @troop.enemies
@trooper_max.times do |n|
sbattler = @battlers[n]
sbattler.change(enemies[n])
end
end
if Input.trigger?(Input::B) or Input.trigger?(Input::C)
$game_system.se_play($data_system.decision_se)
@stage = nil
n = @command_window.index
$game_temp.battle_troop_id = @list[n]
@callback.call
end
end
def dispose
@battlers.each do |s|
s.bitmap.dispose if s.bitmap
s.dispose
end
@command_window.dispose
@help_window.dispose
@vp.dispose
@backdrop.bitmap.dispose
@backdrop.dispose
end
end
end
module Audio
def self.play_anon_bgm(bgm)
if !bgm or bgm.name.empty?
bgm_stop
else
bgm_play("Audio/BGM/" + bgm.name, bgm.volume, bgm.pitch)
end
Graphics.frame_reset
end
end
class Game_Actor
def can_pick_foes?
ChooseFoes::ACCESSORY_ID == @armor4_id and @armor4_id > 0
end
end
class Game_Party
alias :kyon_chs_foes_gm_pty_init :initialize
def initialize
kyon_chs_foes_gm_pty_init
@choose_foes_mode = ChooseFoes::MODE
@defeated_troop_ids = []
@map_troop_ids = {}
end
def choose_foes_with_accessory?
@actors.find {|a| a.can_pick_foes? } != nil
end
def choose_foes_level_avg?
avg_level = @actors.inject(0) {|t, a| t + a.level }
avg_level /= @actors.size
map_level = ChooseFoes::MAP_ACTOR_LVL[$game_map.map_id]
avg_level >= map_level
end
def choose_foes?
case @choose_foes_mode
when :accessory
return choose_foes_with_accessory?
when :levels
return choose_foes_level_avg?
end
end
def lowest_troop_id
@defeated_troop_ids.min || 1
end
def highest_troop_id
@defeated_troop_ids.max || 1
end
def random_troop_id
n = rand(@defeated_troop_ids.size)
@defeated_troop_ids[n] || 1
end
def new_map_troops?(map_id)
@map_troop_ids.has_key?(map_id)
end
def new_map_troops(*troop_ids)
n = $game_map.map_id
@map_troop_ids[n] = troop_ids.flatten
end
attr_accessor :choose_foes_mode, :map_troop_ids
attr_reader :defeated_troop_ids
end
class Sprite_Battler
def change(battler)
@battler = battler
unless @battler
self.bitmap = nil
loop_animation(nil)
return
end
@battler_name = @battler.battler_name
@battler_hue = @battler.battler_hue
self.bitmap = RPG::Cache.battler(@battler_name, @battler_hue)
@width = self.bitmap.width
@height = self.bitmap.height
self.ox = @width / 2
self.oy = @height
self.x = @battler.screen_x
self.y = @battler.screen_y
self.z = @battler.screen_z
end
end
class Scene_Map
alias :kyon_chs_foes_scn_mp_cll_btl :call_battle
def call_battle
list = $game_map.encounter_list
if list.size < 2
kyon_chs_foes_scn_mp_cll_btl
return
else
cb = method(:kyon_chs_foes_scn_mp_cll_btl)
map_id = $game_map.map_id
if $game_party.new_map_troops?(map_id)
$scene = ChooseFoes::Scene.new(cb, true)
elsif $game_party.choose_foes?
$scene = ChooseFoes::Scene.new(cb, false)
end
end
end
end
Terms & Conditions
Free as in beer.
Include my nickname in your game credits.
You may mention this forum there as well.
That's it!
RE: ChooseFoes XP - kyonides - 02-18-2026
Script Update!
ChooseFoes XP has been upgraded! It has reached the 0.9.0 milestone after getting 2 brand new features and a bug fix.
Feature #1
Now you can choose a trigger mode. The available modes are :accessory and :levels right now.
:levels will retrieve your party's level average and then compare it with the current map's minimum level as set in the MAP_ACTOR_LVL hash.
Feature #2
You can call $game_party.choose_foes_mode = :accessory OR :levels to change the current default mode.
Bug Fix #1
It will now call the Scene_Map's call_battle method if the player cannot choose his or her foes.
RE: ChooseFoes XP - kyonides - 05-06-2026
Script Update!
ChooseFoes XP has been upgraded once again, now reaching the 0.11.0 milestone.
New Feature
The MAP_ID_EXTRA_TROOP hash allows you to set an extra troop for a given map.
Like all hashes, it accepts a key-value pair consisting of a MapID and a TroopID or a symbol like :lowest or :highest or :random
That value or symbol will let the script pick one troop ID from the Troops database based on a specific ID or the lowest / highest troop ever defeated so far.
Format #1
Code: MAP_ID_EXTRA_TROOP = { 1 => 11 }
Format #2
Code: MAP_ID_EXTRA_TROOP = {} # empty on purpose
MAP_ID_EXTRA_TROOP[1] = 11
MAP_ID_EXTRA_TROOP[2] = :lowest
MAP_ID_EXTRA_TROOP[3] = :highest
MAP_ID_EXTRA_TROOP[4] = :random
The fallback Troop ID will always be 1, typically the pair of good-for-nothing ghosts.
RE: ChooseFoes XP - kyonides - 05-09-2026
Script Update!
The latest release, namely version 0.14.0, brings you 2 new features that will make this menu look quite decent now.
It now offers you a new viewport where the temporarily chosen enemy troop will be displayed to your advantage. This means that your enemies won't remain anonymous anymore! 
There is another minor change I want to discuss here. It is the troop menu window itself. Now it will only display up to 4 different troop names at any given time, but feel free to scroll up or down at will to reveal the rest of the troop names. 
That change happened only because I could no longer use the typical Window_Command class because it would eventually block the screen, hiding some of the troopers on purpose.
RE: ChooseFoes XP - kyonides - 05-10-2026
Final Script Update!
The final release of your beloved menu script has arrived! 
This new version offers you a very evil feature, from the player's standpoint at least. 
What is it all about? 
Well, it's something Wulfo had suggested days ago. Something I thought it could make players hate the feature forever and ever.
Unless they were true masochists by nature.
Replace the Current Map's Encounter List:
Code: $game_party.new_map_troops(TroopID1, etc.)
This is a very dynamic way to change which foes you might face next. It is especially true if you were planning to change them as many times as needed. 
Now you should be able to understand why I consider it quite evil by design! 
So how do you check if it's time for a change? 
Well, that's completely up to you indeed! 
Just keep in mind that you can now abuse of the conditional branch event command at will.
|