#include "../include/common.h"

const short kong_flags[] = {FLAG_KONG_DK,FLAG_KONG_DIDDY,FLAG_KONG_LANKY,FLAG_KONG_TINY,FLAG_KONG_CHUNKY};
const short normal_key_flags[] = {
	FLAG_KEYHAVE_KEY1,
	FLAG_KEYHAVE_KEY2,
	FLAG_KEYHAVE_KEY3,
	FLAG_KEYHAVE_KEY4,
	FLAG_KEYHAVE_KEY5,
	FLAG_KEYHAVE_KEY6,
	FLAG_KEYHAVE_KEY7,
	FLAG_KEYHAVE_KEY8
};
short tbarrel_flags[] = {
	FLAG_TBARREL_BARREL,
	FLAG_TBARREL_DIVE,
	FLAG_TBARREL_ORANGE,
	FLAG_TBARREL_VINE,
};
short bfi_move_flags[] = {
	FLAG_ABILITY_CAMERA,
	FLAG_ABILITY_SHOCKWAVE,
};
const short tnsportal_flags[] = {
	// Troff n Scoff portal clear flags
	FLAG_PORTAL_JAPES,
	FLAG_PORTAL_AZTEC,
	FLAG_PORTAL_FACTORY,
	FLAG_PORTAL_GALLEON,
	FLAG_PORTAL_FUNGI,
	FLAG_PORTAL_CAVES,
	FLAG_PORTAL_CASTLE,
};
const unsigned char kong_pellets[] = {48,36,42,43,38};
const rgb colorblind_colors[15] = {
    // Protan
    {.red=0x27, .green=0x27, .blue=0x27}, // DK
    {.red=0x00, .green=0x72, .blue=0xFF}, // Diddy
    {.red=0x76, .green=0x6D, .blue=0x5A}, // Lanky
    {.red=0xFF, .green=0xFF, .blue=0xFF}, // Tiny
    {.red=0xFD, .green=0xE4, .blue=0x00}, // Chunky
    // Deutan
    {.red=0x27, .green=0x27, .blue=0x27}, // DK
    {.red=0x31, .green=0x8D, .blue=0xFF}, // Diddy
    {.red=0x7F, .green=0x6D, .blue=0x59}, // Lanky
    {.red=0xFF, .green=0xFF, .blue=0xFF}, // Tiny
    {.red=0xE3, .green=0xA9, .blue=0x00}, // Chunky
    // Tritan
    {.red=0x27, .green=0x27, .blue=0x27}, // DK
    {.red=0xC7, .green=0x20, .blue=0x20}, // Diddy
    {.red=0x13, .green=0xC4, .blue=0xD8}, // Lanky
    {.red=0xFF, .green=0xFF, .blue=0xFF}, // Tiny
    {.red=0xFF, .green=0xA4, .blue=0xA4}, // Chunky
};
const unsigned char crown_maps[] = {
	MAP_BATTLEARENA_BEAVERBRAWL,
	MAP_BATTLEARENA_KRITTERKARNAGE,
	MAP_BATTLEARENA_ARENAAMBUSH,
	MAP_BATTLEARENA_MOREKRITTERKARNAGE,
	MAP_BATTLEARENA_KAMIKAZEKREMLINGS,
	MAP_BATTLEARENA_PLINTHPANIC,
	MAP_BATTLEARENA_PINNACLEPALAVER,
	MAP_BATTLEARENA_FORESTFRACAS,
	MAP_BATTLEARENA_SHOCKWAVESHOWDOWN,
	MAP_BATTLEARENA_BISHBASHBRAWL
};
const unsigned char regular_boss_maps[] = {
	MAP_JAPESDILLO,
    MAP_AZTECDOGADON,
    MAP_FACTORYJACK,
    MAP_GALLEONPUFFTOSS,
    MAP_FUNGIDOGADON,
    MAP_CAVESDILLO,
    MAP_CASTLEKUTOUT
};
static const unsigned char training_maps[] = {
	MAP_TBARREL_VINE,
	MAP_TBARREL_BARREL,
	MAP_TBARREL_DIVE,
	MAP_TBARREL_ORANGE,
};
static unsigned char shop_maps[] = {
	MAP_CRANKY,
	MAP_CANDY,
	MAP_FUNKY,
	MAP_SNIDE,
};
static const map_bitfield minigame_maps_btf = {
    // Bitfield on whether a map is a minigame map
	.test_map = 0,
    .funkys_store = 0,
    .dk_arcade = 1,
    .k_rool_barrel_lankys_maze = 1,
    .jungle_japes_mountain = 0,
    .crankys_lab = 0,
    .jungle_japes_minecart = 0,
    .jungle_japes = 0,
    .jungle_japes_army_dillo = 0,
    .jetpac = 1,
    .kremling_kosh_very_easy = 1,
    .stealthy_snoop_normal_no_logo = 1,
    .jungle_japes_shell = 0,
    .jungle_japes_lankys_cave = 0,
    .angry_aztec_beetle_race = 0,
    .snides_hq = 0,
    .angry_aztec_tinys_temple = 0,
    .hideout_helm = 0,
    .teetering_turtle_trouble_very_easy = 1,
    .angry_aztec_five_door_temple_dk = 0,
    .angry_aztec_llama_temple = 0,
    .angry_aztec_five_door_temple_diddy = 0,
    .angry_aztec_five_door_temple_tiny = 0,
    .angry_aztec_five_door_temple_lanky = 0,
    .angry_aztec_five_door_temple_chunky = 0,
    .candys_music_shop = 0,
    .frantic_factory = 0,
    .frantic_factory_car_race = 0,
    .hideout_helm_level_intros_game_over = 0,
    .frantic_factory_power_shed = 0,
    .gloomy_galleon = 0,
    .gloomy_galleon_k_rools_ship = 0,
    .batty_barrel_bandit_very_easy = 1,
    .jungle_japes_chunkys_cave = 0,
    .dk_isles_overworld = 0,
    .k_rool_barrel_dks_target_game = 1,
    .frantic_factory_crusher_room = 0,
    .jungle_japes_barrel_blast = 0,
    .angry_aztec = 0,
    .gloomy_galleon_seal_race = 0,
    .nintendo_logo = 0,
    .angry_aztec_barrel_blast = 0,
    .troff_n_scoff = 0,
    .gloomy_galleon_shipwreck_diddy_lanky_chunky = 0,
    .gloomy_galleon_treasure_chest = 0,
    .gloomy_galleon_mermaid = 0,
    .gloomy_galleon_shipwreck_dk_tiny = 0,
    .gloomy_galleon_shipwreck_lanky_tiny = 0,
    .fungi_forest = 0,
    .gloomy_galleon_lighthouse = 0,
    .k_rool_barrel_tinys_mushroom_game = 1,
    .gloomy_galleon_mechanical_fish = 0,
    .fungi_forest_ant_hill = 0,
    .battle_arena_beaver_brawl = 0,
    .gloomy_galleon_barrel_blast = 0,
    .fungi_forest_minecart = 0,
    .fungi_forest_diddys_barn = 0,
    .fungi_forest_diddys_attic = 0,
    .fungi_forest_lankys_attic = 0,
    .fungi_forest_dks_barn = 0,
    .fungi_forest_spider = 0,
    .fungi_forest_front_part_of_mill = 0,
    .fungi_forest_rear_part_of_mill = 0,
    .fungi_forest_mushroom_puzzle = 0,
    .fungi_forest_giant_mushroom = 0,
    .stealthy_snoop_normal = 1,
    .mad_maze_maul_hard = 1,
    .stash_snatch_normal = 1,
    .mad_maze_maul_easy = 1,
    .mad_maze_maul_normal = 1,
    .fungi_forest_mushroom_leap = 0,
    .fungi_forest_shooting_game = 0,
    .crystal_caves = 0,
    .battle_arena_kritter_karnage = 0,
    .stash_snatch_easy = 1,
    .stash_snatch_hard = 1,
    .dk_rap = 0,
    .minecart_mayhem_easy = 1,
    .busy_barrel_barrage_easy = 1,
    .busy_barrel_barrage_normal = 1,
    .main_menu = 0,
    .title_screen_not_for_resale_version = 0,
    .crystal_caves_beetle_race = 0,
    .fungi_forest_dogadon = 0,
    .crystal_caves_igloo_tiny = 0,
    .crystal_caves_igloo_lanky = 0,
    .crystal_caves_igloo_dk = 0,
    .creepy_castle = 0,
    .creepy_castle_ballroom = 0,
    .crystal_caves_rotating_room = 0,
    .crystal_caves_shack_chunky = 0,
    .crystal_caves_shack_dk = 0,
    .crystal_caves_shack_diddy_middle_part = 0,
    .crystal_caves_shack_tiny = 0,
    .crystal_caves_lankys_hut = 0,
    .crystal_caves_igloo_chunky = 0,
    .splish_splash_salvage_normal = 1,
    .k_lumsy = 0,
    .crystal_caves_ice_castle = 0,
    .speedy_swing_sortie_easy = 1,
    .crystal_caves_igloo_diddy = 0,
    .krazy_kong_klamour_easy = 1,
    .big_bug_bash_very_easy = 1,
    .searchlight_seek_very_easy = 1,
    .beaver_bother_easy = 1,
    .creepy_castle_tower = 0,
    .creepy_castle_minecart = 0,
    .kong_battle_battle_arena = 0,
    .creepy_castle_crypt_lanky_tiny = 0,
    .kong_battle_arena_1 = 0,
    .frantic_factory_barrel_blast = 0,
    .gloomy_galleon_pufftoss = 0,
    .creepy_castle_crypt_dk_diddy_chunky = 0,
    .creepy_castle_museum = 0,
    .creepy_castle_library = 0,
    .kremling_kosh_easy = 1,
    .kremling_kosh_normal = 1,
    .kremling_kosh_hard = 1,
    .teetering_turtle_trouble_easy = 1,
    .teetering_turtle_trouble_normal = 1,
    .teetering_turtle_trouble_hard = 1,
    .batty_barrel_bandit_easy = 1,
    .batty_barrel_bandit_normal = 1,
    .batty_barrel_bandit_hard = 1,
    .mad_maze_maul_insane = 1,
    .stash_snatch_insane = 1,
    .stealthy_snoop_very_easy = 1,
    .stealthy_snoop_easy = 1,
    .stealthy_snoop_hard = 1,
    .minecart_mayhem_normal = 1,
    .minecart_mayhem_hard = 1,
    .busy_barrel_barrage_hard = 1,
    .splish_splash_salvage_hard = 1,
    .splish_splash_salvage_easy = 1,
    .speedy_swing_sortie_normal = 1,
    .speedy_swing_sortie_hard = 1,
    .beaver_bother_normal = 1,
    .beaver_bother_hard = 1,
    .searchlight_seek_easy = 1,
    .searchlight_seek_normal = 1,
    .searchlight_seek_hard = 1,
    .krazy_kong_klamour_normal = 1,
    .krazy_kong_klamour_hard = 1,
    .krazy_kong_klamour_insane = 1,
    .peril_path_panic_very_easy = 1,
    .peril_path_panic_easy = 1,
    .peril_path_panic_normal = 1,
    .peril_path_panic_hard = 1,
    .big_bug_bash_easy = 1,
    .big_bug_bash_normal = 1,
    .big_bug_bash_hard = 1,
    .creepy_castle_dungeon = 0,
    .hideout_helm_intro_story = 0,
    .dk_isles_dk_theatre = 0,
    .frantic_factory_mad_jack = 0,
    .battle_arena_arena_ambush = 0,
    .battle_arena_more_kritter_karnage = 0,
    .battle_arena_forest_fracas = 0,
    .battle_arena_bish_bash_brawl = 0,
    .battle_arena_kamikaze_kremlings = 0,
    .battle_arena_plinth_panic = 0,
    .battle_arena_pinnacle_palaver = 0,
    .battle_arena_shockwave_showdown = 0,
    .creepy_castle_basement = 0,
    .creepy_castle_tree = 0,
    .k_rool_barrel_diddys_kremling_game = 1,
    .creepy_castle_chunkys_toolshed = 0,
    .creepy_castle_trash_can = 0,
    .creepy_castle_greenhouse = 0,
    .jungle_japes_lobby = 0,
    .hideout_helm_lobby = 0,
    .dks_house = 0,
    .rock_intro_story = 0,
    .angry_aztec_lobby = 0,
    .gloomy_galleon_lobby = 0,
    .frantic_factory_lobby = 0,
    .training_grounds = 0,
    .dive_barrel = 0,
    .fungi_forest_lobby = 0,
    .gloomy_galleon_submarine = 0,
    .orange_barrel = 0,
    .barrel_barrel = 0,
    .vine_barrel = 0,
    .creepy_castle_crypt = 0,
    .enguarde_arena = 0,
    .creepy_castle_car_race = 0,
    .crystal_caves_barrel_blast = 0,
    .creepy_castle_barrel_blast = 0,
    .fungi_forest_barrel_blast = 0,
    .fairy_island = 0,
    .kong_battle_arena_2 = 0,
    .rambi_arena = 0,
    .kong_battle_arena_3 = 0,
    .creepy_castle_lobby = 0,
    .crystal_caves_lobby = 0,
    .dk_isles_snides_room = 0,
    .crystal_caves_army_dillo = 0,
    .angry_aztec_dogadon = 0,
    .training_grounds_end_sequence = 0,
    .creepy_castle_king_kut_out = 0,
    .crystal_caves_shack_diddy_upper_part = 0,
    .k_rool_barrel_diddys_rocketbarrel_game = 1,
    .k_rool_barrel_lankys_shooting_game = 1,
    .k_rool_fight_dk_phase = 0,
    .k_rool_fight_diddy_phase = 0,
    .k_rool_fight_lanky_phase = 0,
    .k_rool_fight_tiny_phase = 0,
    .k_rool_fight_chunky_phase = 0,
    .bloopers_ending = 0,
    .k_rool_barrel_chunkys_hidden_kremling_game = 1,
    .k_rool_barrel_tinys_pony_tail_twirl_game = 1,
    .k_rool_barrel_chunkys_shooting_game = 1,
    .k_rool_barrel_dks_rambi_game = 1,
    .k_lumsy_ending = 0,
    .k_rools_shoe = 0,
    .k_rools_arena = 0,
	.arcade_25m = 1,
	.arcade_50m = 1,
	.arcade_75m = 1,
	.arcade_100m = 1,
	.jetpac_rocket = 1,
};
static const char overlay_indexes[] = {
	OVERLAY_NONE, // Test Map
	OVERLAY_MENU, // Funky's Store
	OVERLAY_ARCADE, // DK Arcade
	OVERLAY_BONUS, // K. Rool Barrel: Lanky's Maze
	OVERLAY_MINECART, // Jungle Japes: Mountain
	OVERLAY_MENU, // Cranky's Lab
	OVERLAY_MINECART, // Jungle Japes: Minecart
	OVERLAY_CRITTER, // Jungle Japes
	OVERLAY_BOSS, // Jungle Japes: Army Dillo
	OVERLAY_JETPAC, // Jetpac
	OVERLAY_BONUS, // Kremling Kosh! (very easy)
	OVERLAY_BONUS, // Stealthy Snoop! (normal, no logo)
	OVERLAY_NONE, // Jungle Japes: Shell
	OVERLAY_NONE, // Jungle Japes: Lanky's Cave
	OVERLAY_RACE, // Angry Aztec: Beetle Race
	OVERLAY_MENU, // Snide's H.Q.
	OVERLAY_CRITTER, // Angry Aztec: Tiny's Temple
	OVERLAY_NONE, // Hideout Helm
	OVERLAY_BONUS, // Teetering Turtle Trouble! (very easy)
	OVERLAY_NONE, // Angry Aztec: Five Door Temple (DK)
	OVERLAY_NONE, // Angry Aztec: Llama Temple
	OVERLAY_NONE, // Angry Aztec: Five Door Temple (Diddy)
	OVERLAY_NONE, // Angry Aztec: Five Door Temple (Tiny)
	OVERLAY_NONE, // Angry Aztec: Five Door Temple (Lanky)
	OVERLAY_NONE, // Angry Aztec: Five Door Temple (Chunky)
	OVERLAY_MENU, // Candy's Music Shop
	OVERLAY_NONE, // Frantic Factory
	OVERLAY_RACE, // Frantic Factory: Car Race
	OVERLAY_BOSS, // Hideout Helm (Level Intros, Game Over)
	OVERLAY_NONE, // Frantic Factory: Power Shed
	OVERLAY_CRITTER, // Gloomy Galleon
	OVERLAY_NONE, // Gloomy Galleon: K. Rool's Ship
	OVERLAY_BONUS, // Batty Barrel Bandit! (easy)
	OVERLAY_CRITTER, // Jungle Japes: Chunky's Cave
	OVERLAY_CRITTER, // DK Isles Overworld
	OVERLAY_BONUS, // K. Rool Barrel: DK's Target Game
	OVERLAY_NONE, // Frantic Factory: Crusher Room
	OVERLAY_NONE, // Jungle Japes: Barrel Blast
	OVERLAY_NONE, // Angry Aztec
	OVERLAY_RACE, // Gloomy Galleon: Seal Race
	OVERLAY_MENU, // Nintendo Logo
	OVERLAY_NONE, // Angry Aztec: Barrel Blast
	OVERLAY_CRITTER, // Troff 'n' Scoff
	OVERLAY_CRITTER, // Gloomy Galleon: Shipwreck (Diddy, Lanky, Chunky)
	OVERLAY_CRITTER, // Gloomy Galleon: Treasure Chest
	OVERLAY_CRITTER, // Gloomy Galleon: Mermaid
	OVERLAY_CRITTER, // Gloomy Galleon: Shipwreck (DK, Tiny)
	OVERLAY_CRITTER, // Gloomy Galleon: Shipwreck (Lanky, Tiny)
	OVERLAY_NONE, // Fungi Forest
	OVERLAY_NONE, // Gloomy Galleon: Lighthouse
	OVERLAY_BONUS, // K. Rool Barrel: Tiny's Mushroom Game
	OVERLAY_NONE, // Gloomy Galleon: Mechanical Fish
	OVERLAY_NONE, // Fungi Forest: Ant Hill
	OVERLAY_BONUS, // Battle Arena: Beaver Brawl!
	OVERLAY_NONE, // Gloomy Galleon: Barrel Blast
	OVERLAY_MINECART, // Fungi Forest: Minecart
	OVERLAY_CRITTER, // Fungi Forest: Diddy's Barn
	OVERLAY_NONE, // Fungi Forest: Diddy's Attic
	OVERLAY_NONE, // Fungi Forest: Lanky's Attic
	OVERLAY_NONE, // Fungi Forest: DK's Barn
	OVERLAY_BOSS, // Fungi Forest: Spider
	OVERLAY_NONE, // Fungi Forest: Front Part of Mill
	OVERLAY_NONE, // Fungi Forest: Rear Part of Mill
	OVERLAY_NONE, // Fungi Forest: Mushroom Puzzle
	OVERLAY_NONE, // Fungi Forest: Giant Mushroom
	OVERLAY_BONUS, // Stealthy Snoop! (normal)
	OVERLAY_BONUS, // Mad Maze Maul! (hard)
	OVERLAY_BONUS, // Stash Snatch! (normal)
	OVERLAY_BONUS, // Mad Maze Maul! (easy)
	OVERLAY_BONUS, // Mad Maze Maul! (normal)
	OVERLAY_NONE, // Fungi Forest: Mushroom Leap
	OVERLAY_NONE, // Fungi Forest: Shooting Game
	OVERLAY_CRITTER, // Crystal Caves
	OVERLAY_BONUS, // Battle Arena: Kritter Karnage!
	OVERLAY_BONUS, // Stash Snatch! (easy)
	OVERLAY_BONUS, // Stash Snatch! (hard)
	OVERLAY_CRITTER, // DK Rap
	OVERLAY_MINECART, // Minecart Mayhem! (easy)
	OVERLAY_BONUS, // Busy Barrel Barrage! (easy)
	OVERLAY_BONUS, // Busy Barrel Barrage! (normal)
	OVERLAY_MENU, // Main Menu
	OVERLAY_NONE, // Title Screen (Not For Resale Version)
	OVERLAY_RACE, // Crystal Caves: Beetle Race
	OVERLAY_BOSS, // Fungi Forest: Dogadon
	OVERLAY_NONE, // Crystal Caves: Igloo (Tiny)
	OVERLAY_NONE, // Crystal Caves: Igloo (Lanky)
	OVERLAY_NONE, // Crystal Caves: Igloo (DK)
	OVERLAY_NONE, // Creepy Castle
	OVERLAY_NONE, // Creepy Castle: Ballroom
	OVERLAY_NONE, // Crystal Caves: Rotating Room
	OVERLAY_NONE, // Crystal Caves: Shack (Chunky)
	OVERLAY_NONE, // Crystal Caves: Shack (DK)
	OVERLAY_NONE, // Crystal Caves: Shack (Diddy, middle part)
	OVERLAY_NONE, // Crystal Caves: Shack (Tiny)
	OVERLAY_NONE, // Crystal Caves: Lanky's Hut
	OVERLAY_NONE, // Crystal Caves: Igloo (Chunky)
	OVERLAY_BONUS, // Splish-Splash Salvage! (normal)
	OVERLAY_NONE, // K. Lumsy
	OVERLAY_NONE, // Crystal Caves: Ice Castle
	OVERLAY_BONUS, // Speedy Swing Sortie! (easy)
	OVERLAY_NONE, // Crystal Caves: Igloo (Diddy)
	OVERLAY_BONUS, // Krazy Kong Klamour! (easy)
	OVERLAY_BONUS, // Big Bug Bash! (very easy)
	OVERLAY_BONUS, // Searchlight Seek! (very easy)
	OVERLAY_BONUS, // Beaver Bother! (easy)
	OVERLAY_NONE, // Creepy Castle: Tower
	OVERLAY_MINECART, // Creepy Castle: Minecart
	OVERLAY_MULTI, // Kong Battle: Battle Arena
	OVERLAY_NONE, // Creepy Castle: Crypt (Lanky, Tiny)
	OVERLAY_MULTI, // Kong Battle: Arena 1
	OVERLAY_NONE, // Frantic Factory: Barrel Blast
	OVERLAY_BOSS, // Gloomy Galleon: Pufftoss
	OVERLAY_NONE, // Creepy Castle: Crypt (DK, Diddy, Chunky)
	OVERLAY_NONE, // Creepy Castle: Museum
	OVERLAY_NONE, // Creepy Castle: Library
	OVERLAY_BONUS, // Kremling Kosh! (easy)
	OVERLAY_BONUS, // Kremling Kosh! (normal)
	OVERLAY_BONUS, // Kremling Kosh! (hard)
	OVERLAY_BONUS, // Teetering Turtle Trouble! (easy)
	OVERLAY_BONUS, // Teetering Turtle Trouble! (normal)
	OVERLAY_BONUS, // Teetering Turtle Trouble! (hard)
	OVERLAY_BONUS, // Batty Barrel Bandit! (easy)
	OVERLAY_BONUS, // Batty Barrel Bandit! (normal)
	OVERLAY_BONUS, // Batty Barrel Bandit! (hard)
	OVERLAY_BONUS, // Mad Maze Maul! (insane)
	OVERLAY_BONUS, // Stash Snatch! (insane)
	OVERLAY_BONUS, // Stealthy Snoop! (very easy)
	OVERLAY_BONUS, // Stealthy Snoop! (easy)
	OVERLAY_BONUS, // Stealthy Snoop! (hard)
	OVERLAY_MINECART, // Minecart Mayhem! (normal)
	OVERLAY_MINECART, // Minecart Mayhem! (hard)
	OVERLAY_BONUS, // Busy Barrel Barrage! (hard)
	OVERLAY_BONUS, // Splish-Splash Salvage! (hard)
	OVERLAY_BONUS, // Splish-Splash Salvage! (easy)
	OVERLAY_BONUS, // Speedy Swing Sortie! (normal)
	OVERLAY_BONUS, // Speedy Swing Sortie! (hard)
	OVERLAY_BONUS, // Beaver Bother! (normal)
	OVERLAY_BONUS, // Beaver Bother! (hard)
	OVERLAY_BONUS, // Searchlight Seek! (easy)
	OVERLAY_BONUS, // Searchlight Seek! (normal)
	OVERLAY_BONUS, // Searchlight Seek! (hard)
	OVERLAY_BONUS, // Krazy Kong Klamour! (normal)
	OVERLAY_BONUS, // Krazy Kong Klamour! (hard)
	OVERLAY_BONUS, // Krazy Kong Klamour! (insane)
	OVERLAY_BONUS, // Peril Path Panic! (very easy)
	OVERLAY_BONUS, // Peril Path Panic! (easy)
	OVERLAY_BONUS, // Peril Path Panic! (normal)
	OVERLAY_BONUS, // Peril Path Panic! (hard)
	OVERLAY_BONUS, // Big Bug Bash! (easy)
	OVERLAY_BONUS, // Big Bug Bash! (normal)
	OVERLAY_BONUS, // Big Bug Bash! (hard)
	OVERLAY_NONE, // Creepy Castle: Dungeon
	OVERLAY_NONE, // Hideout Helm (Intro Story)
	OVERLAY_NONE, // DK Isles (DK Theatre)
	OVERLAY_BOSS, // Frantic Factory: Mad Jack
	OVERLAY_BONUS, // Battle Arena: Arena Ambush!
	OVERLAY_BONUS, // Battle Arena: More Kritter Karnage!
	OVERLAY_BONUS, // Battle Arena: Forest Fracas!
	OVERLAY_BONUS, // Battle Arena: Bish Bash Brawl!
	OVERLAY_BONUS, // Battle Arena: Kamikaze Kremlings!
	OVERLAY_BONUS, // Battle Arena: Plinth Panic!
	OVERLAY_BONUS, // Battle Arena: Pinnacle Palaver!
	OVERLAY_BONUS, // Battle Arena: Shockwave Showdown!
	OVERLAY_NONE, // Creepy Castle: Basement
	OVERLAY_NONE, // Creepy Castle: Tree
	OVERLAY_BONUS, // K. Rool Barrel: Diddy's Kremling Game
	OVERLAY_NONE, // Creepy Castle: Chunky's Toolshed
	OVERLAY_NONE, // Creepy Castle: Trash Can
	OVERLAY_NONE, // Creepy Castle: Greenhouse
	OVERLAY_CRITTER, // Jungle Japes Lobby
	OVERLAY_CRITTER, // Hideout Helm Lobby
	OVERLAY_NONE, // DK's House
	OVERLAY_NONE, // Rock (Intro Story)
	OVERLAY_CRITTER, // Angry Aztec Lobby
	OVERLAY_CRITTER, // Gloomy Galleon Lobby
	OVERLAY_CRITTER, // Frantic Factory Lobby
	OVERLAY_CRITTER, // Training Grounds
	OVERLAY_CRITTER, // Dive Barrel
	OVERLAY_CRITTER, // Fungi Forest Lobby
	OVERLAY_NONE, // Gloomy Galleon: Submarine
	OVERLAY_CRITTER, // Orange Barrel
	OVERLAY_CRITTER, // Barrel Barrel
	OVERLAY_CRITTER, // Vine Barrel
	OVERLAY_NONE, // Creepy Castle: Crypt
	OVERLAY_BONUS, // Enguarde Arena
	OVERLAY_RACE, // Creepy Castle: Car Race
	OVERLAY_NONE, // Crystal Caves: Barrel Blast
	OVERLAY_NONE, // Creepy Castle: Barrel Blast
	OVERLAY_NONE, // Fungi Forest: Barrel Blast
	OVERLAY_CRITTER, // Fairy Island
	OVERLAY_MULTI, // Kong Battle: Arena 2
	OVERLAY_BONUS, // Rambi Arena
	OVERLAY_MULTI, // Kong Battle: Arena 3
	OVERLAY_CRITTER, // Creepy Castle Lobby
	OVERLAY_CRITTER, // Crystal Caves Lobby
	OVERLAY_CRITTER, // DK Isles: Snide's Room
	OVERLAY_BOSS, // Crystal Caves: Army Dillo
	OVERLAY_BOSS, // Angry Aztec: Dogadon
	OVERLAY_NONE, // Training Grounds (End Sequence)
	OVERLAY_BOSS, // Creepy Castle: King Kut Out
	OVERLAY_NONE, // Crystal Caves: Shack (Diddy, upper part)
	OVERLAY_BONUS, // K. Rool Barrel: Diddy's Rocketbarrel Game
	OVERLAY_BONUS, // K. Rool Barrel: Lanky's Shooting Game
	OVERLAY_BOSS, // K. Rool Fight: DK Phase
	OVERLAY_BOSS, // K. Rool Fight: Diddy Phase
	OVERLAY_BOSS, // K. Rool Fight: Lanky Phase
	OVERLAY_BOSS, // K. Rool Fight: Tiny Phase
	OVERLAY_BOSS, // K. Rool Fight: Chunky Phase
	OVERLAY_NONE, // Bloopers Ending
	OVERLAY_BONUS, // K. Rool Barrel: Chunky's Hidden Kremling Game
	OVERLAY_BONUS, // K. Rool Barrel: Tiny's Pony Tail Twirl Game
	OVERLAY_BONUS, // K. Rool Barrel: Chunky's Shooting Game
	OVERLAY_BONUS, // K. Rool Barrel: DK's Rambi Game
	OVERLAY_NONE, // K. Lumsy Ending
	OVERLAY_BOSS, // K. Rool's Shoe
	OVERLAY_NONE, // K. Rool's Arena
};

#define UNAFFECTED_HEAD_MODEL -3

const char big_head_actors[MODEL_COUNT] = {
	UNAFFECTED_HEAD_MODEL, // No Model
	0, // Diddy
	0, // Diddy (Instrument)
	0, // Diddy (Low Poly)
	0, // DK
	0, // DK (Low Poly)
	0, // Lanky
	0, // Lanky (Instrument)
	0, // Lanky (Low Poly)
	0, // Tiny
	0, // Tiny (Instrument)
	0, // Tiny (Low Poly)
	0, // Chunky
	0, // Chunky (Instrument)
	0, // Disco Chunky
	0, // Chunky (Low Poly)
	0, // Invisible Chunky
	0, // Cranky
	0, // Funky
	0, // Candy
	0, // Rambi
	UNAFFECTED_HEAD_MODEL, // Snake
	0, // Turtle
	8, // Seal // 0 for butt
	0, // Enguarde
	0, // Beaver (Low Poly)
	0, // Beaver
	0, // Beaver (Gold)
	21, // Zinger // Big ass, 0 for eyes. Polled the easiest person to amuse
	UNAFFECTED_HEAD_MODEL, // Squawks // -1 causes crashes
	0, // Klobber // Might not work properly
	3, // Snide // 0 for hench snide
	0, // Kaboom // might not work properly
	0, // Klaptrap (Green)
	0, // Klaptrap (Purple)
	0, // Klaptrap (Red)
	UNAFFECTED_HEAD_MODEL, // Klaptrap (Teeth)
	UNAFFECTED_HEAD_MODEL, // Mad Jack // Causes him to jump into the ceiling
	1, // Krash
	0, // Troff
	UNAFFECTED_HEAD_MODEL, // Bad Hit Detection Man
	8, // Sir Domino // Right eye
	UNAFFECTED_HEAD_MODEL, // Mr. Dice
	UNAFFECTED_HEAD_MODEL, // Ruler
	0, // Robo-Kremling
	0, // Scoff
	0, // Beetle
	UNAFFECTED_HEAD_MODEL, // Klaptrap (Teeth?)
	UNAFFECTED_HEAD_MODEL, // Nintendo Logo
	0, // Kremling
	0, // Kremling (Red - Kosh)
	0, // Kremling (Green - Kosh)
	5, // Mechanical Fish // Tail Fin
	UNAFFECTED_HEAD_MODEL, // Toy Car
	UNAFFECTED_HEAD_MODEL, // Giant Clam
	0, // Kasplat
	UNAFFECTED_HEAD_MODEL, // Army Dillo // Causes collision issues with the TNT Barrel
	UNAFFECTED_HEAD_MODEL, // Mr. Dice
	0, // Klump
	UNAFFECTED_HEAD_MODEL, // Puftoss // Inconsequential
	UNAFFECTED_HEAD_MODEL, // Dogadon // Makes DDQ super easy
	0, // Banana Fairy
	3, // Llama
	12, // Guard
	2, // Robo-Zinger
	UNAFFECTED_HEAD_MODEL, // Turntable
	0, // Krossbones
	UNAFFECTED_HEAD_MODEL, // Shuri
	UNAFFECTED_HEAD_MODEL, // Gimpfish
	0, // K. Lumsy
	0, // Spider // Technically -1, but causes crashes
	0, // Rabbit
	UNAFFECTED_HEAD_MODEL, // Beanstalk
	0, // K. Rool (Cutscene)
	UNAFFECTED_HEAD_MODEL, // Fireball (With Glasses)
	UNAFFECTED_HEAD_MODEL, // Skeleton Head // 0 for jaw
	UNAFFECTED_HEAD_MODEL, // Skeleton Hand
	0, // Vulture (Race)
	0, // Vulture (Shooting)
	0, // Bat // Jaw
	UNAFFECTED_HEAD_MODEL, // Skull
	18, // Tomato // Jaw
	UNAFFECTED_HEAD_MODEL, // Kritter-in-a-Sheet
	UNAFFECTED_HEAD_MODEL, // Fly
	UNAFFECTED_HEAD_MODEL, // Fly Swatter
	UNAFFECTED_HEAD_MODEL, // Fly Swatter
	0, // Owl
	17, // Book
	UNAFFECTED_HEAD_MODEL, // Ship's Wheel
	UNAFFECTED_HEAD_MODEL, // Spotlight Fish // -1, causes crashes
	0, // Puftup // Jaw
	0, // Mermaid
	15, // Mushroom
	UNAFFECTED_HEAD_MODEL, // Shockwave (Mad Jack)
	UNAFFECTED_HEAD_MODEL, // Squawks // -1, causes crashes
	0, // Worm (apple)
	UNAFFECTED_HEAD_MODEL, // Cuckoo Bird
	0, // Kosha
	18, // Ice Tomato // Jaw
	UNAFFECTED_HEAD_MODEL, // Army Dillo (No Shell)
	UNAFFECTED_HEAD_MODEL, // Boombox
	23, // B. Locker // Right eye
	UNAFFECTED_HEAD_MODEL, // Escape Ship
	UNAFFECTED_HEAD_MODEL, // Army Dillo's Cannon
	0, // K. Rool (Fight)
	UNAFFECTED_HEAD_MODEL, // Golden Banana
	UNAFFECTED_HEAD_MODEL, // Shockwave
	UNAFFECTED_HEAD_MODEL, // K. Rool's Glove
	UNAFFECTED_HEAD_MODEL, // K. Rool's Foot
	UNAFFECTED_HEAD_MODEL, // K. Rool's Toe
	UNAFFECTED_HEAD_MODEL, // K. Rool's Toe
	UNAFFECTED_HEAD_MODEL, // K. Rool's Toe
	UNAFFECTED_HEAD_MODEL, // Microphone // -1, causes crashes
	UNAFFECTED_HEAD_MODEL, // Desk (K. Rool)
	UNAFFECTED_HEAD_MODEL, // Bell
	UNAFFECTED_HEAD_MODEL, // Clapper Board
	UNAFFECTED_HEAD_MODEL, // Cannon
	UNAFFECTED_HEAD_MODEL, // Barrel?
	UNAFFECTED_HEAD_MODEL, // Bonus Barrel
	UNAFFECTED_HEAD_MODEL, // Hunky Chunky Barrel
	UNAFFECTED_HEAD_MODEL, // Mini Monkey Barrel
	UNAFFECTED_HEAD_MODEL, // Barrel
	UNAFFECTED_HEAD_MODEL, // Pushable Box
	UNAFFECTED_HEAD_MODEL, // TNT Barrel Spawner
	UNAFFECTED_HEAD_MODEL, // Cannon
	UNAFFECTED_HEAD_MODEL, // TNT Barrel
	UNAFFECTED_HEAD_MODEL, // Rambi Crate
	UNAFFECTED_HEAD_MODEL, // Enguarde Crate
	UNAFFECTED_HEAD_MODEL, // Chain
	UNAFFECTED_HEAD_MODEL, // Swinging Light
	UNAFFECTED_HEAD_MODEL, // Minecart
	UNAFFECTED_HEAD_MODEL, // Barrel
	UNAFFECTED_HEAD_MODEL, // Bridge (Castle)
	UNAFFECTED_HEAD_MODEL, // Large Brown Bridge
	UNAFFECTED_HEAD_MODEL, // Feather
	UNAFFECTED_HEAD_MODEL, // Laser
	UNAFFECTED_HEAD_MODEL, // Golden Banana (Item Drop)
	UNAFFECTED_HEAD_MODEL, // Rocketbarrel
	UNAFFECTED_HEAD_MODEL, // Strong Kong Barrel
	UNAFFECTED_HEAD_MODEL, // Orangstand Sprint Barrel
	UNAFFECTED_HEAD_MODEL, // Diddy's Jetpack
	UNAFFECTED_HEAD_MODEL, // Photo
	UNAFFECTED_HEAD_MODEL, // Minecart (TNT)
	UNAFFECTED_HEAD_MODEL, // Weird glitch texture (computer screen?)
	UNAFFECTED_HEAD_MODEL, // BBB Slot
	UNAFFECTED_HEAD_MODEL, // BBB Slot
	UNAFFECTED_HEAD_MODEL, // BBB Slot
	UNAFFECTED_HEAD_MODEL, // BBB Slot
	UNAFFECTED_HEAD_MODEL, // BBB Lever
	UNAFFECTED_HEAD_MODEL, // Tiny's Car
	UNAFFECTED_HEAD_MODEL, // Missile
	UNAFFECTED_HEAD_MODEL, // Swinging light
	UNAFFECTED_HEAD_MODEL, // Bananaporter Zipper
	UNAFFECTED_HEAD_MODEL, // Boulder
	UNAFFECTED_HEAD_MODEL, // Vase (O)
	UNAFFECTED_HEAD_MODEL, // Vase (:)
	UNAFFECTED_HEAD_MODEL, // Vase (Triangle)
	UNAFFECTED_HEAD_MODEL, // Vase (+)
	UNAFFECTED_HEAD_MODEL, // Toy Box
	UNAFFECTED_HEAD_MODEL, // Boat
	UNAFFECTED_HEAD_MODEL, // Padlock
	UNAFFECTED_HEAD_MODEL, // Cannon Ball
	UNAFFECTED_HEAD_MODEL, // Vine
	UNAFFECTED_HEAD_MODEL, // Vine
	UNAFFECTED_HEAD_MODEL, // Counter
	UNAFFECTED_HEAD_MODEL, // Key
	UNAFFECTED_HEAD_MODEL, // Bongos
	UNAFFECTED_HEAD_MODEL, // DK Star
	UNAFFECTED_HEAD_MODEL, // Spotlight
	UNAFFECTED_HEAD_MODEL, // Cannon (Seasick Chunky)
	UNAFFECTED_HEAD_MODEL, // Boulder Debris
	UNAFFECTED_HEAD_MODEL, // Spider Web
	UNAFFECTED_HEAD_MODEL, // Steel Keg
	UNAFFECTED_HEAD_MODEL, // Shockwave
	UNAFFECTED_HEAD_MODEL, // Shockwave
	UNAFFECTED_HEAD_MODEL, // Battle Crown
	UNAFFECTED_HEAD_MODEL, // Buoy
	UNAFFECTED_HEAD_MODEL, // Buoy (Green)
	UNAFFECTED_HEAD_MODEL, // Nothing?
	UNAFFECTED_HEAD_MODEL, // DK Banana Counter
	UNAFFECTED_HEAD_MODEL, // Diddy Banana Counter
	UNAFFECTED_HEAD_MODEL, // Tiny Banana Counter
	UNAFFECTED_HEAD_MODEL, // Lanky Banana Counter
	UNAFFECTED_HEAD_MODEL, // Chunky Banana Counter
	UNAFFECTED_HEAD_MODEL, // Shockwave (Green)
	UNAFFECTED_HEAD_MODEL, // Potion
	UNAFFECTED_HEAD_MODEL, // Missile (Army Dillo)
	UNAFFECTED_HEAD_MODEL, // Shockwave (Red)
	UNAFFECTED_HEAD_MODEL, // Ice wall? 
	UNAFFECTED_HEAD_MODEL, // Rareware Logo
	UNAFFECTED_HEAD_MODEL, // Stalactite
	UNAFFECTED_HEAD_MODEL, // Rock Debris
	UNAFFECTED_HEAD_MODEL, // Spotlight (BONUS)
	UNAFFECTED_HEAD_MODEL, // Tag Barrel
	UNAFFECTED_HEAD_MODEL, // Krossbones Head
	UNAFFECTED_HEAD_MODEL, // Lever", -- Gorilla Grab
	UNAFFECTED_HEAD_MODEL, // K. Lumsy's Cage
	UNAFFECTED_HEAD_MODEL, // Freeze Attack
	UNAFFECTED_HEAD_MODEL, // 1 Pad (Diddy 5DI)
	UNAFFECTED_HEAD_MODEL, // 2 Pad (Diddy 5DI)
	UNAFFECTED_HEAD_MODEL, // 3 Pad (Diddy 5DI)
	UNAFFECTED_HEAD_MODEL, // 4 Pad (Diddy 5DI)
	UNAFFECTED_HEAD_MODEL, // 5 Pad (Diddy 5DI)
	UNAFFECTED_HEAD_MODEL, // 6 Pad (Diddy 5DI)
	UNAFFECTED_HEAD_MODEL, // Race Checkpoint
	UNAFFECTED_HEAD_MODEL, // Padlock & Key
	UNAFFECTED_HEAD_MODEL, // Finish Line
	UNAFFECTED_HEAD_MODEL, // Shockwave (Green)
	UNAFFECTED_HEAD_MODEL, // Shockwave (Blue)
	UNAFFECTED_HEAD_MODEL, // Shockwave (Purple)
	UNAFFECTED_HEAD_MODEL, // Question Mark
	UNAFFECTED_HEAD_MODEL, // Flower (Instrument)
	UNAFFECTED_HEAD_MODEL, // DK Logo (Instrument)
	UNAFFECTED_HEAD_MODEL, // Golden Banana
	UNAFFECTED_HEAD_MODEL, // Apple
	UNAFFECTED_HEAD_MODEL, // Barrel
	UNAFFECTED_HEAD_MODEL, // Flag
	UNAFFECTED_HEAD_MODEL, // Flag
	UNAFFECTED_HEAD_MODEL, // Boat
	0, // Krusha (Gun)
	UNAFFECTED_HEAD_MODEL, // King Kut Out Body
	UNAFFECTED_HEAD_MODEL, // King Kut Out Head
	UNAFFECTED_HEAD_MODEL, // King Kut Out Arm
	UNAFFECTED_HEAD_MODEL, // King Kut Out Arm
	UNAFFECTED_HEAD_MODEL, // Rainbow Coin Patch
	UNAFFECTED_HEAD_MODEL, // Rope
	UNAFFECTED_HEAD_MODEL, // DK Smoke Trail
	UNAFFECTED_HEAD_MODEL, // Light (K. Rool fight)
	UNAFFECTED_HEAD_MODEL, // Bonus Barrel (Hideout Helm)
	UNAFFECTED_HEAD_MODEL, // Banana
	UNAFFECTED_HEAD_MODEL, // Banana Barrel
	UNAFFECTED_HEAD_MODEL, // Training Barrel
	UNAFFECTED_HEAD_MODEL, // Pirate Photo
	UNAFFECTED_HEAD_MODEL, // Butterfly
	UNAFFECTED_HEAD_MODEL, // Barrel
	UNAFFECTED_HEAD_MODEL, // Funky's Gun
	UNAFFECTED_HEAD_MODEL, // Boot
};


char* levels[] = {
    "ALL",
    "JUNGLE JAPES",
    "ANGRY AZTEC",
    "FRANTIC FACTORY",
    "GLOOMY GALLEON",
    "FUNGI FOREST",
    "CRYSTAL CAVES",
    "CREEPY CASTLE",
    "DK ISLES",
    "HIDEOUT HELM",
};

overlays getOverlayFromMap(maps map) {
	return overlay_indexes[map];
}

int getBitArrayValue(unsigned char* arr, int value) {
	int offset = value >> 3;
    int check = value % 8;
	return arr[offset] & (0x80 >> check);
}

int inMinigame(maps map) {
	return getBitArrayValue(&minigame_maps_btf, map);
}

int inShop(maps map, int include_snide) {
	return inU8List(map, &shop_maps[0], 3 + include_snide);
}

void playSFX(short sfxIndex) {
	playSound(sfxIndex, 0x7FFF, 63.0f, 1.0f, 0, 0);
}

void setPermFlag(short flagIndex) {
	setFlag(flagIndex,1,FLAGTYPE_PERMANENT);
}

int convertIDToIndex(short obj_index) {
	int _count = ObjectModel2Count;
	int index = -1;
	for (int i = 0; i < _count; i++) {
		if (ObjectModel2Pointer[i].object_id == obj_index) {
			index = i;
			return i;
		}
	}
	return index;
}

int convertSubIDToIndex(short obj_index) {
	int _count = ObjectModel2Count;
	int index = -1;
	for (int i = 0; i < _count; i++) {
		if (ObjectModel2Pointer[i].sub_id == obj_index) {
			index = i;
			return i;
		}
	}
	return index;
}

int isFlagInRange(int test_flag, int start_flag, int count) {
	if (test_flag >= start_flag) {
		return test_flag < (start_flag + count);
	}
	return 0;
}


void* findActorWithType(int search_actor_type) {
	for (int i = 0; i < ActorCount; i++) {
		actorData* _actor_ = (actorData*)ActorArray[i];
		if (_actor_->actorType == search_actor_type) {
			return _actor_;
		}
	}
	return 0;
}

int isRDRAM(void* address) {
	if (((int)address >= 0x80000000) && ((int)address < 0x80800000)) {
		return 1;
	}
	return 0;
}

void createCollisionObjInstance(collision_types subtype, int map, int exit) {
	createCollision(0,Player,subtype,map,exit,collisionPos[0],collisionPos[1],collisionPos[2]);
}

void resetMapContainer(void) {
	resetMap();
	for (int i = 0; i < 0x12; i++) {
		SubmapData[i].slot_populated = 0;
	}
}

static unsigned char vanilla_portal_maps[] = {
	MAP_JAPES,
	MAP_AZTEC,
	MAP_FACTORY,
	MAP_GALLEON,
	MAP_FUNGI,
	MAP_CAVES,
	MAP_CASTLE,
};

void correctDKPortal(void) {
	int exit = DestExit;
	int portal_state = 2;
	if (isLobby(CurrentMap))  {
		if (exit == 1) {
			portal_state = 0;
		}
	} else {
		if ((CurrentMap == MAP_JAPES) && (exit == 15)) {
			portal_state = 0;
		} else if ((CurrentMap == MAP_FUNGI) && (exit == 27)) {
			portal_state = 0;
		} else if ((exit == 0) && (inU8List(CurrentMap, &vanilla_portal_maps, 7))) {
			portal_state = 0;
		} else if (exit == -1) {
			portal_state = 0;
		}
	}		
	int _count = ObjectModel2Count;
	for (int i = 0; i < _count; i++) {
		ModelTwoData* _object = &ObjectModel2Pointer[i];
		if (_object->object_type == 0x2AD) {
			behaviour_data* behav = _object->behaviour_pointer;
			if (behav) {
				behav->current_state = portal_state;
				//behav->next_state = portal_state;
			}
		}
	}
}

int getCenter(int style, char* str) {
	return (screenCenterX + 100 - (getCenterOffset(style,str))) * 0.5f;
}

int getLo(void* addr) {
    return ((int)addr) & 0xFFFF;
}

int getHi(void* addr) {
    int addr_0 = (int)addr;
    int hi = (addr_0 >> 16) & 0xFFFF;
    int lo = getLo(addr);
    if (lo & 0x8000) {
        hi += 1;
    }
    return hi;
}

void cancelCutscene(int enable_movement) {
	if ((TBVoidByte & 2) == 0) {
		if (CutsceneActive) {
			if (CutsceneTypePointer) {
				if (CutsceneTypePointer->cutscene_databank) {
					int* databank = (int *)(CutsceneTypePointer->cutscene_databank);
					short cam_state = *(short *)(getObjectArrayAddr(databank,0xC,CutsceneIndex));
					// short cam_state = *( short*)(cs_databank + (0xC * CutsceneIndex));
					CurrentCameraState = cam_state;
					PreviousCameraState = cam_state;
					CameraStateChangeTimer = 0;
					if ((Player) && (enable_movement)) {
						Player->control_state = 0xC;
					}
				}
			}
		}
	}
}

void modifyCutscenePoint(int bank, int cutscene, int point, int new_item) {
	if (CutsceneBanks[bank].cutscene_databank) {
		void* databank = CutsceneBanks[bank].cutscene_databank;
		cutscene_item_data* data = (cutscene_item_data*)getObjectArrayAddr(databank,0xC,cutscene);
		short* write_spot = (short*)getObjectArrayAddr(data->point_array,2,point);
		*(short*)write_spot = new_item;
	}
}

void modifyCutsceneItem(int bank, int item, int new_param1, int new_param2, int new_param3) {
	if (CutsceneBanks[bank].cutscene_funcbank) {
		void* funcbank = CutsceneBanks[bank].cutscene_funcbank;
		cutscene_item* data = (cutscene_item*)getObjectArrayAddr(funcbank,0x14,item);
		data->command = 0xD;
		data->params[0] = new_param1;
		data->params[1] = new_param2;
		data->params[2] = new_param3;
	}
}

void modifyCutscenePanPoint(int bank, int item, int point_index, int x, int y, int z, int rot0, int rot1, int rot2, int zoom, int roll) {
	if (CutsceneBanks[bank].cutscene_funcbank) {
		cutscene_pan_item* funcbank = (cutscene_pan_item*)CutsceneBanks[bank].cutscene_funcbank;
		cutscene_pan_item* cs_item = (cutscene_pan_item*)&funcbank[item];
		pan_data* data = (pan_data*)&cs_item->pan_content[point_index];
		data->x = x;
		data->y = y;
		data->z = z;
		data->rot_data[0] = rot0;
		data->rot_data[1] = rot1;
		data->rot_data[2] = rot2;
		data->zoom = zoom;
		data->roll = roll;
	}
}

void modifyCutscenePointTime(int bank, int cutscene, int point, int new_time) {
	cutscene_item_data* databank = CutsceneBanks[bank].cutscene_databank;
	cutscene_item_data* data = (cutscene_item_data*)&databank[cutscene];
	if (data) {
		short* write_spot = (short*)&data->length_array[point];
		if (write_spot) {
			*(short*)write_spot = new_time;
		}
	}
}

int getWrinklyLevelIndex(void) {
	return getWorld(CurrentMap, 0);
}

sprite_data_struct bean_sprite = {
	.unk0 = 0xC4,
	.images_per_frame_horizontal = 1,
	.images_per_frame_vertical = 1,
	.codec = RGBA16,
	.unk8 = -1,
	.table = TABLE_25,
	.width = 64,
	.height = 32,
	.image_count = 12,
	.images = {
		BEANSPIN_SPRITE_START + 0,
		BEANSPIN_SPRITE_START + 1,
		BEANSPIN_SPRITE_START + 2,
		BEANSPIN_SPRITE_START + 3,
		BEANSPIN_SPRITE_START + 4,
		BEANSPIN_SPRITE_START + 5,
		BEANSPIN_SPRITE_START + 6,
		BEANSPIN_SPRITE_START + 7,
		BEANSPIN_SPRITE_START + 8,
		BEANSPIN_SPRITE_START + 9,
		BEANSPIN_SPRITE_START + 10,
		BEANSPIN_SPRITE_START + 11,
	},
};

sprite_data_struct pearl_sprite = {
	.unk0 = 0xC5,
	.images_per_frame_horizontal = 1,
	.images_per_frame_vertical = 1,
	.codec = RGBA16,
	.unk8 = -1,
	.table = TABLE_25,
	.width = 32,
	.height = 32,
	.image_count = 1,
	.images = {6021},
};

sprite_data_struct krool_sprite = {
	.unk0 = 0xC6,
	.images_per_frame_horizontal = 2,
	.images_per_frame_vertical = 1,
	.codec = RGBA16,
	.unk8 = -1,
	.table = TABLE_25,
	.width = 32,
	.height = 64,
	.image_count = 2,
	.images = {0x383, 0x384},
};

sprite_data_struct feather_gun_sprite = {
	.unk0 = 0xC7,
	.images_per_frame_horizontal = 1,
	.images_per_frame_vertical = 1,
	.codec = RGBA16,
	.unk8 = -1,
	.table = TABLE_25,
	.width = 32,
	.height = 32,
	.image_count = 8,
	.images = {
		FEATHER_SPRITE_START + 0,
		FEATHER_SPRITE_START + 1,
		FEATHER_SPRITE_START + 2,
		FEATHER_SPRITE_START + 3,
		FEATHER_SPRITE_START + 4,
		FEATHER_SPRITE_START + 5,
		FEATHER_SPRITE_START + 6,
		FEATHER_SPRITE_START + 7,
	},
};

sprite_data_struct fool_overlay_sprite = {
	.unk0 = 0xC8,
	.images_per_frame_horizontal = 1,
	.images_per_frame_vertical = 1,
	.codec = IA8,
	.unk8 = -1,
	.table = TABLE_25,
	.width = 40,
	.height = 16,
	.image_count = 1,
	.images = {
		FOOL_SPRITE_START,
	},
};

sprite_data_struct company_coin_sprite = {
	.unk0 = 0xC9,
	.images_per_frame_horizontal = 1,
	.images_per_frame_vertical = 1,
	.codec = RGBA16,
	.unk8 = -1,
	.table = TABLE_25,
	.width = 44,
	.height = 44,
	.image_count = 16,
	.images = {
		0x170D,
		0x170E,
		0x170F,
		0x1710,
		0x0D48,
		0x1711,
		0x1712,
		0x1713,
		0x1714,
		0x1715,
		0x1716,
		0x1717,
		0x0D49,
		0x1718,
		0x1719,
		0x171A,
	},
};

sprite_data_struct potion_sprite = {
	.unk0 = 0xCA,
	.images_per_frame_horizontal = 1,
	.images_per_frame_vertical = 1,
	.codec = RGBA16,
	.unk8 = -1,
	.table = TABLE_25,
	.width = 44,
	.height = 44,
	.image_count = 9,
	.images = {
		POTIONSPIN_SPRITE_START + 0,
		POTIONSPIN_SPRITE_START + 1,
		POTIONSPIN_SPRITE_START + 2,
		POTIONSPIN_SPRITE_START + 3,
		POTIONSPIN_SPRITE_START + 4,
		POTIONSPIN_SPRITE_START + 5,
		POTIONSPIN_SPRITE_START + 6,
		POTIONSPIN_SPRITE_START + 7,
		POTIONSPIN_SPRITE_START + 8,
	},
};

void giveGB() {
	changeCollectableCount(8, 0, 1);
	displayItemOnHUD(8, 0, 0);
}

int getTotalCBCount(void) {
	int world = getWorld(CurrentMap,1);
	int count = 0;
	if (world < 8) {
		for (int kong = 0; kong < 5; kong++) {
			count += MovesBase[kong].cb_count[world] + MovesBase[kong].tns_cb_count[world];
		}
	}
	return count;
}

void giveAmmo(void) {
	changeCollectableCount(2, 0, 5);
}

void giveOrange(void) {
	playSound(0x147, 0x7FFF, 63.0f, 1.0f, 5, 0);
	changeCollectableCount(4, 0, 1);
}

void giveMelon(void) {
	applyDamageMask(0, 1);
}

int inShortList(int target, short* list, int count) {
	for (int i = 0; i < count; i++) {
		if (list[i] == target) {
			return i + 1;
		}
	}
	return 0;
}

int inU8List(int target, unsigned char* list, int count) {
	for (int i = 0; i < count; i++) {
		if (list[i] == target) {
			return i + 1;
		}
	}
	return 0;
}

void giveCrystal(void) {
	changeCollectableCount(5, 0, 150);
}

move_text_overlay_struct text_overlay_data[TEXT_OVERLAY_BUFFER] = {};

int spawnItemOverlay(requirement_item type, int level, int kong, int force) {
	for (int i = 0; i < TEXT_OVERLAY_BUFFER; i++) {
		if (text_overlay_data[i].used) {
			continue;
		}
		if (force) {
			spawnActor(NEWACTOR_JETPACITEMOVERLAY, 0);
		} else {
			spawnActor(324,0);
		}
		move_overlay_paad * ovl_paad = LastSpawnedActor->paad;
		ovl_paad->index = i;
		text_overlay_data[i].type = type;
		text_overlay_data[i].level = level;
		text_overlay_data[i].kong = kong;
		text_overlay_data[i].string = (char*)0;
		text_overlay_data[i].subtitle = (char*)0;
		text_overlay_data[i].used = 1;
		return i;
	}
	return -1;
}

int giveSlamLevel(void) {
	int level = MovesBase[0].simian_slam;
	if (level < 3) {
		for (int i = 0; i < 5; i++) {
			MovesBase[i].simian_slam = level + 1;
		}
		return level + 1;
	}
	return 3;
}

int inBattleCrown(maps map) {
	if (map == MAP_BATTLEARENA_BEAVERBRAWL) {
		return 1;
	} else if (map == MAP_BATTLEARENA_KRITTERKARNAGE) {
		return 1;
	}
	return (map >= MAP_BATTLEARENA_ARENAAMBUSH) && (map <= MAP_BATTLEARENA_SHOCKWAVESHOWDOWN);
}

int inTraining(maps map) {
	for (int i = 0; i < sizeof(training_maps); i++) {
		if (map == training_maps[i]) {
			return 1;
		}
	}
	return 0;
}

int inBossMap(maps map, int include_regular, int include_krool, int include_shoe) {
	if (include_regular) {
		for (int i = 0; i < 7; i++) {
			if (regular_boss_maps[i] == map) {
				return 1;
			}
		}
	}
	if (include_krool) {
		if ((map >= MAP_KROOLDK) && (map <= MAP_KROOLCHUNKY)) {
			return 1;
		}
	}
	if (include_shoe) {
		return map == MAP_KROOLSHOE;
	}
	return 0;
}

int isGamemode(gamemodes target_mode, int force_both) {
	if (force_both) {
		if ((Gamemode == target_mode) && (Mode == target_mode)) {
			return 1;
		}
		return 0;
	}
	if (Gamemode == target_mode) {
		return 1;
	}
	return Mode == target_mode;
}

int filterSong(int* song_write) {
	int song = *song_write;
	if ((Rando.disabled_music.events) || (Rando.disabled_music.shops)) {
		if (Rando.disabled_music.events) {
			if (music_types[song] == SONGTYPE_EVENT) {
				*song_write = 0;
				song = 0;
			}
		}
		if (Rando.disabled_music.shops) {
			if (
				((song == SONG_CRANKY) && (CurrentMap == MAP_CRANKY)) || // Cranky
				((song == SONG_FUNKY) && (CurrentMap == MAP_FUNKY)) || // Funky
				((song == SONG_CANDY) && (CurrentMap == MAP_CANDY)) || // Candy
				((song == SONG_SNIDE) && (CurrentMap == MAP_SNIDE)) // Snide
			) {
				*song_write = 0;
				song = 0;
			}
		}
	}
	return getTrackChannel(song);
}

static unsigned char galleon_underwater_maps[] = {
	MAP_GALLEON2DS,
	MAP_GALLEON5DSDIDDYLANKYCHUNKY,
	MAP_GALLEON5DSDKTINY,
	MAP_GALLEONMECHFISH,
	MAP_GALLEONMERMAID,
	MAP_GALLEONSUBMARINE,
	MAP_GALLEONTREASURECHEST,
};

void death(void) {
	sendDeath();
	GameStats[STAT_DEATHS]++;
}

int applyDamageMask(int player_index, int damage) {
	int applied_multiplier = Rando.damage_multiplier;
	int init_health = CollectableBase.Health;
	if ((damage > 0) || (damage <= -12)) {
		// Health or death-dealing damage
		if (damage <= -12) {
			death();
		}
		return applyDamage(player_index, damage);
	}
	if ((CurrentMap == MAP_CASTLEKUTOUT) && (CutsceneActive == 1) && (CutsceneIndex == 4)) {
		// King Kut out death cutscene, force to 0
		applied_multiplier = 0;
	} else if (Rando.hard_mode.lava_water) {
		if (Player->grounded_bitfield & 4) {
			// Underwater
			applied_multiplier = 1;
			if (inU8List(CurrentMap, &galleon_underwater_maps, sizeof(galleon_underwater_maps))) {
				applied_multiplier = 0;
			}
		}
	}
	int applied_damage = damage * applied_multiplier;
	if ((init_health + applied_damage) <= 0) {
		death();
	}
	return applyDamage(player_index, applied_damage);
}

void* replaceWaterTexture(int table, int file, int unk0, int unk1) {
	if (file == 0xCF) {
		return getMapData(7, 0x3BA, unk0, unk1);
	}
	return getMapData(table, file, unk0, unk1);
}

void* replaceWaterTexture_spooky(int table, int file, int unk0, int unk1) {
	if (file == 0xCF) {
		return getMapData(7, 0x3D2, unk0, unk1);
	}
	return getMapData(table, file, unk0, unk1);
}

int isBounceObject(int object) {
	return inShortList(object, (short*)&bounce_objects[0], sizeof(bounce_objects) >> 1);
}

void* getFile(int size, int rom) {
	/**
	 * @brief Get file from ROM
	 */
	void* loc = dk_malloc(size);
	copyFromROM(rom,loc,&size,0,0,0,0);
	return loc;
}

static float percentage_rewards[] = {
	0.4f, // GBs
	0.5f, // Crowns
	0.25f, // Keys
	0.2f, // Medals
	0.5f, // RW Coins
	0.2f, // Fairies
	0.5f, // Nintendo Coins
};

static unsigned char reward_cap[] = {
	201, // GBs
	10, // Crowns
	8, // Keys
	40, // Medals
	1, // RW Coin
	20, // Fairies
	1, // Nintendo Coin
};

float getPercentageOfItem(int index, float percentage_per_item, int cap) {
	int count = FileVariables[index];
	if (count > cap) {
		count = cap;
	}
	float i_f = count;
	return i_f * percentage_per_item;
}

int getGamePercentage(void) {
	// This is a slightly modified version of the vanilla function
	updateFilePercentage();
	float percentage = 0;
	float target = 100.4f;
	for (int i = 0; i < 7; i++) {
		percentage += getPercentageOfItem(i, percentage_rewards[i], reward_cap[i]);
	}
	if (percentage == target) {
		return 101;
	}
	return percentage;
}

int getTotalMoveCount(void) {
	int count = MovesBase[0].simian_slam + MovesBase[0].ammo_belt;
	for (int kong = 0; kong < 5; kong++) {
		for (int i = 0; i < 3; i++) {
			if (MovesBase[kong].special_moves & (1 << i)) {
				count += 1;
			}
		}
		if (MovesBase[kong].weapon_bitfield & 1) {
			count += 1;
		}
		if (MovesBase[kong].instrument_bitfield & 1) {
			count += 1;
		}
	}
	for (int i = 0; i < 4; i++) {
		if (hasFlagMove(tbarrel_flags[i])) {
			count += 1;
		}
		if (i > 0) {
			if (MovesBase[0].weapon_bitfield & (1 << i)) {
				count += 1;
			}
			if (MovesBase[0].instrument_bitfield & (1 << i)) {
				count += 1;
			}
		}
		if (i < 2) {
			if (hasFlagMove(bfi_move_flags[i])) {
				count += 1;
			}
		}
	}
	if (hasFlagMove(FLAG_ABILITY_CLIMBING)) {
		count++;
	}
	return count;
}

unsigned int cs_skip_db[2] = {0, 0};
static unsigned char unused_bonus_ids[] = {2, 29, 30, 32, 34, 35, 38, 41, 42, 52};
static unsigned char use_req_counters[] = {
	REQITEM_COMPANYCOIN,
	REQITEM_MEDAL,
	REQITEM_KONG,
	REQITEM_BLUEPRINT,
	REQITEM_FAIRY,
	REQITEM_CROWN,
	REQITEM_RAINBOWCOIN,
	REQITEM_BEAN,
	REQITEM_PEARL,
	REQITEM_ICETRAP,
	REQITEM_KEY,
	REQITEM_RACECOIN,
};

int getItemCountReq(requirement_item item) {
	int count = 0;
	if (inU8List(item, &use_req_counters, sizeof(use_req_counters))) {
		return getItemCount_new(item, -1, -1);
	}
	switch(item) {
		case REQITEM_MOVE:
			return getTotalMoveCount();
		case REQITEM_GOLDENBANANA:
			return getTotalGBs();
		case REQITEM_GAMEPERCENTAGE:
			return getGamePercentage();
		case REQITEM_COLOREDBANANA:
			for (int world = 0; world < 8; world++) {
				for (int kong = 0; kong < 5; kong++) {
					count += MovesBase[kong].cb_count[world] + MovesBase[kong].tns_cb_count[world];
				}
			}
			return count;
		case REQITEM_BOSSES:
			for (int i = 0; i < 7; i++) {
				if (checkFlag(normal_key_flags[i], FLAGTYPE_PERMANENT)) {
					count += 1;
				}
			}
			return count;
		case REQITEM_BONUSES:
			for (int i = 1; i < 54; i++) {
				if (!inU8List(i, &unused_bonus_ids, sizeof(unused_bonus_ids))) {
					if (checkFlag(bonus_data[i].flag, FLAGTYPE_PERMANENT)) {
						count += 1;
					}
				}
			}
			for (int i = 0; i < 10; i++) {
				if (checkFlag(FLAG_HELM_MINIGAMES + i, FLAGTYPE_PERMANENT)) {
					count += 1;
				}
			}
			return count;
		default:
			return 0;
	}
	return 0;
}

int isItemRequirementSatisfied(ItemRequirement* req) {
	if (req->item == REQITEM_NONE) {
		return 1;
	}
	return getItemCountReq(req->item) >= req->count;
}

purchase_struct* getShopData(vendors vendor, int kong, int level) {
	if (vendor == SHOP_CRANKY) {
		return &CrankyMoves_New[kong][level];
	}
	if (vendor == SHOP_FUNKY) {
		return &FunkyMoves_New[kong][level];
	}
	if (vendor == SHOP_CANDY) {
		return &CandyMoves_New[kong][level];
	}
	return 0;
}

void exitBoss(void) {
	maps reference_map = CurrentMap;
	if (reference_map == MAP_KROOLSHOE) {
		reference_map = MAP_KROOLTINY;
	}
	for (int i = 0; i < 5; i++) {
		if (Rando.k_rool_order[i] == reference_map) {
			initiateTransition(MAP_ISLES, 0xC);
			return;
		}
	}
	initiateTransition(MAP_TROFFNSCOFF, 2);
}

static const unsigned char krusha_adj_models[] = {KONGMODEL_KRUSHA, KONGMODEL_KROOL_CUTSCENE, KONGMODEL_KROOL_FIGHT};
int isKrushaAdjacentModel(int kong) {
	custom_kong_models slot_value = Rando.kong_models[kong];
	return inU8List(slot_value, &krusha_adj_models, 3);
}

int isGlobalCutscenePlaying(int cutscene_index) {
	if (CutsceneActive != 1) {
		return 0;
	}
	if (CutsceneIndex != cutscene_index) {
		return 0;
	}
	if ((CutsceneStateBitfield & 4) != 0) {
		return 1;
	}
	return 0;
}

int DetermineLevel_NewLevel(maps map) {
	for (int i = 0; i < 8; i++) {
		if (CurrentMap == LobbiesArray[i]) {
			if (!checkFlag(FLAG_STORY_JAPES + i, FLAGTYPE_PERMANENT)) {
				setPermFlag(FLAG_STORY_JAPES + i);
				if (StorySkip) {
					return 0;
				}
				int world = getWorld(map, 0);
				if (world == 8) {
					world = 7;
				} else if (world > 6) {
					return 0;
				}
				initiateTransitionFade(MAP_HELM_INTROSGAMEOVER, 0xF + world, Mode);
				return 1;
			}
		}
	}
	return 0;
}

void refillIfRefillable(item_ids item_id, int player, int change) {
	int cap = getRefillCount(item_id, player);
	int count = getItemCount(item_id, player);
	if (count < cap) {
		changeCollectableCount(item_id, player, change);
	}
}

void refillHealthOnInit(void) {
	initCharSpawnerActor();
	if (CurrentActorPointer_0->obj_props_bitfield & 0x10) {
		return;
	}
	refillHealth(0);
}

void refillPlayerHealthKKO(void* actor, int cutscene, int bitfield) {
	playCutscene(actor, cutscene, bitfield);
	refillHealth(0);
}

static short dynflag_items[] = {
	0x00A,
	0x00D,
	0x016,
	0x01C,
	0x01D,
	0x01E,
	0x01F,
	0x023,
	0x024,
	0x027,
	0x02B,
	0x205,
	0x206,
	0x207,
	0x208,
};

int isDynFlag(int obj, maps map) {
	if (inShortList(obj, &dynflag_items, 15)) {
		return 1;
	}
	if (Rando.race_coins_shuffled) {
		if (obj == 236) {
			if (levelIndexMapping[map] != LEVEL_BONUS) {
				return 1;
			}
		}
	}
	return 0;
}

int getProjectileCount_modified(void *player, unsigned short int_bitfield, void* code) {
	int count = 0;
	int longest_life = ActorTimer - 50; // Has to be at least 50f old
	void *actor_oldest = 0;
	for (int i = 0; i < LoadedActorCount; i++) {
		actorData *actor = LoadedActorArray[i].actor;
		if (player == actor->parent) {
			if (actor->interaction_bitfield == int_bitfield) {
				if ((!code) || callFunc(code, actor)) {
					count += 1;
					int *paad = actor->paad;
					if (paad) {
						if (*paad < longest_life) {
							longest_life = *paad;
							actor_oldest = actor;
						}
					}
				}
			}
		}
	}
	if (count == 4) {
		if (actor_oldest) {
			deleteActorContainer(actor_oldest);
			return 3;
		}
	}
	return count;
}

unsigned short enabled_buttons = 0xFFFF;
unsigned short cc_enabled_buttons = 0xFFFF;
unsigned short trap_enabled_buttons = 0xFFFF;

void applyButtonBansInternals(void *cont) {
	getControllerContainer(cont);
	enabled_buttons = ButtonsEnabledBitfield & cc_enabled_buttons & trap_enabled_buttons;
}
