//===========================================================================

// 

// |cff1ce6b9MaxEscapeCreation v1.0

// 

//   Warcraft III map script

//   Generated by the Warcraft III World Editor

//   Date: Sat Jul 21 20:40:29 2012

//   Map Author: Maximaxou

// 

//===========================================================================



//***************************************************************************

//*

//*  Global Variables

//*

//***************************************************************************



globals

    // User-defined

    boolean array           udg_has_max_name

    boolean                 udg_tripleKillSoundOn      = false

    gamecache               udg_cheatCache             = null

    integer array           udg_used_terrain_types

    integer                 udg_nb_used_terrains       = 0

    boolean                 udg_cheatsUsed             = false

    boolean                 udg_areRedRightsOn         = false

    boolean array           udg_is_circleing_j

    real array              udg_loc_x

    real array              udg_loc_y

    unit array              udg_hero_j

    integer                 udg_terrain_slide          = 0

    handle                  udg_handle                 = null

    real                    udg_x                      = 0



    // Generated

    rect                    gg_rct_departLvl_0         = null

    sound                   gg_snd_noob                = null

    sound                   gg_snd_multisquish         = null

    sound                   gg_snd_questCompleted      = null

    sound                   gg_snd_questFailed         = null

    sound                   gg_snd_goodJob             = null

    sound                   gg_snd_warning             = null

    sound                   gg_snd_start               = null

    trigger                 gg_trg_Constants           = null

    trigger                 gg_trg_Text                = null

    trigger                 gg_trg_Init_terrain_limit_variables = null

    trigger                 gg_trg_Init_colorCodes     = null

    trigger                 gg_trg_Basic_functions     = null

    trigger                 gg_trg_Functions_on_numbers = null

    trigger                 gg_trg_Ascii               = null

    trigger                 gg_trg_Decode_string       = null

    trigger                 gg_trg_View_all_hide_all   = null

    trigger                 gg_trg_Immolation_skills   = null

    trigger                 gg_trg_MonsterType         = null

    trigger                 gg_trg_MonsterTypeArray    = null

    trigger                 gg_trg_Monster_creation_functions = null

    trigger                 gg_trg_MonsterInterface    = null

    trigger                 gg_trg____trig_Monsters_clickable_set_life = null

    trigger                 gg_trg_MonsterNoMove       = null

    trigger                 gg_trg_MonsterNoMoveArray  = null

    trigger                 gg_trg_MonsterSimplePatrol = null

    trigger                 gg_trg_MonsterSimplePatrolArray = null

    trigger                 gg_trg_MonsterMultiplePatrols = null

    trigger                 gg_trg_MonsterMultiplePatrolsArray = null

    trigger                 gg_trg_MonsterSpawn        = null

    trigger                 gg_trg_MonsterSpawnArray   = null

    trigger                 gg_trg_Terrain_type_functions = null

    trigger                 gg_trg_TerrainType         = null

    trigger                 gg_trg_TerrainTypeWalk     = null

    trigger                 gg_trg_TerrainTypeDeath_functions = null

    trigger                 gg_trg_TerrainTypeDeath_KillingTimers = null

    trigger                 gg_trg_TerrainTypeDeath    = null

    trigger                 gg_trg_TerrainTypeSlide    = null

    trigger                 gg_trg_TerrainTypeArray    = null

    trigger                 gg_trg_Time_of_game_trigger = null

    trigger                 gg_trg_Lives_and_game_time = null

    trigger                 gg_trg_Meteor              = null

    trigger                 gg_trg_MeteorArray         = null

    trigger                 gg_trg_Meteor_functions    = null

    trigger                 gg_trg_Right_click_on_widget = null

    trigger                 gg_trg_Meteor_being_used   = null

    trigger                 gg_trg_Stop_using_normal_meteor = null

    trigger                 gg_trg_Effect_meteor_on_pick_up = null

    trigger                 gg_trg_VisibilityModifier  = null

    trigger                 gg_trg_VisibilityModifierArray = null

    trigger                 gg_trg_StartAndEnd         = null

    trigger                 gg_trg_Triggers            = null

    trigger                 gg_trg_Level               = null

    trigger                 gg_trg____Level_functions  = null

    trigger                 gg_trg____Trig_checkpoint_revive_heroes = null

    trigger                 gg_trg_LevelArray          = null

    trigger                 gg_trg_EscaperEffect_functions = null

    trigger                 gg_trg_EscaperEffect       = null

    trigger                 gg_trg_EscaperEffectArray  = null

    trigger                 gg_trg_Escaper_functions   = null

    trigger                 gg_trg_Escaper_disco       = null

    trigger                 gg_trg_Escaper             = null

    trigger                 gg_trg_EscaperArray        = null

    trigger                 gg_trg_EscaperSavedCommands = null

    trigger                 gg_trg_Make                = null

    trigger                 gg_trg_Monster_making_no_move_Actions = null

    trigger                 gg_trg_MakeMonsterNoMove   = null

    trigger                 gg_trg_Monster_making_simple_patrol_Actions = null

    trigger                 gg_trg_MakeMonsterSimplePatrol = null

    trigger                 gg_trg_Monster_making_multiple_patrols_Actions = null

    trigger                 gg_trg_MakeMonsterMultiplePatrols = null

    trigger                 gg_trg_Monster_spawn_making_Actions = null

    trigger                 gg_trg_MakeMonsterSpawn    = null

    trigger                 gg_trg_Monster_delete_Actions = null

    trigger                 gg_trg_MakeDeleteMonsters  = null

    trigger                 gg_trg_Meteor_making_Actions = null

    trigger                 gg_trg_MakeMeteor          = null

    trigger                 gg_trg_Meteor_delete_Actions = null

    trigger                 gg_trg_MakeDeleteMeteors   = null

    trigger                 gg_trg_Terrain_making_Actions = null

    trigger                 gg_trg_MakeTerrainCreate   = null

    trigger                 gg_trg_Terrain_copy_paste_Actions = null

    trigger                 gg_trg_MakeTerrainCopyPaste = null

    trigger                 gg_trg_Terrain_vertical_symmetry_Actions = null

    trigger                 gg_trg_MakeTerrainVerticalSymmetry = null

    trigger                 gg_trg_Terrain_horizontal_symmetry_Actions = null

    trigger                 gg_trg_MakeTerrainHorizontalSymmetry = null

    trigger                 gg_trg_Make_exchange_terrains_Actions = null

    trigger                 gg_trg_MakeExchangeTerrains = null

    trigger                 gg_trg_Start_making_Actions = null

    trigger                 gg_trg_MakeStart           = null

    trigger                 gg_trg_End_making_Actions  = null

    trigger                 gg_trg_MakeEnd             = null

    trigger                 gg_trg_VisibilityModifier_making_Actions = null

    trigger                 gg_trg_MakeVisibilityModifier = null

    trigger                 gg_trg_Getting_terrain_type_info_Actions = null

    trigger                 gg_trg_MakeGetTerrainType  = null

    trigger                 gg_trg_MakeAction          = null

    trigger                 gg_trg_MakeMonsterAction   = null

    trigger                 gg_trg_MakeDeleteMonstersAction = null

    trigger                 gg_trg_MakeMeteorAction    = null

    trigger                 gg_trg_MakeDeleteMeteorsAction = null

    trigger                 gg_trg_MakeTerrainCreateAction = null

    trigger                 gg_trg_MakeTerrainCopyPasteAction = null

    trigger                 gg_trg_MakeTerrainVerticalSymmetryAction = null

    trigger                 gg_trg_MakeTerrainHorizontalSymmetryAction = null

    trigger                 gg_trg_MakeVisibilityModifierAction = null

    trigger                 gg_trg_MakeLastActions     = null

    trigger                 gg_trg_Command_functions   = null

    trigger                 gg_trg_Teleport_once_only  = null

    trigger                 gg_trg_Teleport            = null

    trigger                 gg_trg_Autorevive          = null

    trigger                 gg_trg_Command_all         = null

    trigger                 gg_trg_Command_red         = null

    trigger                 gg_trg_Command_cheat       = null

    trigger                 gg_trg_Command_make        = null

    trigger                 gg_trg_Command_max         = null

    trigger                 gg_trg_Command_true_max    = null

    trigger                 gg_trg_Command_execution   = null

    trigger                 gg_trg_Slide               = null

    trigger                 gg_trg_To_turn_on_slide    = null

    trigger                 gg_trg_Auto_continue_after_sliding = null

    trigger                 gg_trg_CheckTerrain        = null

    trigger                 gg_trg_All_terrain_functions = null

    trigger                 gg_trg_Terrain_type_ascii_conversion = null

    trigger                 gg_trg_Terrain_type_max    = null

    trigger                 gg_trg_Terrain_type_grass  = null

    trigger                 gg_trg_Terrain_type_names_and_data = null

    trigger                 gg_trg_Terrain_functions   = null

    trigger                 gg_trg_Terrain_data_search = null

    trigger                 gg_trg_Terrain_type_from_string = null

    trigger                 gg_trg_Modify_terrain_functions = null

    trigger                 gg_trg_Terrain_modifying_trig = null

    trigger                 gg_trg_Change_one_terrain  = null

    trigger                 gg_trg_Change_all_terrains = null

    trigger                 gg_trg_Exchange_terrains   = null

    trigger                 gg_trg_Randomize_terrains  = null

    trigger                 gg_trg_Reinit_terrains     = null

    trigger                 gg_trg_Reinit_terrains_position_Change_variations_and_ut_at_beginning = null

    trigger                 gg_trg_Save_load_terrain_without_name = null

    trigger                 gg_trg_Save_load_terrain_with_name = null

    trigger                 gg_trg_struct_StringArrayForCache = null

    trigger                 gg_trg_Save_terrain_config = null

    trigger                 gg_trg_Save_terrain        = null

    trigger                 gg_trg_Save_monster_types  = null

    trigger                 gg_trg_Save_levels         = null

    trigger                 gg_trg_SAVE_MAP_in_cache   = null

    trigger                 gg_trg_Init_lives          = null

    trigger                 gg_trg_Init_escapers       = null

    trigger                 gg_trg_Init_struct_levels  = null

    trigger                 gg_trg_Forces_ally         = null

    trigger                 gg_trg_Camera              = null

    trigger                 gg_trg_No_selection_circle = null

    trigger                 gg_trg_Allways_day         = null

    trigger                 gg_trg_Start_sound         = null

    trigger                 gg_trg_Heroes              = null

    trigger                 gg_trg_Heroes_for_test     = null

    trigger                 gg_trg_Command_shortcuts_functions = null

    trigger                 gg_trg_Using_shortcut      = null

    trigger                 gg_trg_Camera_reset        = null

    trigger                 gg_trg_Apm                 = null

    trigger                 gg_trg_Afk_mode            = null

    trigger                 gg_trg_Afk_mode_ordre_recu = null

    trigger                 gg_trg_A_player_leaves     = null

    trigger                 gg_trg_InvisUnit_is_getting_damage = null

    trigger                 gg_trg_A_hero_dies_check_if_all_dead_and_sounds = null

    trigger                 gg_trg_Lose_a_life_and_res = null

    trigger                 gg_trg_Sound_monster_dies  = null

    trigger                 gg_trg_Giving_making_rights = null

    trigger                 gg_trg_Welcome_message     = null

    trigger                 gg_trg_Commands_1          = null

    trigger                 gg_trg_Commands_2          = null

    trigger                 gg_trg_Colors              = null

    trigger                 gg_trg_Effects             = null

    trigger                 gg_trg_Red_commands        = null

    trigger                 gg_trg_Map_description     = null

    trigger                 gg_trg_Contact             = null

    trigger                 gg_trg_Command_shortcuts   = null

    trigger                 gg_trg_Adding_quests       = null

    trigger                 gg_trg_Antisave            = null

    trigger                 gg_trg_Antisave_warning    = null

    trigger                 gg_trg_Init_terrain_types  = null

    trigger                 gg_trg_Init_monster_types  = null

    trigger                 gg_trg_Init_levels         = null

endglobals



function InitGlobals takes nothing returns nothing

    local integer i = 0

    set i = 0

    loop

        exitwhen (i > 12)

        set udg_has_max_name[i] = false

        set i = i + 1

    endloop



    set udg_tripleKillSoundOn = true

    set i = 0

    loop

        exitwhen (i > 20)

        set udg_used_terrain_types[i] = 0

        set i = i + 1

    endloop



    set udg_nb_used_terrains = 0

    set udg_cheatsUsed = false

    set udg_areRedRightsOn = true

    set i = 0

    loop

        exitwhen (i > 1)

        set udg_is_circleing_j[i] = false

        set i = i + 1

    endloop



    set i = 0

    loop

        exitwhen (i > 1)

        set udg_loc_x[i] = 0

        set i = i + 1

    endloop



    set i = 0

    loop

        exitwhen (i > 1)

        set udg_loc_y[i] = 0

        set i = i + 1

    endloop



    set udg_terrain_slide = 0

    set udg_x = 0

endfunction



//***************************************************************************

//*

//*  Sounds

//*

//***************************************************************************



function InitSounds takes nothing returns nothing

    set gg_snd_noob = CreateSound( "war3mapImported\\Noob.wav", false, false, false, 10, 10, "DefaultEAXON" )

    call SetSoundDuration( gg_snd_noob, 1022 )

    call SetSoundChannel( gg_snd_noob, 0 )

    call SetSoundVolume( gg_snd_noob, 127 )

    call SetSoundPitch( gg_snd_noob, 1.0 )

    set gg_snd_multisquish = CreateSound( "war3mapImported\\triple_kill.wav", false, false, false, 10, 10, "DefaultEAXON" )

    call SetSoundDuration( gg_snd_multisquish, 1828 )

    call SetSoundChannel( gg_snd_multisquish, 0 )

    call SetSoundVolume( gg_snd_multisquish, 127 )

    call SetSoundPitch( gg_snd_multisquish, 1.0 )

    set gg_snd_questCompleted = CreateSound( "Sound\\Interface\\QuestCompleted.wav", false, false, false, 10, 10, "DefaultEAXON" )

    call SetSoundParamsFromLabel( gg_snd_questCompleted, "QuestCompleted" )

    call SetSoundDuration( gg_snd_questCompleted, 5155 )

    set gg_snd_questFailed = CreateSound( "Sound\\Interface\\QuestFailed.wav", false, false, false, 10, 10, "DefaultEAXON" )

    call SetSoundParamsFromLabel( gg_snd_questFailed, "QuestFailed" )

    call SetSoundDuration( gg_snd_questFailed, 4690 )

    set gg_snd_goodJob = CreateSound( "Sound\\Interface\\GoodJob.wav", false, false, false, 10, 10, "DefaultEAXON" )

    call SetSoundParamsFromLabel( gg_snd_goodJob, "GoodJob" )

    call SetSoundDuration( gg_snd_goodJob, 2548 )

    set gg_snd_warning = CreateSound( "Sound\\Interface\\Warning.wav", false, false, false, 10, 10, "DefaultEAXON" )

    call SetSoundParamsFromLabel( gg_snd_warning, "Warning" )

    call SetSoundDuration( gg_snd_warning, 1904 )

    set gg_snd_start = CreateSound( "Sound\\Interface\\NewTournament.wav", false, false, false, 10, 10, "DefaultEAXON" )

    call SetSoundParamsFromLabel( gg_snd_start, "NewTournament" )

    call SetSoundDuration( gg_snd_start, 7988 )

endfunction



//***************************************************************************

//*

//*  Regions

//*

//***************************************************************************



function CreateRegions takes nothing returns nothing

    local weathereffect we



    set gg_rct_departLvl_0 = Rect( -224.0, -320.0, 96.0, -64.0 )

endfunction



//***************************************************************************

//*

//*  Custom Script Code

//*

//***************************************************************************

//TESH.scrollpos=0

//TESH.alwaysfold=0



//***************************************************************************

//*

//*  Triggers

//*

//***************************************************************************



//===========================================================================

// Trigger: Constants

//===========================================================================

//TESH.scrollpos=26

//TESH.alwaysfold=0

globals

    real MAP_MIN_X

    real MAP_MAX_X

    real MAP_MIN_Y

    real MAP_MAX_Y



	constant integer INVIS_UNIT_TYPE_ID = 'Einv' 

    constant integer HERO_TYPE_ID = 'E000'

    

	constant integer HERO_WALK_SPEED = 522

    

    constant real MAX_MOVE_SPEED = 522

    

    

    constant integer DEFAULT_MONSTER_SPEED = 400

    

	constant real HERO_SLIDE_SPEED = 550

	constant real SLIDE_PERIOD = 0.015

	constant real CHECK_TERRAIN_PERIOD = 0.05

    constant real LOW_PERIOD_FOR_WORK = 0.0001

    

    

    constant integer CRITICAL_LIVES_LIMIT = 2 //s'il y a au plus ce nombre de vies, on affiche les vies en rouge

    

    constant integer DEFAULT_CAMERA_FIELD = 2500

    

    

    constant integer LIMIT_NB_HERO_EFFECTS = 20

    

    

    constant integer PATROL_DISTANCE_MIN = 100

    

    

    constant integer MAX_NB_MONSTERS_BY_LEVEL = 1000

    

    

    constant real LARGEUR_CASE = 128

    

    

    constant real TERRAIN_DEATH_TIME_TO_KILL = 2

    

    

	constant player ENNEMY_PLAYER = Player(PLAYER_NEUTRAL_AGGRESSIVE)

	constant player NEUTRAL_PLAYER = Player(PLAYER_NEUTRAL_PASSIVE)

    

    

    constant player PLAYER_INVIS_UNIT = Player(12)

    

    

    constant string GM_TOUCH_DEATH_TERRAIN_EFFECT_STR = "Abilities\\Spells\\NightElf\\Blink\\BlinkCaster.mdl"

    constant string GM_KILLING_EFFECT = "Abilities\\Spells\\NightElf\\Blink\\BlinkCaster.mdl"

    constant string TERRAIN_KILL_EFFECT_BODY_PART = "origin"

    

    constant integer NB_MAX_OF_TERRAINS = 16

    constant real TERRAIN_DATA_DISPLAY_TIME = 15

    constant integer NB_MAX_TERRAIN_DATA_DISPLAY = 16

    constant integer NB_MAX_TILES_MODIFIED = 1000

    

    constant integer NB_LIVES_AT_BEGINNING = 5

    

    constant integer RED = 0

    constant integer BLUE = 1

    constant integer TEAL = 2

    constant integer PURPLE = 3

    constant integer YELLOW = 4

    constant integer ORANGE = 5

    constant integer GREEN = 6

    constant integer PINK = 7

    constant integer GREY = 8

    constant integer LIGHTBLUE = 9

    constant integer DARKGREEN = 10

    constant integer BROWN = 11

endglobals//===========================================================================

// Trigger: Text

//

// 58 lignes

//===========================================================================

//TESH.scrollpos=57

//TESH.alwaysfold=0

library Text







globals

    private constant string NORMAL_TEXT_COLORCODE = "|c00ffffff" //blanc

    private constant string MAKE_TEXT_COLORCODE = "|c00ffff00" //jaune

    private constant string ERROR_TEXT_COLORCODE = "|c00960000" //sorte de rouge foncé

    

    public boolean enabled = true

    public real posX = 0

    public real posY = 0.4

endglobals





private function ForPlayer_timed_withColorCode takes player p, real duration, string colorcode, string message returns boolean

    if (not enabled) then

        return false

    endif

    if (duration >= 0.) then

        call DisplayTimedTextToPlayer(p, posX, posY, duration, colorcode + message)

    else

        call DisplayTextToPlayer(p, posX, posY, colorcode + message)

    endif

    

    return true

endfunction

    

private function ForAll_timed_withColorCode takes real duration, string colorcode, string message returns boolean

    local integer i 

    if (not enabled) then

        return false

    endif

    set i = 0

    loop

        exitwhen (i > 11)

            call ForPlayer_timed_withColorCode(Player(i), duration, colorcode, message)

        set i = i + 1

    endloop

    

    return true

endfunction





public function P_timed takes player p, real duration, string message returns boolean

    return ForPlayer_timed_withColorCode(p, duration, NORMAL_TEXT_COLORCODE, message)

endfunction



public function P takes player p, string message returns boolean

    return ForPlayer_timed_withColorCode(p, -1., NORMAL_TEXT_COLORCODE, message)

endfunction



public function erP_timed takes player p, real duration, string message returns boolean

    return ForPlayer_timed_withColorCode(p, duration, ERROR_TEXT_COLORCODE, message)

endfunction



public function erP takes player p, string message returns boolean

    return ForPlayer_timed_withColorCode(p, -1., ERROR_TEXT_COLORCODE, message)

endfunction



public function mkP_timed takes player p, real duration, string message returns boolean

    return ForPlayer_timed_withColorCode(p, duration, MAKE_TEXT_COLORCODE, message)

endfunction



public function mkP takes player p, string message returns boolean

    return ForPlayer_timed_withColorCode(p, -1., MAKE_TEXT_COLORCODE, message)

endfunction





public function A_timed takes real duration, string message returns boolean

    return ForAll_timed_withColorCode(duration, NORMAL_TEXT_COLORCODE, message)

endfunction



public function A takes string message returns boolean

    return ForAll_timed_withColorCode(-1., NORMAL_TEXT_COLORCODE, message)

endfunction



public function erA_timed takes real duration, string message returns boolean

    return ForAll_timed_withColorCode(duration, ERROR_TEXT_COLORCODE, message)

endfunction



public function erA takes string message returns boolean

    return ForAll_timed_withColorCode(-1., ERROR_TEXT_COLORCODE, message)

endfunction



public function mkA_timed takes real duration, string message returns boolean

    return ForAll_timed_withColorCode(duration, MAKE_TEXT_COLORCODE, message)

endfunction



public function mkA takes string message returns boolean

    return ForAll_timed_withColorCode(-1., MAKE_TEXT_COLORCODE, message)

endfunction









function DisplayLineToPlayer takes player p returns nothing

    call Text_P(p, " ")

endfunction







endlibrary

//===========================================================================

// Trigger: Init terrain limit variables

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

function InitTrig_Init_terrain_limit_variables takes nothing returns nothing

    set MAP_MIN_X = GetRectMinX(GetWorldBounds())

    set MAP_MAX_X = GetRectMaxX(GetWorldBounds())

    set MAP_MIN_Y = GetRectMinY(GetWorldBounds())

    set MAP_MAX_Y = GetRectMaxY(GetWorldBounds())

endfunction



//===========================================================================

// Trigger: Init colorCodes

//===========================================================================

//TESH.scrollpos=6

//TESH.alwaysfold=0

globals

    string array udg_colorCode

    string array udg_baseColorString

    string COLOR_TERRAIN_SLIDE 

    string COLOR_TERRAIN_WALK

    string COLOR_TERRAIN_DEATH

endglobals







function Trig_init_colorCodes_Actions takes nothing returns nothing



    set udg_colorCode[ 0 ] = "|cffff0303" //red

    set udg_colorCode[ 1 ] = "|cff0042ff" //blue

    set udg_colorCode[ 2 ] = "|cff1ce6b9" //teal

    set udg_colorCode[ 3 ] = "|cff540081" //purple

    set udg_colorCode[ 4 ] = "|cfffffc01" //yellow

    set udg_colorCode[ 5 ] = "|cfffeba0e" //orange

    set udg_colorCode[ 6 ] = "|cff20c000" //green

    set udg_colorCode[ 7 ] = "|cffe55bb0" //pink

    set udg_colorCode[ 8 ] = "|cff959697" //grey

    set udg_colorCode[ 9 ] = "|cff7ebff1" //lightblue

    set udg_colorCode[10 ] = "|cff106246" //darkgreen

    set udg_colorCode[11 ] = "|cFF4A2800" //brown

    set udg_colorCode[12 ] = "|c33333333" //black



    set udg_baseColorString[ 0 ] = udg_colorCode[ 0 ] + "red"

    set udg_baseColorString[ 1 ] = udg_colorCode[ 1 ] + "blue"

    set udg_baseColorString[ 2 ] = udg_colorCode[ 2 ] + "teal"

    set udg_baseColorString[ 3 ] = udg_colorCode[ 3 ] + "purple"

    set udg_baseColorString[ 4 ] = udg_colorCode[ 4 ] + "yellow"

    set udg_baseColorString[ 5 ] = udg_colorCode[ 5 ] + "orange"

    set udg_baseColorString[ 6 ] = udg_colorCode[ 6 ] + "green"

    set udg_baseColorString[ 7 ] = udg_colorCode[ 7 ] + "pink"

    set udg_baseColorString[ 8 ] = udg_colorCode[ 8 ] + "grey"

    set udg_baseColorString[ 9 ] = udg_colorCode[ 9 ] + "lightblue"

    set udg_baseColorString[10 ] = udg_colorCode[10 ] + "darkgreen"

    set udg_baseColorString[11 ] = udg_colorCode[11 ] + "brown"

    set udg_baseColorString[12 ] = udg_colorCode[12 ] + "black"

    

    set COLOR_TERRAIN_SLIDE = udg_colorCode[TEAL]

    set COLOR_TERRAIN_WALK = udg_colorCode[GREEN]

    set COLOR_TERRAIN_DEATH = udg_colorCode[ORANGE]



endfunction



//===========================================================================

function InitTrig_Init_colorCodes takes nothing returns nothing

    set gg_trg_Init_colorCodes = CreateTrigger(  )

    call TriggerAddAction( gg_trg_Init_colorCodes, function Trig_init_colorCodes_Actions )

endfunction



//===========================================================================

// Trigger: Basic functions

//===========================================================================

//TESH.scrollpos=103

//TESH.alwaysfold=0

library BasicFunctions needs Text





globals

    integer udg_currentMonsterPlayerId = 0

endglobals







function IsUnitBetweenLocs takes unit u, real x1, real y1, real x2, real y2 returns boolean

	local real minX = RMinBJ(x1, x2)

	local real maxX = RMaxBJ(x1, x2)

	local real minY = RMinBJ(y1, y2)

	local real maxY = RMaxBJ(y1, y2)

	

	local real x = GetUnitX(u)

	local real y = GetUnitY(u)

	

	return ((minX < x and maxX > x) and (minY < y and maxY > y))

endfunction



function IsItemBetweenLocs takes item i, real x1, real y1, real x2, real y2 returns boolean

	local real minX = RMinBJ(x1, x2)

	local real maxX = RMaxBJ(x1, x2)

	local real minY = RMinBJ(y1, y2)

	local real maxY = RMaxBJ(y1, y2)

	

	local real x = GetItemX(i)

	local real y = GetItemY(i)

	

	return ((minX < x and maxX > x) and (minY < y and maxY > y))

endfunction





function IsPlayerInGame takes player p returns boolean

    return (GetPlayerController(p) == MAP_CONTROL_USER and GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING)

endfunction





function SpecialIllidan takes unit hero returns nothing

    call SetUnitAnimation(hero, "Morph Alternate")

endfunction





function IsIssuedOrder takes string orderString returns boolean

    return (GetIssuedOrderId() == OrderId(orderString))

endfunction



function IsLastOrderPause takes nothing returns boolean

    return GetIssuedOrderId() == 851973

endfunction



function GetLocDist takes real x1, real y1, real x2, real y2 returns real

    local real diffX = x2 - x1

    local real diffY = y2 - y1

    return SquareRoot(diffX * diffX + diffY * diffY)

endfunction





function GetCurrentMonsterPlayer takes nothing returns player

    if (udg_currentMonsterPlayerId >= 11) then

        set udg_currentMonsterPlayerId = 0

    else

        set udg_currentMonsterPlayerId = udg_currentMonsterPlayerId + 1

    endif

    return Player(udg_currentMonsterPlayerId)

endfunction





function IsUnitInvulnerable takes unit u returns boolean

    local real life = GetUnitState(u, UNIT_STATE_LIFE)

    local real damages

    call UnitDamageTarget(u, u, 0.01, false, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL,WEAPON_TYPE_WHOKNOWS)

    set damages=life-GetUnitState(u, UNIT_STATE_LIFE)

    call SetUnitState(u, UNIT_STATE_LIFE, life)

    return (damages == 0)

endfunction 





function StopUnit takes unit U returns nothing

    call PauseUnit(U, true)

    call IssueImmediateOrder(U, "stop")

    call PauseUnit(U, false)

endfunction





function IsHero takes unit U returns boolean

    local integer i = 0

    loop

        exitwhen (i > 11)

            if (udg_escapers.get(i).getHero() == U) then

                return true

            endif

        set i = i + 1

    endloop

    return false

endfunction



function ClearTextForPlayer takes player p returns nothing

    if (GetLocalPlayer() == p) then

        call ClearTextMessages()

    endif

endfunction



function MoveCamExceptForPlayer takes player p, real x, real y returns nothing

    if (GetLocalPlayer() == p) then

         set x = GetCameraTargetPositionX()

         set y = GetCameraTargetPositionY()

    endif

    call SetCameraPosition(x, y)

endfunction





function StringContainsChar takes string str, string char returns boolean

    local integer i

    local integer length

    if (StringLength(char) != 1) then

        return false

    endif

    set length = StringLength(str)

    set i = 1

    loop

        exitwhen (i > length)

            if (SubStringBJ(str, i, i) == char) then

                return true

            endif

        set i = i + 1

    endloop

    return false

endfunction





function IsBoolString takes string S returns boolean

    return (S == "true" or S == "false" or S == "on" or S == "off" or S == "1" or S == "0")

endfunction



function S2B takes string S returns boolean

    return (S == "true" or S == "on" or S == "1")

endfunction



function B2S takes boolean b returns string

    if (b) then

        return "true"

    endif

    return "false"

endfunction

    



endlibrary

//===========================================================================

// Trigger: Functions on numbers

//===========================================================================

//TESH.scrollpos=10

//TESH.alwaysfold=0

library FunctionsOnNumbers







function EstChiffre takes string str returns boolean

    if (str == "0" or str == "1" or str == "2" or str == "3" or str == "4") then

        return true

    endif

    if (str == "5" or str == "6" or str == "7" or str == "8" or str == "9") then

        return true

    endif

    return false

endfunction



function IsInteger takes string str returns boolean

    local integer length = StringLength(str)

    local integer i

    

    if (SubString(str, 0, 1) == "-") then

        set i = 1

    else

        set i = 0

    endif

    

    loop

        exitwhen (i >= length)

            if (not EstChiffre(SubString(str, i, i+1))) then

                return false

            endif

        set i = i + 1

    endloop

    

    return true

endfunction



function IsPositiveInteger takes string str returns boolean

    return (SubString(str, 0, 1) != "-" and IsInteger(str))

endfunction    



function IsPercentage takes string str returns boolean

    local integer n = S2I(str)

    return (IsPositiveInteger(str) and n >= 0 and n <= 100)

endfunction



function PercentageStringOrX2Integer takes string str returns integer

    if (not IsPercentage(str)) then

        if (str == "x") then

            return GetRandomInt(0, 100)

        endif

        return -1

    endif

    return S2I(str)

endfunction





endlibrary

//===========================================================================

// Trigger: Ascii

//===========================================================================

//TESH.scrollpos=46

//TESH.alwaysfold=0

library Ascii



    globals

        private constant string TABLE_ASCII = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"

        private constant integer DEBUT_TABLE_ASCII = 32

        private constant integer TAILLE_TABLE_ASCII = StringLength(TABLE_ASCII)

    endglobals

   

    //Permet de convertir un caractère en son nombre Ascii correspondant.

    //@caractere string : Caractère a convertir. Ne doit contenir qu'un seul caractère !

    //@return integer : Code Ascii de caractere.

    //                  Ou -1, si caractere n'est pas conforme.

    private function CaractereVersAscii takes string caractere returns integer

        //Le caractère est recherché dans TABLE_ASCII, et son rang est renvoyé.

       

        local integer curseurSurTableAscii = 0

   

        loop

            exitwhen (curseurSurTableAscii >= TAILLE_TABLE_ASCII) or (SubString(TABLE_ASCII, curseurSurTableAscii, curseurSurTableAscii + 1) == caractere)

            set curseurSurTableAscii = curseurSurTableAscii + 1

        endloop

   

        if (curseurSurTableAscii < TAILLE_TABLE_ASCII) then

            return curseurSurTableAscii + DEBUT_TABLE_ASCII

        endif

       

        //Caractère non reconnue.

        return -1

    endfunction



    //Permet de convertir un code Ascii en son caractère correspondant.

    //@integer source : Code Ascii a convertir. Doit être entre 32 et 126.

    //@return string : Caractère correspondant au code Ascii de source.

    //                 Ou chaine vide, en cas d'erreur.

    private function AsciiVersCaractere takes integer source returns string

        //Le caractère de TABLE_ASCII correspondant au rang est renvoyé.

        if (source >= DEBUT_TABLE_ASCII) and (source <= (StringLength(TABLE_ASCII) - 1 + DEBUT_TABLE_ASCII)) then

            return SubString(TABLE_ASCII, source - DEBUT_TABLE_ASCII, source - (DEBUT_TABLE_ASCII - 1))

        endif

        //Code Ascii non reconnu.

        return ""

    endfunction

   

    function String2Ascii takes string source returns integer

        //La chaine est parcouru de gauche à droite et convertis en même temps.

        //En cas d'erreur, -1 est renvoyé.

   

        local integer resultat = 0

        local integer resultatIntermediaire = 0

        local integer curseurSurSource = 0

        local integer sourceTaille = StringLength(source)

   

        loop

            exitwhen (curseurSurSource >= sourceTaille) or (resultatIntermediaire == -1)

            set resultatIntermediaire = CaractereVersAscii(SubString(source, curseurSurSource, curseurSurSource + 1))

            set resultat = resultat*256 + resultatIntermediaire

            set curseurSurSource = curseurSurSource + 1

        endloop

       

        if (resultatIntermediaire != -1) then

            return resultat

        endif

       

        //Un caractère n'a pas été reconnue dans source.

        return -1

    endfunction

   

    function Ascii2String takes integer source returns string

        //source est divisé successivement par 256 et le reste est utilisé pour retrouver le caractère correspondant.

        //Le résultat est construit en même temps.

        //En cas d'erreur, "" est retourné.

       

        local string resultat = ""

        local string resultatIntermediaire = " "    //Pour éviter une initialisation à "".

        local integer modulo = 1                    //Pour éviter une initialisation à 0.

       

        loop

            exitwhen (resultatIntermediaire == "") or (modulo <= 0)

            set modulo = source - (source/256) * 256

            set resultatIntermediaire = AsciiVersCaractere(modulo)

            set resultat = resultatIntermediaire + resultat

            set source = source/256

        endloop

       

        if (modulo == 0) then

            return resultat

        endif

       

        //Le code n'a pas été reconnue.

        return ""

    endfunction



endlibrary//===========================================================================

// Trigger: Decode string

//===========================================================================

//TESH.scrollpos=37

//TESH.alwaysfold=0

library DecodeString needs Text





private function DecodeChar takes string char returns string    

    //! textmacro DecodeChar takes in, out

    if (char == "$in$") then

        return "$out$"

    endif

    //! endtextmacro

    

    //! runtextmacro DecodeChar("A", "Z")

    //! runtextmacro DecodeChar("B", "A")

    //! runtextmacro DecodeChar("C", "B")

    //! runtextmacro DecodeChar("D", "C")

    //! runtextmacro DecodeChar("E", "D")

    //! runtextmacro DecodeChar("F", "E")

    //! runtextmacro DecodeChar("G", "F")

    //! runtextmacro DecodeChar("H", "G")

    //! runtextmacro DecodeChar("I", "H")

    //! runtextmacro DecodeChar("J", "I")

    //! runtextmacro DecodeChar("K", "J")

    //! runtextmacro DecodeChar("L", "K")

    //! runtextmacro DecodeChar("M", "L")

    //! runtextmacro DecodeChar("N", "M")

    //! runtextmacro DecodeChar("O", "N")

    //! runtextmacro DecodeChar("P", "O")

    //! runtextmacro DecodeChar("Q", "P")

    //! runtextmacro DecodeChar("R", "Q")

    //! runtextmacro DecodeChar("S", "R")

    //! runtextmacro DecodeChar("T", "S")

    //! runtextmacro DecodeChar("U", "T")

    //! runtextmacro DecodeChar("V", "U")

    //! runtextmacro DecodeChar("W", "V")

    //! runtextmacro DecodeChar("X", "W")

    //! runtextmacro DecodeChar("Y", "X")

    //! runtextmacro DecodeChar("Z", "Y")

    

    //! runtextmacro DecodeChar("a", "z")

    //! runtextmacro DecodeChar("b", "a")

    //! runtextmacro DecodeChar("c", "b")

    //! runtextmacro DecodeChar("d", "c")

    //! runtextmacro DecodeChar("e", "d")

    //! runtextmacro DecodeChar("f", "e")

    //! runtextmacro DecodeChar("g", "f")

    //! runtextmacro DecodeChar("h", "g")

    //! runtextmacro DecodeChar("i", "h")

    //! runtextmacro DecodeChar("j", "i")

    //! runtextmacro DecodeChar("k", "j")

    //! runtextmacro DecodeChar("l", "k")

    //! runtextmacro DecodeChar("m", "l")

    //! runtextmacro DecodeChar("n", "m")

    //! runtextmacro DecodeChar("o", "n")

    //! runtextmacro DecodeChar("p", "o")

    //! runtextmacro DecodeChar("q", "p")

    //! runtextmacro DecodeChar("r", "q")

    //! runtextmacro DecodeChar("s", "r")

    //! runtextmacro DecodeChar("t", "s")

    //! runtextmacro DecodeChar("u", "t")

    //! runtextmacro DecodeChar("v", "u")

    //! runtextmacro DecodeChar("w", "v")

    //! runtextmacro DecodeChar("x", "w")

    //! runtextmacro DecodeChar("y", "x")

    //! runtextmacro DecodeChar("z", "y")

    

    return char

endfunction





function DecodeString takes string strIn returns string

    local string strOut = ""

    local integer i = 1

    loop

        exitwhen (i > StringLength(strIn))

            set strOut = strOut + DecodeChar(SubStringBJ(strIn, i, i))

        set i = i + 1

    endloop

    //call Text_A("strIn : " + strIn + ", strOut : " + strOut)

    return strOut

endfunction









endlibrary//===========================================================================

// Trigger: View all hide all

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library ViewAllHideAll initializer Init_ViewAllHideAll





globals

    fogmodifier udg_hideAll

    fogmodifier udg_viewAll

endglobals





function RefreshHideAllVM takes nothing returns nothing

    call DestroyFogModifier(udg_hideAll)

    set udg_hideAll = CreateFogModifierRect(Player(0), FOG_OF_WAR_MASKED, GetWorldBounds(), true, false )

    call FogModifierStart(udg_hideAll)

endfunction





function Init_ViewAllHideAll takes nothing returns nothing

    set udg_viewAll = CreateFogModifierRect(Player(0), FOG_OF_WAR_VISIBLE, GetPlayableMapRect(), true, false )

    set udg_hideAll = CreateFogModifierRect(Player(0), FOG_OF_WAR_MASKED, GetWorldBounds(), true, false )

    call FogModifierStart(udg_hideAll)

endfunction





endlibrary//===========================================================================

// Trigger: Immolation skills

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library ImmolationSkills initializer Init_ImmolationSkills





globals

    integer array IMMOLATION_SKILLS

endglobals





function Init_ImmolationSkills takes nothing returns nothing

    set IMMOLATION_SKILLS[1] = 'I005'

    set IMMOLATION_SKILLS[2] = 'I010'

    set IMMOLATION_SKILLS[3] = 'I015'

    set IMMOLATION_SKILLS[4] = 'I020'

    set IMMOLATION_SKILLS[5] = 'I025'

    set IMMOLATION_SKILLS[6] = 'I030'

    set IMMOLATION_SKILLS[7] = 'I035'

    set IMMOLATION_SKILLS[8] = 'I040'

    set IMMOLATION_SKILLS[9] = 'I045'

    set IMMOLATION_SKILLS[10] = 'I050'

    set IMMOLATION_SKILLS[11] = 'I055'

    set IMMOLATION_SKILLS[12] = 'I060'

    set IMMOLATION_SKILLS[13] = 'I065'

    set IMMOLATION_SKILLS[14] = 'I070'

    set IMMOLATION_SKILLS[15] = 'I075'

    set IMMOLATION_SKILLS[16] = 'I080'

    set IMMOLATION_SKILLS[17] = 'I085'

    set IMMOLATION_SKILLS[18] = 'I090'

    set IMMOLATION_SKILLS[19] = 'I095'

    set IMMOLATION_SKILLS[20] = 'I100'

    set IMMOLATION_SKILLS[21] = 'I105'

    set IMMOLATION_SKILLS[22] = 'I110'

    set IMMOLATION_SKILLS[23] = 'I115'

    set IMMOLATION_SKILLS[24] = 'I120'

    set IMMOLATION_SKILLS[25] = 'I125'

    set IMMOLATION_SKILLS[26] = 'I130'

    set IMMOLATION_SKILLS[27] = 'I135'

    set IMMOLATION_SKILLS[28] = 'I140'

    set IMMOLATION_SKILLS[29] = 'I145'

    set IMMOLATION_SKILLS[30] = 'I150'

    set IMMOLATION_SKILLS[31] = 'I155'

    set IMMOLATION_SKILLS[32] = 'I160'

    set IMMOLATION_SKILLS[33] = 'I165'

    set IMMOLATION_SKILLS[34] = 'I170'

    set IMMOLATION_SKILLS[35] = 'I175'

    set IMMOLATION_SKILLS[36] = 'I180'

    set IMMOLATION_SKILLS[37] = 'I185'

    set IMMOLATION_SKILLS[38] = 'I190'

    set IMMOLATION_SKILLS[39] = 'I195'

    set IMMOLATION_SKILLS[40] = 'I200'

    set IMMOLATION_SKILLS[41] = 'I205'

    set IMMOLATION_SKILLS[42] = 'I210'

    set IMMOLATION_SKILLS[43] = 'I215'

    set IMMOLATION_SKILLS[44] = 'I220'

    set IMMOLATION_SKILLS[45] = 'I225'

    set IMMOLATION_SKILLS[46] = 'I230'

    set IMMOLATION_SKILLS[47] = 'I235'

    set IMMOLATION_SKILLS[48] = 'I240'

    set IMMOLATION_SKILLS[49] = 'I245'

    set IMMOLATION_SKILLS[50] = 'I250'

    set IMMOLATION_SKILLS[51] = 'I255'

    set IMMOLATION_SKILLS[52] = 'I260'

    set IMMOLATION_SKILLS[53] = 'I265'

    set IMMOLATION_SKILLS[54] = 'I270'

    set IMMOLATION_SKILLS[55] = 'I275'

    set IMMOLATION_SKILLS[56] = 'I280'

    set IMMOLATION_SKILLS[57] = 'I285'

    set IMMOLATION_SKILLS[58] = 'I290'

    set IMMOLATION_SKILLS[59] = 'I295'

    set IMMOLATION_SKILLS[60] = 'I300'

    set IMMOLATION_SKILLS[61] = 'I305'

    set IMMOLATION_SKILLS[62] = 'I310'

    set IMMOLATION_SKILLS[63] = 'I315'

    set IMMOLATION_SKILLS[64] = 'I320'

    set IMMOLATION_SKILLS[65] = 'I325'

    set IMMOLATION_SKILLS[66] = 'I330'

    set IMMOLATION_SKILLS[67] = 'I335'

    set IMMOLATION_SKILLS[68] = 'I340'

    set IMMOLATION_SKILLS[69] = 'I345'

    set IMMOLATION_SKILLS[70] = 'I350'

    set IMMOLATION_SKILLS[71] = 'I355'

    set IMMOLATION_SKILLS[72] = 'I360'

    set IMMOLATION_SKILLS[73] = 'I365'

    set IMMOLATION_SKILLS[74] = 'I370'

    set IMMOLATION_SKILLS[75] = 'I375'

    set IMMOLATION_SKILLS[76] = 'I380'

    set IMMOLATION_SKILLS[77] = 'I385'

    set IMMOLATION_SKILLS[78] = 'I390'

    set IMMOLATION_SKILLS[79] = 'I395'

    set IMMOLATION_SKILLS[80] = 'I400'

endfunction









endlibrary//===========================================================================

// Trigger: MonsterType

//===========================================================================

//TESH.scrollpos=187

//TESH.alwaysfold=0

library MonsterType initializer Init_MonsterType needs ImmolationSkills





struct MonsterType

    string label

    string alias

    private integer unitTypeId

    private real scale //influe sur la taille de l'unité ; 1.0 donne une taille normale

    private integer immolationSkill

    private real speed

    private boolean isClickableB

    private string killingEffectStr

    private integer maxLife

    

    

	method setLabel takes string label returns nothing

		set .label = label

	endmethod

	

	method setAlias takes string alias returns MonsterType

		set .alias = alias

        return this

	endmethod



    static method create takes string label, integer unitTypeId, real scale, real immolationRadius, real speed, boolean isClickable returns MonsterType

        local MonsterType mt

        local unit testMonster

        if (speed <= 0 or speed > MAX_MOVE_SPEED or scale <= 0 or not((immolationRadius/5) == I2R(R2I(immolationRadius/5))) or immolationRadius < 5 or immolationRadius > 400) then

            return 0

        endif

        set testMonster = CreateUnit(NEUTRAL_PLAYER, unitTypeId, 0,0,0)

        if (testMonster == null) then

            return 0

        else

            call RemoveUnit(testMonster)

            set testMonster = null

        endif

        set mt = MonsterType.allocate()

        set mt.label = label

        set mt.alias = null

        set mt.unitTypeId = unitTypeId

        set mt.scale = scale

        set mt.immolationSkill = IMMOLATION_SKILLS[R2I(immolationRadius/5)]

        set mt.speed = speed

        set mt.isClickableB = isClickable

        set mt.killingEffectStr = null

        set mt.maxLife = 10000

        return mt

    endmethod

    

    method refresh takes nothing returns nothing //recrée les monstres correspondant au niveau actuel

        local Level array levelsMaking

        local Escaper escaper

        local integer i

        local integer j

        local boolean levelAlreadyChecked

        local integer nbLevelsMaking = 0

        local Level currentLevel = udg_levels.getCurrentLevel()

        call currentLevel.recreateMonstersOfType(this) 

        set i = 0

        loop

            exitwhen (i > 11)

                set escaper = udg_escapers.get(i)

                if (escaper != 0) then

                    if (escaper.getMakingLevel() != currentLevel) then

                        set levelAlreadyChecked = false

                        set j = 0

                        loop

                            exitwhen (j >= nbLevelsMaking)

                                if (escaper.getMakingLevel() == levelsMaking[j]) then

                                    set levelAlreadyChecked = true

                                endif

                            set j = j + 1

                        endloop

                        if (not levelAlreadyChecked) then

                            set levelsMaking[nbLevelsMaking] = escaper.getMakingLevel()

                            set nbLevelsMaking = nbLevelsMaking + 1

                        endif

                    endif

                endif

            set i = i + 1

        endloop

        set i = 0

        loop

            exitwhen (i >= nbLevelsMaking)

                call levelsMaking[i].recreateMonstersOfType(this)

            set i = i + 1

        endloop

    endmethod

    

    method onDestroy takes nothing returns nothing

        call udg_levels.removeMonstersOfType(this)

    endmethod

    

    method getUnitTypeId takes nothing returns integer

        return .unitTypeId

    endmethod

    

    method setUnitTypeId takes integer unitTypeId returns boolean

        local unit testMonster = CreateUnit(NEUTRAL_PLAYER, unitTypeId, 0,0,0)

        if (testMonster == null) then

            return false

        endif

        call RemoveUnit(testMonster)

        set testMonster = null

        set .unitTypeId = unitTypeId

        call .refresh()

        return true

    endmethod

    

    method getScale takes nothing returns real

        return .scale

    endmethod

    

    method setScale takes real scale returns boolean

        if (scale <= 0) then

            return false

        endif

        set .scale = scale

        call .refresh()

        return true

    endmethod

    

    method getImmolationSkill takes nothing returns integer

        return .immolationSkill

    endmethod

    

    method setImmolation takes real immolationRadius returns boolean

        if (not((immolationRadius/5) == I2R(R2I(immolationRadius/5))) or immolationRadius < 5 or immolationRadius > 400) then

            return false

        endif

        set .immolationSkill = IMMOLATION_SKILLS[R2I(immolationRadius/5)]

        call .refresh()

        return true

    endmethod

    

    method getUnitMoveSpeed takes nothing returns real

        return .speed

    endmethod

    

    method setUnitMoveSpeed takes real speed returns boolean

        if (speed <= 0 or speed > MAX_MOVE_SPEED) then

            return false

        endif

        set .speed = speed

        call .refresh()

        return true

    endmethod

    

    method isClickable takes nothing returns boolean

        return .isClickableB

    endmethod

    

    method setIsClickable takes boolean isClickable returns boolean

        if (.isClickableB == isClickable) then

            return false

        endif

        set .isClickableB = isClickable

        call .refresh()

        return true

    endmethod

    

    method getKillingEffectStr takes nothing returns string

        return .killingEffectStr

    endmethod

    

    method setKillingEffectStr takes string effectStr returns MonsterType

        set .killingEffectStr = effectStr

        return this

    endmethod

    

    method displayForPlayer takes player p returns nothing

        local string space = "   "

        local string display = udg_colorCode[RED] + .label + " " + .alias + " : '"

        set display = display + Ascii2String(.unitTypeId) + "'" + space + "'" + Ascii2String(.immolationSkill) + "'"

        set display = display + space + I2S(R2I(.speed)) + space + R2S(.scale)

        if (.isClickableB) then

            set display = display + space + "clickable" + space + I2S(.maxLife / 10000)

        endif

        call Text_P_timed(p, TERRAIN_DATA_DISPLAY_TIME, display)

    endmethod

    

    method displayTotalForPlayer takes player p returns nothing

        local string space = "   "

        local string display = udg_colorCode[RED] + .label + " " + .alias + " : '"

        set display = display + Ascii2String(.unitTypeId) + "'" + space + "'" + Ascii2String(.immolationSkill) + "'"

        set display = display + space + I2S(R2I(.speed)) + space + R2S(.scale) + space + .killingEffectStr

        if (.isClickableB) then

            set display = display + space + "clickable" + space + I2S(.maxLife / 10000)

        endif

        call Text_P_timed(p, TERRAIN_DATA_DISPLAY_TIME, display)

    endmethod

    

    method setNbMeteorsToKill takes integer nbMeteorsToKill returns MonsterType

        //nombre de météores qu'il faut pour tuer le monstre, sachant qu'une météore fait 10k de dégât

        if (nbMeteorsToKill < 1 or nbMeteorsToKill > 9) then

            return this

        endif

        set .maxLife = nbMeteorsToKill * 10000

        if (.isClickableB) then

            call .refresh()

        endif

        return this

    endmethod

    

    method getMaxLife takes nothing returns integer

        return .maxLife

    endmethod

    

    method getImmolationRadiusStr takes nothing returns string

        local string immoStr = Ascii2String(.immolationSkill)

        set immoStr = SubStringBJ(immoStr, 2, 4)

        return I2S(S2I(immoStr))

    endmethod

    

    method toString takes nothing returns string

        local string str = .label + CACHE_SEPARATEUR_PARAM + .alias + CACHE_SEPARATEUR_PARAM

        set str = str + Ascii2String(.unitTypeId) + CACHE_SEPARATEUR_PARAM + R2S(.scale) + CACHE_SEPARATEUR_PARAM

        set str = str + .getImmolationRadiusStr() + CACHE_SEPARATEUR_PARAM + R2S(.speed) + CACHE_SEPARATEUR_PARAM

        set str = str + B2S(.isClickableB) + CACHE_SEPARATEUR_PARAM + .killingEffectStr + CACHE_SEPARATEUR_PARAM

        set str = str + I2S(.maxLife / 10000)

        return str

    endmethod

endstruct







//===========================================================================

function Init_MonsterType takes nothing returns nothing

endfunction







endlibrary//===========================================================================

// Trigger: MonsterTypeArray

//===========================================================================

//TESH.scrollpos=74

//TESH.alwaysfold=0

library MonsterTypeArray needs MonsterType





struct MonsterTypeArray

    private MonsterType array monsterTypes [1000]

    private integer numberOfMonsterTypes



    static method create takes nothing returns MonsterTypeArray

        local MonsterTypeArray ma = MonsterTypeArray.allocate()

        set ma.numberOfMonsterTypes = 0

        return ma        

    endmethod

    

    method get takes string label returns MonsterType

		local integer i = 0

		loop

			exitwhen (i >= .numberOfMonsterTypes)

				if (.monsterTypes[i].label == label or .monsterTypes[i].alias == label) then

					return .monsterTypes[i]

				endif

			set i = i + 1

		endloop

		return 0

	endmethod



	method isLabelAlreadyUsed takes string label returns boolean

		return (.get(label) != 0)

	endmethod

    

    method new takes string label, integer unitTypeId, real scale, real immolationRadius, real speed, boolean isClickable returns MonsterType

        local integer n = .numberOfMonsterTypes

        if (.isLabelAlreadyUsed(label)) then

            return 0

        endif

        set .monsterTypes[n] = MonsterType.create(label, unitTypeId, scale, immolationRadius, speed, isClickable)

        if (.monsterTypes[n] != 0) then

            set .numberOfMonsterTypes = .numberOfMonsterTypes + 1

        endif

        return .monsterTypes[n]

    endmethod

    

    method remove takes string label returns boolean

        local integer position

        local integer i

        local MonsterType mt = .get(label)

        if (mt == 0) then

            return false

        endif

        set i = 0

        loop

            exitwhen (.monsterTypes[i].label == label or .monsterTypes[i].alias == label or i >= .numberOfMonsterTypes)

            set i = i + 1

        endloop

        if (i < .numberOfMonsterTypes) then

            set position = i

            set i = i + 1

            loop

                exitwhen (i >= .numberOfMonsterTypes)

                    set .monsterTypes[i-1] = .monsterTypes[i]

                set i = i + 1

            endloop

            set .numberOfMonsterTypes = .numberOfMonsterTypes - 1

        endif

        call mt.destroy()

        return true

    endmethod

    

    method displayForPlayer takes player p returns nothing

        local integer i = 0

        loop

            exitwhen (i >= .numberOfMonsterTypes)

                call .monsterTypes[i].displayForPlayer(p)

            set i = i + 1

        endloop

        if (.numberOfMonsterTypes == 0) then

            call Text_erP(p, "no monster type saved")

        endif

    endmethod

    

    method monsterUnit2KillEffectStr takes unit monsterUnit returns string

        local integer monsterUnitTypeId = GetUnitTypeId(monsterUnit)

        local integer i = 0

        loop

            exitwhen i >= numberOfMonsterTypes

                if(.monsterTypes[i].getUnitTypeId() == monsterUnitTypeId)then

                    return .monsterTypes[i].getKillingEffectStr()

                endif

            set i = i + 1

        endloop

        return null

    endmethod

    

    method monsterUnit2MonsterType takes unit monsterUnit returns MonsterType

        local integer monsterUnitTypeId = GetUnitTypeId(monsterUnit)

        local integer i = 0

        loop

            exitwhen i >= numberOfMonsterTypes

                if(.monsterTypes[i].getUnitTypeId() == monsterUnitTypeId)then

                    return .monsterTypes[i]

                endif

            set i = i + 1

        endloop

        return 0

    endmethod

    

    method saveInCache takes nothing returns nothing

        local integer i

        set stringArrayForCache = StringArrayForCache.create("monsterTypes", "monsterTypes", true)

        set i = 0

        loop

            exitwhen (i >= .numberOfMonsterTypes)

                call stringArrayForCache.push(.monsterTypes[i].toString())

            set i = i + 1

        endloop

        call stringArrayForCache.writeInCache()

    endmethod

endstruct







endlibrary//===========================================================================

// Trigger: Monster creation functions

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library MonsterCreationFunctions needs BasicFunctions, MonsterTypeArray





globals

    private unit monster

    private integer ATTACK_SKILL = 'Aatk'

    private constant integer ABILITY_1_LIFE = 'ABV1'

    private constant integer ABILITY_10_LIFE = 'ABV2'

    private constant integer ABILITY_100_LIFE = 'ABV3'

    private constant integer ABILITY_1000_LIFE = 'ABV4'

    private constant integer ABILITY_10000_LIFE = 'ABV5'

    private constant integer ABILITY_ANNULER_VISION = 'A0AV'

endglobals



    

    

private function UnitAddRemoveLifeAbility takes unit u, integer lifeAbility returns nothing

    call UnitAddAbility(u, lifeAbility)

    call SetUnitAbilityLevel(u, lifeAbility, 2)

    call UnitRemoveAbility(u, lifeAbility)

endfunction



function UnitAddMaxLife takes unit u, integer lifeToAdd returns nothing

    loop

        exitwhen (lifeToAdd <= 0)

            if (lifeToAdd >= 10000) then

                call UnitAddRemoveLifeAbility(u, ABILITY_10000_LIFE)

                set lifeToAdd = lifeToAdd - 10000

            else

                if (lifeToAdd >= 1000) then

                    call UnitAddRemoveLifeAbility(u, ABILITY_1000_LIFE)

                    set lifeToAdd = lifeToAdd - 1000

                else

                    if (lifeToAdd >= 100) then

                        call UnitAddRemoveLifeAbility(u, ABILITY_100_LIFE)

                        set lifeToAdd = lifeToAdd - 100

                    else

                        if (lifeToAdd >= 10) then

                            call UnitAddRemoveLifeAbility(u, ABILITY_10_LIFE)

                            set lifeToAdd = lifeToAdd - 10

                        else

                            call UnitAddRemoveLifeAbility(u, ABILITY_1_LIFE)

                            set lifeToAdd = lifeToAdd - 1

                        endif

                    endif

                endif

            endif

    endloop

endfunction



function SetUnitMaxLife takes unit u, integer newMaxLife returns boolean

    local integer maxLife = R2I(GetUnitState(u, UNIT_STATE_MAX_LIFE))

    if (newMaxLife <= maxLife) then

        return false

    endif

    call UnitAddMaxLife(u, newMaxLife - maxLife)

    return true

endfunction





function NewImmobileMonsterForPlayer takes MonsterType mt, player p, real x, real y, real angle returns unit

    local real scale

    if (angle == -1) then

        set monster = CreateUnit(p, mt.getUnitTypeId(), x, y, GetRandomDirectionDeg())

    else

        set monster = CreateUnit(p, mt.getUnitTypeId(), x, y, angle)

    endif

    //if (IsHeroUnitId(mt.getUnitTypeId())) then

    //    call Text_A("hero")

    //else

    //    call Text_A("pas hero")

    //endif

    call SetUnitUseFood(monster, false)

    if (mt.isClickable()) then

        call SetUnitMaxLife(monster, mt.getMaxLife())

    else

        call UnitAddAbility(monster, 'Aloc')

        call UnitAddAbility(monster, ABILITY_ANNULER_VISION)

    endif

    call UnitAddAbility(monster, mt.getImmolationSkill())

    set scale = mt.getScale()

    if (scale != 1) then

        call SetUnitScale(monster, scale, scale, scale)

    endif

    call SetUnitMoveSpeed(monster, mt.getUnitMoveSpeed())

    call SetUnitColor(monster, ConvertPlayerColor(12))

    call UnitRemoveAbility(monster, ATTACK_SKILL)

    return monster

endfunction



function NewImmobileMonster takes MonsterType mt, real x, real y, real angle returns unit

    local player p

    if (mt.isClickable()) then

        set p = ENNEMY_PLAYER

    else

        set p = GetCurrentMonsterPlayer()

    endif

    return NewImmobileMonsterForPlayer(mt, p, x, y, angle)

endfunction





function NewPatrolMonster takes MonsterType mt, real x1, real y1, real x2, real y2 returns unit

    local real angle = bj_RADTODEG * Atan2(y1 - y2, x1 - x2)

    set monster = NewImmobileMonster(mt, x1, y1, angle)

    call IssuePointOrder(monster, "patrol", x2, y2)

    return monster

endfunction





function MonsterTypeString2Id takes string S returns integer





    return 0

endfunction





function IsMonsterTypeString takes string str returns boolean

    return MonsterTypeString2Id( str ) != 0

endfunction









endlibrary





//===========================================================================

// Trigger: MonsterInterface

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library MonsterInterface needs MonsterCreationFunctions





interface Monster [600000] //200 niveaux * 1000 monstres par type * 3 types

    static integer nbInstances = 0

	unit u = null

	MonsterType mt

    Level level

    integer arrayId

    integer life

	//static method count takes nothing returns integer

	method createUnit takes nothing returns nothing

	method removeUnit takes nothing returns nothing

    method killUnit takes nothing returns nothing

    method getMonsterType takes nothing returns MonsterType

    method toString takes nothing returns string

    method getLife takes nothing returns integer

    method setLife takes integer life returns nothing

endinterface





endlibrary





globals

    constant integer MAX_NB_MONSTERS = 1000 //nombre maximum de monstres pour chacun des trois types et par niveau (no move, simple patrol, multiple patrols)

endglobals





//===========================================================================

// Trigger:    trig Monsters clickable set life

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library MonstersClickableSetLife initializer Init_MonstersClickableSetLife needs MonsterInterface





globals

    group monstersClickable

    trigger trigMonstersClickableSetLife

    private constant real PERIOD = 0.1

endglobals





function MonstersClickableSetLifeForEach takes nothing returns nothing

    local unit monsterUnit = GetEnumUnit()

    local real currentLife = GetUnitState(monsterUnit, UNIT_STATE_LIFE)

    local Monster monster = Monster(GetUnitUserData(monsterUnit))

    local real previousLife = I2R(monster.getLife())

    local real diffLife = RMaxBJ(currentLife, previousLife) - RMinBJ(currentLife, previousLife)

    if (diffLife < 100) then

        call SetUnitLifeBJ(GetEnumUnit(), previousLife - 0.5)

    else

        loop

            exitwhen (diffLife <= 0)

                call monster.setLife(R2I(previousLife) - 10000)

            set diffLife = diffLife - 10000

        endloop

    endif

endfunction



function MonstersClickableSetLife_Actions takes nothing returns nothing

    call ForGroup(monstersClickable, function MonstersClickableSetLifeForEach)

endfunction





//===========================================================================

function Init_MonstersClickableSetLife takes nothing returns nothing

    set monstersClickable = CreateGroup()

    set trigMonstersClickableSetLife = CreateTrigger()

    call TriggerAddAction(trigMonstersClickableSetLife, function MonstersClickableSetLife_Actions)

    call TriggerRegisterTimerEvent(trigMonstersClickableSetLife, PERIOD, true)

endfunction





endlibrary//===========================================================================

// Trigger: MonsterNoMove

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library MonsterNoMove needs MonsterInterface





struct MonsterNoMove extends Monster

    static integer nbInstances = 0

    

    static method count takes nothing returns integer

        return MonsterNoMove.nbInstances

    endmethod

    

    

    unit u

    private MonsterType mt

    

	private real x

	private real y

    private real angle //-1 -> random

    

	method removeUnit takes nothing returns nothing

        if (.u != null) then

            call GroupRemoveUnit(monstersClickable, .u)

            call RemoveUnit(.u)

            set .u = null

        endif

	endmethod

    

    method killUnit takes nothing returns nothing

        if (.u != null and IsUnitAliveBJ(.u)) then

            call KillUnit(.u)

        endif

    endmethod

    

    private method onDestroy takes nothing returns nothing

		if (.u != null) then

			call .removeUnit()

		endif

        call .level.monstersNoMove.setMonsterNull(.arrayId)

        set MonsterNoMove.nbInstances = MonsterNoMove.nbInstances - 1

    endmethod

	

	static method create takes MonsterType mt, real x, real y, real angle returns MonsterNoMove

		local MonsterNoMove m = MonsterNoMove.allocate()

        set MonsterNoMove.nbInstances = MonsterNoMove.nbInstances + 1

        set m.mt = mt

		set m.x = x

		set m.y = y

        set m.angle = angle

        set m.life = 0

		return m

	endmethod

	

	method createUnit takes nothing returns nothing

        if (.u != null) then

            call .removeUnit()

        endif

        set .u = NewImmobileMonster(.mt, .x, .y, .angle)

        call SetUnitUserData(.u, integer(this))

        if (.mt.isClickable()) then

            set .life = .mt.getMaxLife()

            call GroupAddUnit(monstersClickable, .u)

        endif

	endmethod

	

    method getLife takes nothing returns integer

        return .life

    endmethod

    

    method setLife takes integer life returns nothing

        set .life = life

        if (life > 0) then

            call SetUnitLifeBJ(.u, I2R(life) - 0.5)

        else

            call .killUnit()

        endif

    endmethod

    

    method getMonsterType takes nothing returns MonsterType

        return .mt

    endmethod

    

    method toString takes nothing returns string

        local string str

        if (.mt.alias != null and .mt.alias != "") then

            set str = .mt.alias + CACHE_SEPARATEUR_PARAM

        else

            set str = .mt.label + CACHE_SEPARATEUR_PARAM

        endif

        set str = str + I2S(R2I(.x)) + CACHE_SEPARATEUR_PARAM + I2S(R2I(.y))

        set str = str + CACHE_SEPARATEUR_PARAM + I2S(R2I(.angle))

        return str

    endmethod

endstruct





endlibrary







//===========================================================================

// Trigger: MonsterNoMoveArray

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

globals

    constant real MONSTER_NEAR_DIFF_MAX = 64

endglobals





library MonsterNoMoveArray needs MonsterNoMove





struct MonsterNoMoveArray [200000] //200 niveaux * 1000 monstres

    private MonsterNoMove array monsters [MAX_NB_MONSTERS]

	private integer lastInstance

	

	static method create takes nothing returns MonsterNoMoveArray

		local MonsterNoMoveArray ma = MonsterNoMoveArray.allocate()

		set ma.lastInstance = -1

		return ma

	endmethod

	

	method getFirstEmpty takes nothing returns integer

		local integer i = 0

		loop

			exitwhen (i > .lastInstance or .monsters[i] == 0)

			set i = i + 1

		endloop

		return i

	endmethod	

	

    method get takes integer arrayId returns MonsterNoMove

        if (arrayId < 0 or arrayId > .lastInstance) then

            return 0

        endif

        return .monsters[arrayId]

    endmethod

    

    method getLastInstanceId takes nothing returns integer

        return .lastInstance

    endmethod

	

    method new takes MonsterType mt, real x, real y, real angle, boolean createUnit returns MonsterNoMove //retourne le monstre s'il a pu être créé, 0 sinon

		//local integer n = .getFirstEmpty()

        local integer n = .lastInstance + 1

		if (n >= MAX_NB_MONSTERS) then

			return 0

		endif

		//if (n > .lastInstance) then

			set .lastInstance = n

		//endif

		set .monsters[n] = MonsterNoMove.create(mt, x, y, angle)

		if (createUnit) then

			call .monsters[n].createUnit()

		endif

        set .monsters[n].level = udg_levels.getLevelFromMonsterNoMoveArray(this)

        set .monsters[n].arrayId = n

		return .monsters[n]   

    endmethod

	

	method count takes nothing returns integer

		local integer n = 0

		local integer i = 0

		loop

			exitwhen (i > .lastInstance)

				if (.monsters[i] != 0) then

					set n = n + 1

				endif

			set i = i + 1

		endloop

		return n

	endmethod

    

    method onDestroy takes nothing returns nothing

        local integer i = 0

        loop

            exitwhen (i > .lastInstance)

                if (.monsters[i] != 0) then

                    call .monsters[i].destroy()

                endif

            set i = i + 1

        endloop

        set .lastInstance = -1

    endmethod

    

    method setMonsterNull takes integer monsterArrayId returns nothing

        set .monsters[monsterArrayId] = 0

    endmethod

    

    method clearMonster takes integer monsterId returns boolean

        local integer i = 0

        loop

            exitwhen (.monsters[i] == MonsterNoMove(monsterId) or i > .lastInstance)

            set i = i + 1

        endloop

        if (i > .lastInstance) then

            return false

        endif

        call .monsters[i].destroy()

        return true

    endmethod

    

    method getMonsterNear takes real x, real y returns MonsterNoMove

        local real xMob

        local real yMob

        local integer i = 0

        loop

            exitwhen (i > .lastInstance)

                if (.monsters[i] != 0 and .monsters[i].u != null) then

                    set xMob = GetUnitX(.monsters[i].u)

                    set yMob = GetUnitY(.monsters[i].u)

                    if (RAbsBJ(x - xMob) < MONSTER_NEAR_DIFF_MAX and RAbsBJ(y - yMob) < MONSTER_NEAR_DIFF_MAX) then

                        return .monsters[i]

                    endif

                endif

            set i = i + 1

        endloop

        return 0    

    endmethod

    

    method createMonsters takes nothing returns nothing

        local integer i = 0

        loop

            exitwhen (i > .lastInstance)

                if (.monsters[i] != 0) then

                    call .monsters[i].createUnit()

                endif

            set i = i + 1

        endloop

    endmethod

    

    method removeMonsters takes nothing returns nothing

        local integer i = 0

        loop

            exitwhen (i > .lastInstance)

                if (.monsters[i] != 0) then

                    call .monsters[i].removeUnit()

                endif

            set i = i + 1

        endloop

    endmethod

    

    method recreateMonstersOfType takes MonsterType mt returns nothing

        local integer i = 0

        loop

            exitwhen (i > .lastInstance)

                if (.monsters[i] != 0 and .monsters[i].getMonsterType() == mt and .monsters[i].u != null) then

                    call .monsters[i].createUnit()

                endif

            set i = i + 1

        endloop

    endmethod

    

    method removeMonstersOfType takes MonsterType mt returns nothing

        local integer i = 0

        loop

            exitwhen (i > .lastInstance)

                if (.monsters[i] != 0 and .monsters[i].getMonsterType() == mt) then

                    call .monsters[i].destroy()

                endif

            set i = i + 1

        endloop

    endmethod

endstruct





endlibrary



//===========================================================================

// Trigger: MonsterSimplePatrol

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library MonsterSimplePatrol initializer Init_MonsterSimplePatrol needs MonsterInterface





//vérification que les monstres multi-patrouilles patrouillent bien

globals

    private group simplePatrolMobs = CreateGroup()

    private constant real checkSimplePatrolMobsPeriod = 5.

endglobals



private function CheckSimplePatrolMobsEnum takes nothing returns nothing

    if (GetUnitCurrentOrder(GetEnumUnit()) == 0) then //le mob s'est arrêté

        call MonsterSimplePatrol(GetUnitUserData(GetEnumUnit())).createUnit()

    endif        

endfunction 



private function CheckSimplePatrolMobs_Actions takes nothing returns nothing

    call ForGroup(simplePatrolMobs, function CheckSimplePatrolMobsEnum)

endfunction



function Init_MonsterSimplePatrol takes nothing returns nothing

    local trigger trigCheckSimplePatrolMobs = CreateTrigger()

    call TriggerAddAction(trigCheckSimplePatrolMobs, function CheckSimplePatrolMobs_Actions)

    call TriggerRegisterTimerEvent(trigCheckSimplePatrolMobs, checkSimplePatrolMobsPeriod, true)

    set trigCheckSimplePatrolMobs = null

endfunction

/////////////////////////////////////////////////////////////////////////





struct MonsterSimplePatrol extends Monster

    static integer nbInstances = 0    

    

    static method count takes nothing returns integer

        return MonsterSimplePatrol.nbInstances

    endmethod

    

    

    unit u

    private MonsterType mt

    

	private real x1

	private real y1

	private real x2

	private real y2

	

	method removeUnit takes nothing returns nothing

        if (.u != null) then

            call GroupRemoveUnit(monstersClickable, .u)

            call GroupRemoveUnit(simplePatrolMobs, .u)

            call RemoveUnit(.u)

            set .u = null

        endif

	endmethod

    

    method killUnit takes nothing returns nothing

        if (.u != null and IsUnitAliveBJ(.u)) then

            call GroupRemoveUnit(simplePatrolMobs, .u)

            call KillUnit(.u)

        endif

    endmethod

    

    private method onDestroy takes nothing returns nothing

		if (.u != null) then

			call .removeUnit()

		endif

        call .level.monstersSimplePatrol.setMonsterNull(.arrayId)

        set MonsterSimplePatrol.nbInstances = MonsterSimplePatrol.nbInstances - 1

    endmethod

	

	static method create takes MonsterType mt, real x1, real y1, real x2, real y2 returns MonsterSimplePatrol

		local MonsterSimplePatrol m = MonsterSimplePatrol.allocate()

        set MonsterSimplePatrol.nbInstances = MonsterSimplePatrol.nbInstances + 1

        set m.mt = mt

		set m.x1 = x1

		set m.y1 = y1

		set m.x2 = x2

		set m.y2 = y2

        set m.life = 0

		return m

	endmethod

	

	method createUnit takes nothing returns nothing

        if (.u != null) then

            call .removeUnit()

        endif

        set .u = NewPatrolMonster(.mt, .x1, .y1, .x2, .y2)

        call SetUnitUserData(.u, integer(this))

        call GroupAddUnit(simplePatrolMobs, .u)

        if (.mt.isClickable()) then

            set .life = .mt.getMaxLife()

            call GroupAddUnit(monstersClickable, .u)

        endif

	endmethod   

	

    method getLife takes nothing returns integer

        return .life

    endmethod	

    

    method setLife takes integer life returns nothing

        set .life = life

        if (life > 0) then

            call SetUnitLifeBJ(.u, I2R(life) - 0.5)

        else

            call .killUnit()

        endif

    endmethod

    

    method getMonsterType takes nothing returns MonsterType

        return .mt

    endmethod 

    

    method toString takes nothing returns string

        local string str

        if (.mt.alias != null and .mt.alias != "") then

            set str = .mt.alias + CACHE_SEPARATEUR_PARAM

        else

            set str = .mt.label + CACHE_SEPARATEUR_PARAM

        endif

        set str = str + I2S(R2I(.x1)) + CACHE_SEPARATEUR_PARAM + I2S(R2I(.y1)) + CACHE_SEPARATEUR_PARAM

        set str = str + I2S(R2I(.x2)) + CACHE_SEPARATEUR_PARAM + I2S(R2I(.y2))

        return str

    endmethod

endstruct





endlibrary





//===========================================================================

// Trigger: MonsterSimplePatrolArray

//===========================================================================

//TESH.scrollpos=112

//TESH.alwaysfold=0

library MonsterSimplePatrolArray needs MonsterSimplePatrol







struct MonsterSimplePatrolArray [200000] //200 niveaux * 1000 monstres

    private MonsterSimplePatrol array monsters [MAX_NB_MONSTERS]

	private integer lastInstance

    	

	static method create takes nothing returns MonsterSimplePatrolArray

		local MonsterSimplePatrolArray ma = MonsterSimplePatrolArray.allocate()

		set ma.lastInstance = -1

		return ma

	endmethod

	

	method getFirstEmpty takes nothing returns integer

		local integer i = 0

		loop

			exitwhen (i > .lastInstance or .monsters[i] == 0)

			set i = i + 1

		endloop

		return i

	endmethod	

	

    method get takes integer arrayId returns MonsterSimplePatrol

        if (arrayId < 0 or arrayId > .lastInstance) then

            return 0

        endif

        return .monsters[arrayId]

    endmethod	

    

    method getLastInstanceId takes nothing returns integer

        return .lastInstance

    endmethod

	

    method new takes MonsterType mt, real x1, real y1, real x2, real y2, boolean createUnit returns MonsterSimplePatrol

		//local integer n = .getFirstEmpty()

        local integer n = .lastInstance + 1

		if (n >= MAX_NB_MONSTERS) then

			return 0

		endif

		//if (n > .lastInstance) then

			set .lastInstance = n

		//endif

		set .monsters[n] = MonsterSimplePatrol.create(mt, x1, y1, x2, y2)

		if (createUnit) then

			call .monsters[n].createUnit()

		endif

        set .monsters[n].level = udg_levels.getLevelFromMonsterSimplePatrolArray(this)

        set .monsters[n].arrayId = n

		return .monsters[n]  

    endmethod

	

	method count takes nothing returns integer

		local integer n = 0

		local integer i = 0

		loop

			exitwhen (i > .lastInstance)

				if (.monsters[i] != 0) then

					set n = n + 1

				endif

			set i = i + 1

		endloop

		return n

	endmethod

    

    method onDestroy takes nothing returns nothing

        local integer i = 0

        loop

            exitwhen (i > .lastInstance)

                if (.monsters[i] != 0) then

                    call .monsters[i].destroy()

                endif

            set i = i + 1

        endloop

        set .lastInstance = -1

    endmethod

    

    method setMonsterNull takes integer monsterArrayId returns nothing

        set .monsters[monsterArrayId] = 0

    endmethod

    

    method clearMonster takes integer monsterId returns boolean

        local integer i = 0

        loop

            exitwhen (.monsters[i] == MonsterSimplePatrol(monsterId) or i > .lastInstance)

            set i = i + 1

        endloop

        if (i > .lastInstance) then

            return false

        endif

        call .monsters[i].destroy()

        return true

    endmethod

    

    method getMonsterNear takes real x, real y returns MonsterSimplePatrol

        local real xMob

        local real yMob

        local integer i = 0

        loop

            exitwhen (i > .lastInstance)

                if (.monsters[i] != 0 and .monsters[i].u != null) then

                    set xMob = GetUnitX(.monsters[i].u)

                    set yMob = GetUnitY(.monsters[i].u)

                    if (RAbsBJ(x - xMob) < MONSTER_NEAR_DIFF_MAX and RAbsBJ(y - yMob) < MONSTER_NEAR_DIFF_MAX) then

                        return .monsters[i]

                    endif

                endif

            set i = i + 1

        endloop

        return 0    

    endmethod

    

    method createMonsters takes nothing returns nothing

        local integer i = 0

        loop

            exitwhen (i > .lastInstance)

                if (.monsters[i] != 0) then

                    call .monsters[i].createUnit()

                endif

            set i = i + 1

        endloop

    endmethod

    

    method removeMonsters takes nothing returns nothing

        local integer i = 0

        loop

            exitwhen (i > .lastInstance)

                if (.monsters[i] != 0) then

                    call .monsters[i].removeUnit()

                endif

            set i = i + 1

        endloop

    endmethod

    

    method recreateMonstersOfType takes MonsterType mt returns nothing

        local integer i = 0

        loop

            exitwhen (i > .lastInstance)

                if (.monsters[i] != 0 and .monsters[i].getMonsterType() == mt and .monsters[i].u != null) then

                    call .monsters[i].createUnit()

                endif

            set i = i + 1

        endloop

    endmethod

    

    method removeMonstersOfType takes MonsterType mt returns nothing

        local integer i = 0

        loop

            exitwhen (i > .lastInstance)

                if (.monsters[i] != 0 and .monsters[i].getMonsterType() == mt) then

                    call .monsters[i].destroy()

                endif

            set i = i + 1

        endloop

    endmethod

endstruct





endlibrary//===========================================================================

// Trigger: MonsterMultiplePatrols

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library MonsterMultiplePatrols needs MonsterInterface //extends Monster [8000]







private function NewRegion takes real x, real y returns region

    local rect r = Rect(x-16, y-16, x+16, y+16)

    local region R = CreateRegion()

    call RegionAddRect(R, r)

    call RemoveRect(r)

    set r = null

    return R

endfunction



function MonsterMultiplePatrols_move_Actions takes nothing returns nothing 

    local Monster monster

    local MonsterMultiplePatrols MMP

    if (IsHero(GetTriggerUnit())) then

        return

    endif

    set monster = Monster(GetUnitUserData(GetTriggerUnit()))

    if (monster.getType() == MonsterMultiplePatrols.typeid) then

        set MMP = MonsterMultiplePatrols(integer(monster))

        if (MMP.getCurrentTrigger() == GetTriggeringTrigger()) then

            call MMP.nextMove()

        endif

    endif

endfunction

//===========================================================





struct MonsterMultiplePatrols extends Monster

	static integer NB_MAX_LOC = 20  

    static integer nbInstances = 0 

	static real array X [20]

	static real array Y [20]

	static integer staticLastLocInd = -1

    

    static method count takes nothing returns integer

        return MonsterMultiplePatrols.nbInstances

    endmethod

	

	static method storeNewLoc takes real x, real y returns boolean //retourne true si le nouveau point a pu être stocké

		if (MonsterMultiplePatrols.staticLastLocInd >= MonsterMultiplePatrols.NB_MAX_LOC - 1) then

			return false

		endif

		set MonsterMultiplePatrols.staticLastLocInd = MonsterMultiplePatrols.staticLastLocInd + 1

		set MonsterMultiplePatrols.X[MonsterMultiplePatrols.staticLastLocInd] = x

		set MonsterMultiplePatrols.Y[MonsterMultiplePatrols.staticLastLocInd] = y	

		return true

	endmethod

    

    static method destroyLocs takes nothing returns nothing

        set MonsterMultiplePatrols.staticLastLocInd = -1

    endmethod

    

    

    

    unit u

    private MonsterType mt

    

	private integer lastLocInd

	private integer currentMove

    private integer sens //0 : normal toujours positif, 1 : sens normal avec changement, 2 : sens inversé avec changement

    

    //! textmacro MMP_Variables takes N

	private real x$N$

	private real y$N$

	private region r$N$

	trigger t$N$

	//! endtextmacro

	//! runtextmacro MMP_Variables( "0"  )

	//! runtextmacro MMP_Variables( "1"  )

	//! runtextmacro MMP_Variables( "2"  )

	//! runtextmacro MMP_Variables( "3"  )

	//! runtextmacro MMP_Variables( "4"  )

	//! runtextmacro MMP_Variables( "5"  )

	//! runtextmacro MMP_Variables( "6"  )

	//! runtextmacro MMP_Variables( "7"  )

	//! runtextmacro MMP_Variables( "8"  )

	//! runtextmacro MMP_Variables( "9"  )

	//! runtextmacro MMP_Variables( "10" )

	//! runtextmacro MMP_Variables( "11" )

	//! runtextmacro MMP_Variables( "12" )

	//! runtextmacro MMP_Variables( "13" )

	//! runtextmacro MMP_Variables( "14" )

	//! runtextmacro MMP_Variables( "15" )

	//! runtextmacro MMP_Variables( "16" )

	//! runtextmacro MMP_Variables( "17" )

	//! runtextmacro MMP_Variables( "18" )

	//! runtextmacro MMP_Variables( "19" )

    trigger currentTrigger

    

    method getCurrentTrigger takes nothing returns trigger

        return .currentTrigger

    endmethod

	

	method removeUnit takes nothing returns nothing

        if (.u != null) then

            call GroupRemoveUnit(monstersClickable, .u)

            call RemoveUnit(.u)

            set .u = null

        endif

	endmethod

    

    method killUnit takes nothing returns nothing

        if (.u != null and IsUnitAliveBJ(.u)) then

            call KillUnit(.u)

        endif

    endmethod

    

    private method onDestroy takes nothing returns nothing

        loop

            exitwhen (not .destroyLastLoc())

        endloop

		if (.u != null) then

			call .removeUnit()

		endif

        call .level.monstersMultiplePatrols.setMonsterNull(.arrayId)

        set MonsterMultiplePatrols.nbInstances = MonsterMultiplePatrols.nbInstances - 1

    endmethod

	

	method disableTrigger takes integer id returns nothing

	//! textmacro MMP_disableTrigger takes N

	if (id == $N$) then

		call DisableTrigger(.t$N$)

		return

	endif

	//! endtextmacro

	//! runtextmacro MMP_disableTrigger( "0"  )

	//! runtextmacro MMP_disableTrigger( "1"  )

	//! runtextmacro MMP_disableTrigger( "2"  )

	//! runtextmacro MMP_disableTrigger( "3"  )

	//! runtextmacro MMP_disableTrigger( "4"  )

	//! runtextmacro MMP_disableTrigger( "5"  )

	//! runtextmacro MMP_disableTrigger( "6"  )

	//! runtextmacro MMP_disableTrigger( "7"  )

	//! runtextmacro MMP_disableTrigger( "8"  )

	//! runtextmacro MMP_disableTrigger( "9"  )

	//! runtextmacro MMP_disableTrigger( "10" )

	//! runtextmacro MMP_disableTrigger( "11" )

	//! runtextmacro MMP_disableTrigger( "12" )

	//! runtextmacro MMP_disableTrigger( "13" )

	//! runtextmacro MMP_disableTrigger( "14" )

	//! runtextmacro MMP_disableTrigger( "15" )

	//! runtextmacro MMP_disableTrigger( "16" )

	//! runtextmacro MMP_disableTrigger( "17" )

	//! runtextmacro MMP_disableTrigger( "18" )

	//! runtextmacro MMP_disableTrigger( "19" )

	endmethod

	

	method activateMove takes integer id returns nothing

	//! textmacro MMP_activateMove takes N

	if (id == $N$) then

		call EnableTrigger(.t$N$)

        set .currentTrigger = .t$N$

		call IssuePointOrder(.u, "move", .x$N$, .y$N$)

		return

	endif

	//! endtextmacro

	//! runtextmacro MMP_activateMove( "0"  )

	//! runtextmacro MMP_activateMove( "1"  )

	//! runtextmacro MMP_activateMove( "2"  )

	//! runtextmacro MMP_activateMove( "3"  )

	//! runtextmacro MMP_activateMove( "4"  )

	//! runtextmacro MMP_activateMove( "5"  )

	//! runtextmacro MMP_activateMove( "6"  )

	//! runtextmacro MMP_activateMove( "7"  )

	//! runtextmacro MMP_activateMove( "8"  )

	//! runtextmacro MMP_activateMove( "9"  )

	//! runtextmacro MMP_activateMove( "10" )

	//! runtextmacro MMP_activateMove( "11" )

	//! runtextmacro MMP_activateMove( "12" )

	//! runtextmacro MMP_activateMove( "13" )

	//! runtextmacro MMP_activateMove( "14" )

	//! runtextmacro MMP_activateMove( "15" )

	//! runtextmacro MMP_activateMove( "16" )

	//! runtextmacro MMP_activateMove( "17" )

	//! runtextmacro MMP_activateMove( "18" )

	//! runtextmacro MMP_activateMove( "19" )

	endmethod

	

	method nextMove takes nothing returns nothing

		call .disableTrigger(.currentMove)

        if (.sens == 0 or .sens == 1) then

       		if (.currentMove >= .lastLocInd) then

                if (.sens == 0) then

                    set .currentMove = 0

                else

                    set .sens = 2

                    set .currentMove = .currentMove - 1

                endif

            else

                set .currentMove = .currentMove + 1

            endif

        else //sens == 2

            if (.currentMove <= 0) then

                set .sens = 1

                set .currentMove = 1

            else

                set .currentMove = .currentMove - 1

            endif

        endif   

		call .activateMove(.currentMove)

	endmethod

	

	static method create takes MonsterType mt, string mode returns MonsterMultiplePatrols

        //mode == "normal" (0, 1, 2, 3, 0 , 1...) ou mode == "string" (0, 1, 2, 3, 2, 1...)

		local MonsterMultiplePatrols m

		local integer i

		

        if (mode != "normal" and mode != "string") then

            return 0

        endif

        

        set m = MonsterMultiplePatrols.allocate()

        set MonsterMultiplePatrols.nbInstances = MonsterMultiplePatrols.nbInstances + 1	

        set m.mt = mt

        if (mode == "normal") then

            set m.sens = 0

        else

            set m.sens = 1

        endif

		

		//! textmacro MMP_create takes N

		if ($N$ <= MonsterMultiplePatrols.staticLastLocInd) then

			set m.x$N$ = MonsterMultiplePatrols.X[$N$]

			set m.y$N$ = MonsterMultiplePatrols.Y[$N$]

			set m.r$N$ = NewRegion(m.x$N$, m.y$N$)

			set m.t$N$ = CreateTrigger()

			call DisableTrigger(m.t$N$)

			call TriggerAddAction(m.t$N$, function MonsterMultiplePatrols_move_Actions)

			call TriggerRegisterEnterRegionSimple(m.t$N$, m.r$N$)

		endif

		//! endtextmacro

		//! runtextmacro MMP_create( "0"  )

		//! runtextmacro MMP_create( "1"  )

		//! runtextmacro MMP_create( "2"  )

		//! runtextmacro MMP_create( "3"  )

		//! runtextmacro MMP_create( "4"  )

		//! runtextmacro MMP_create( "5"  )

		//! runtextmacro MMP_create( "6"  )

		//! runtextmacro MMP_create( "7"  )

		//! runtextmacro MMP_create( "8"  )

		//! runtextmacro MMP_create( "9"  )

		//! runtextmacro MMP_create( "10" )

		//! runtextmacro MMP_create( "11" )

		//! runtextmacro MMP_create( "12" )

		//! runtextmacro MMP_create( "13" )

		//! runtextmacro MMP_create( "14" )

		//! runtextmacro MMP_create( "15" )

		//! runtextmacro MMP_create( "16" )

		//! runtextmacro MMP_create( "17" )

		//! runtextmacro MMP_create( "18" )

		//! runtextmacro MMP_create( "19" )

		

		set m.lastLocInd = MonsterMultiplePatrols.staticLastLocInd

        //call Text_A("test, lastLocInd == " + I2S(m.lastLocInd))

		set m.currentMove = -1

		call MonsterMultiplePatrols.destroyLocs()

        set m.life = 0

		return m

	endmethod

	

	method createUnit takes nothing returns nothing

        if (.u != null) then

            call .removeUnit()

        endif

		if (.lastLocInd <= 0) then

			return

		endif

		set .u = NewPatrolMonster(.mt, .x0, .y0, .x1, .y1)

        call SetUnitUserData(.u, integer(this))

        set .currentMove = 1

        if (.sens == 2) then

            set .sens = 1

        endif

        call EnableTrigger(.t1)

        set .currentTrigger = .t1

        if (.mt.isClickable()) then

            set .life = .mt.getMaxLife()

            call GroupAddUnit(monstersClickable, .u)

        endif

	endmethod

	

    method getLife takes nothing returns integer

        return .life

    endmethod

    

    method setLife takes integer life returns nothing

        set .life = life

        if (life > 0) then

            call SetUnitLifeBJ(.u, I2R(life) - 0.5)

        else

            call .killUnit()

        endif

    endmethod

    

    method getX takes integer id returns real

        //! textmacro MMP_getX takes N

        if (id == $N$) then

            return .x$N$

        endif

        //! endtextmacro

		//! runtextmacro MMP_getX( "0"  )

		//! runtextmacro MMP_getX( "1"  )

		//! runtextmacro MMP_getX( "2"  )

		//! runtextmacro MMP_getX( "3"  )

		//! runtextmacro MMP_getX( "4"  )

		//! runtextmacro MMP_getX( "5"  )

		//! runtextmacro MMP_getX( "6"  )

		//! runtextmacro MMP_getX( "7"  )

		//! runtextmacro MMP_getX( "8"  )

		//! runtextmacro MMP_getX( "9"  )

		//! runtextmacro MMP_getX( "10" )

		//! runtextmacro MMP_getX( "11" )

		//! runtextmacro MMP_getX( "12" )

		//! runtextmacro MMP_getX( "13" )

		//! runtextmacro MMP_getX( "14" )

		//! runtextmacro MMP_getX( "15" )

		//! runtextmacro MMP_getX( "16" )

		//! runtextmacro MMP_getX( "17" )

		//! runtextmacro MMP_getX( "18" )

		//! runtextmacro MMP_getX( "19" )

        return 0.    

    endmethod

    

    method getY takes integer id returns real

        //! textmacro MMP_getY takes N

        if (id == $N$) then

            return .y$N$

        endif

        //! endtextmacro

		//! runtextmacro MMP_getY( "0"  )

		//! runtextmacro MMP_getY( "1"  )

		//! runtextmacro MMP_getY( "2"  )

		//! runtextmacro MMP_getY( "3"  )

		//! runtextmacro MMP_getY( "4"  )

		//! runtextmacro MMP_getY( "5"  )

		//! runtextmacro MMP_getY( "6"  )

		//! runtextmacro MMP_getY( "7"  )

		//! runtextmacro MMP_getY( "8"  )

		//! runtextmacro MMP_getY( "9"  )

		//! runtextmacro MMP_getY( "10" )

		//! runtextmacro MMP_getY( "11" )

		//! runtextmacro MMP_getY( "12" )

		//! runtextmacro MMP_getY( "13" )

		//! runtextmacro MMP_getY( "14" )

		//! runtextmacro MMP_getY( "15" )

		//! runtextmacro MMP_getY( "16" )

		//! runtextmacro MMP_getY( "17" )

		//! runtextmacro MMP_getY( "18" )

		//! runtextmacro MMP_getY( "19" )

        return 0.    

    endmethod

    

    method destroyLastLoc takes nothing returns boolean

		if (.lastLocInd == 1) then

            call DisableTrigger(.t0)

			call DestroyTrigger(.t1)

			set .t1 = null

			call RemoveRegion(.r1)

			set .r1 = null

			call RemoveUnit(.u)

			set .u = null

		endif

        //! textmacro MMP_destroyLastLoc takes N

        if (.lastLocInd == $N$) then

            call DestroyTrigger(.t$N$)

            set .t$N$ = null

            call RemoveRegion(.r$N$)

            set .r$N$ = null

            if ($N$ == .currentMove) then

                set .currentMove = .currentMove - 1

                call .activateMove(.currentMove)

            endif

        endif

        //! endtextmacro

		//! runtextmacro MMP_destroyLastLoc( "0"  )

		//! runtextmacro MMP_destroyLastLoc( "2"  )

		//! runtextmacro MMP_destroyLastLoc( "3"  )

		//! runtextmacro MMP_destroyLastLoc( "4"  )

		//! runtextmacro MMP_destroyLastLoc( "5"  )

		//! runtextmacro MMP_destroyLastLoc( "6"  )

		//! runtextmacro MMP_destroyLastLoc( "7"  )

		//! runtextmacro MMP_destroyLastLoc( "8"  )

		//! runtextmacro MMP_destroyLastLoc( "9"  )

		//! runtextmacro MMP_destroyLastLoc( "10" )

		//! runtextmacro MMP_destroyLastLoc( "11" )

		//! runtextmacro MMP_destroyLastLoc( "12" )

		//! runtextmacro MMP_destroyLastLoc( "13" )

		//! runtextmacro MMP_destroyLastLoc( "14" )

		//! runtextmacro MMP_destroyLastLoc( "15" )

		//! runtextmacro MMP_destroyLastLoc( "16" )

		//! runtextmacro MMP_destroyLastLoc( "17" )

		//! runtextmacro MMP_destroyLastLoc( "18" )

		//! runtextmacro MMP_destroyLastLoc( "19" )

        if (.lastLocInd < 0) then

            return false

        endif

        set .lastLocInd = .lastLocInd - 1

        return true

    endmethod

	

	method addNewLocAt takes integer id, real x, real y returns nothing

		//! textmacro MMP_addNewLocAt takes N

		if (id == $N$) then

			set .x$N$ = x

			set .y$N$ = y

			set .r$N$ = NewRegion(x, y)

			set .t$N$ = CreateTrigger()

			call DisableTrigger(.t$N$)

			call TriggerAddAction(.t$N$, function MonsterMultiplePatrols_move_Actions)

			call TriggerRegisterEnterRegionSimple(.t$N$, .r$N$)

			return

		endif

		//! endtextmacro

		//! runtextmacro MMP_addNewLocAt( "0"  )

		//! runtextmacro MMP_addNewLocAt( "1"  )

		//! runtextmacro MMP_addNewLocAt( "2"  )

		//! runtextmacro MMP_addNewLocAt( "3"  )

		//! runtextmacro MMP_addNewLocAt( "4"  )

		//! runtextmacro MMP_addNewLocAt( "5"  )

		//! runtextmacro MMP_addNewLocAt( "6"  )

		//! runtextmacro MMP_addNewLocAt( "7"  )

		//! runtextmacro MMP_addNewLocAt( "8"  )

		//! runtextmacro MMP_addNewLocAt( "9"  )

		//! runtextmacro MMP_addNewLocAt( "10" )

		//! runtextmacro MMP_addNewLocAt( "11" )

		//! runtextmacro MMP_addNewLocAt( "12" )

		//! runtextmacro MMP_addNewLocAt( "13" )

		//! runtextmacro MMP_addNewLocAt( "14" )

		//! runtextmacro MMP_addNewLocAt( "15" )

		//! runtextmacro MMP_addNewLocAt( "16" )

		//! runtextmacro MMP_addNewLocAt( "17" )

		//! runtextmacro MMP_addNewLocAt( "18" )

		//! runtextmacro MMP_addNewLocAt( "19" )

	endmethod

	

	method addNewLoc takes real x, real y returns integer

        if (.lastLocInd >= MonsterMultiplePatrols.NB_MAX_LOC - 1) then //nombre limite de points atteint

			return 3 //erreur 3

		endif

        if (GetLocDist(.getX(.lastLocInd), .getY(.lastLocInd), x, y) <= PATROL_DISTANCE_MIN) then

            return 2 //erreur 2

        endif

        if (.sens == 0 and GetLocDist(.x0, .y0, x, y) <= PATROL_DISTANCE_MIN) then

            return 1 //erreur 1

        endif

		set .lastLocInd = .lastLocInd + 1

		call .addNewLocAt(.lastLocInd, x, y)

		if (.lastLocInd == 1) then

            call .createUnit()

		endif

		return 0 //c'est bon, pas d'erreur

	endmethod   	

    

    method getMonsterType takes nothing returns MonsterType

        return .mt

    endmethod

    

    method toString takes nothing returns string

        local string str

        if (.mt.alias != null and .mt.alias != "") then

            set str = .mt.alias + CACHE_SEPARATEUR_PARAM

        else

            set str = .mt.label + CACHE_SEPARATEUR_PARAM

        endif

        if (.sens > 0) then

            set str = str + "string"

        else

            set str = str + "normal"

        endif

        //! textmacro MMP_loc_toString takes N

        if (.lastLocInd < $N$) then

            return str

        endif

        set str = str + CACHE_SEPARATEUR_PARAM + I2S(R2I(.x$N$)) + CACHE_SEPARATEUR_PARAM + I2S(R2I(.y$N$))

        //! endtextmacro

		//! runtextmacro MMP_loc_toString( "0"  )

		//! runtextmacro MMP_loc_toString( "1"  )

		//! runtextmacro MMP_loc_toString( "2"  )

		//! runtextmacro MMP_loc_toString( "3"  )

		//! runtextmacro MMP_loc_toString( "4"  )

		//! runtextmacro MMP_loc_toString( "5"  )

		//! runtextmacro MMP_loc_toString( "6"  )

		//! runtextmacro MMP_loc_toString( "7"  )

		//! runtextmacro MMP_loc_toString( "8"  )

		//! runtextmacro MMP_loc_toString( "9"  )

		//! runtextmacro MMP_loc_toString( "10" )

		//! runtextmacro MMP_loc_toString( "11" )

		//! runtextmacro MMP_loc_toString( "12" )

		//! runtextmacro MMP_loc_toString( "13" )

		//! runtextmacro MMP_loc_toString( "14" )

		//! runtextmacro MMP_loc_toString( "15" )

		//! runtextmacro MMP_loc_toString( "16" )

		//! runtextmacro MMP_loc_toString( "17" )

		//! runtextmacro MMP_loc_toString( "18" )

		//! runtextmacro MMP_loc_toString( "19" )

        return str

    endmethod

endstruct







endlibrary

//===========================================================================

// Trigger: MonsterMultiplePatrolsArray

//===========================================================================

//TESH.scrollpos=115

//TESH.alwaysfold=0

library MonsterMultiplePatrolsArray needs MonsterMultiplePatrols





struct MonsterMultiplePatrolsArray [200000] //200 niveaux * 1000 monstres

    private MonsterMultiplePatrols array monsters [MAX_NB_MONSTERS]

	private integer lastInstance

	

	static method create takes nothing returns MonsterMultiplePatrolsArray

		local MonsterMultiplePatrolsArray ma = MonsterMultiplePatrolsArray.allocate()

		set ma.lastInstance = -1

		return ma

	endmethod

	

	method getFirstEmpty takes nothing returns integer

		local integer i = 0

		loop

			exitwhen (i > .lastInstance or .monsters[i] == 0)

			set i = i + 1

		endloop

		return i

	endmethod	

	

    method get takes integer arrayId returns MonsterMultiplePatrols

        if (arrayId < 0 or arrayId > .lastInstance) then

            return 0

        endif

        return .monsters[arrayId]

    endmethod

    

    method getLastInstanceId takes nothing returns integer

        return .lastInstance

    endmethod	

	

    method new takes MonsterType mt, string mode, boolean createUnit returns MonsterMultiplePatrols

		local integer n

        if (mode != "normal" and mode != "string") then

            return 0

        endif

        //set n = .getFirstEmpty()

        set n = .lastInstance + 1

		if (n >= MAX_NB_MONSTERS) then

			return 0

		endif

		//if (n > .lastInstance) then

			set .lastInstance = n

		//endif

		set .monsters[n] = MonsterMultiplePatrols.create(mt, mode)

        if (createUnit) then

            call .monsters[n].createUnit()

        endif

        set .monsters[n].level = udg_levels.getLevelFromMonsterMultiplePatrolsArray(this)

        set .monsters[n].arrayId = n

		return .monsters[n]   

    endmethod	

	

	method count takes nothing returns integer

		local integer n = 0

		local integer i = 0

		loop

			exitwhen (i > .lastInstance)

				if (.monsters[i] != 0) then

					set n = n + 1

				endif

			set i = i + 1

		endloop

		return n

	endmethod

    

    method onDestroy takes nothing returns nothing

        local integer i = 0

        loop

            exitwhen (i > .lastInstance)

                if (.monsters[i] != 0) then

                    call .monsters[i].destroy()

                endif

            set i = i + 1

        endloop

        set .lastInstance = -1

    endmethod

    

    method setMonsterNull takes integer monsterArrayId returns nothing

        set .monsters[monsterArrayId] = 0

    endmethod



    method clearMonster takes integer monsterId returns boolean

        local integer i = 0

        loop

            exitwhen (.monsters[i] == MonsterMultiplePatrols(monsterId) or i > .lastInstance)

            set i = i + 1

        endloop

        if (i > .lastInstance) then

            return false

        endif

        call .monsters[i].destroy()

        return true

    endmethod

    

    method getMonsterNear takes real x, real y returns MonsterMultiplePatrols

        local real xMob

        local real yMob

        local integer i = 0

        loop

            exitwhen (i > .lastInstance)

                if (.monsters[i] != 0 and .monsters[i].u != null) then

                    set xMob = GetUnitX(.monsters[i].u)

                    set yMob = GetUnitY(.monsters[i].u)

                    if (RAbsBJ(x - xMob) < MONSTER_NEAR_DIFF_MAX and RAbsBJ(y - yMob) < MONSTER_NEAR_DIFF_MAX) then

                        return .monsters[i]

                    endif

                endif

            set i = i + 1

        endloop

        return 0    

    endmethod

    

    method createMonsters takes nothing returns nothing

        local integer i = 0

        loop

            exitwhen (i > .lastInstance)

                if (.monsters[i] != 0) then

                    call .monsters[i].createUnit()

                endif

            set i = i + 1

        endloop

    endmethod

    

    method removeMonsters takes nothing returns nothing

        local integer i = 0

        loop

            exitwhen (i > .lastInstance)

                if (.monsters[i] != 0) then

                    call .monsters[i].removeUnit()

                endif

            set i = i + 1

        endloop

    endmethod

    

    method recreateMonstersOfType takes MonsterType mt returns nothing

        local integer i = 0

        loop

            exitwhen (i > .lastInstance)

                if (.monsters[i] != 0 and .monsters[i].getMonsterType() == mt and .monsters[i].u != null) then

                    call .monsters[i].createUnit()

                endif

            set i = i + 1

        endloop

    endmethod

    

    method removeMonstersOfType takes MonsterType mt returns nothing

        local integer i = 0

        loop

            exitwhen (i > .lastInstance)

                if (.monsters[i] != 0 and .monsters[i].getMonsterType() == mt) then

                    call .monsters[i].destroy()

                endif

            set i = i + 1

        endloop

    endmethod

endstruct





endlibrary//===========================================================================

// Trigger: MonsterSpawn

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library MonsterSpawn needs MonsterCreationFunctions





private function RemoveEnumMonster takes nothing returns nothing

    call RemoveUnit(GetEnumUnit())

endfunction



globals

    private hashtable ht //pour retrouver les MonsterSpawn correspondant aux triggers et régions

    private constant real DECALAGE_UNSPAWN = 200 //décalage de l'ordre de déplacement au delà de la région d'unspawn

    private constant real DELAY_BETWEEN_SPAWN_AND_MOVEMENT = 0.5

endglobals



private function MonsterStartMovement takes nothing returns nothing

    local timer mobTimer = GetExpiredTimer()

    local MonsterSpawn ms = MonsterSpawn(LoadInteger(ht, 1, GetHandleId(mobTimer)))

    local unit mobUnit = LoadUnitHandle(ht, 2, GetHandleId(mobTimer))

    call ms.startMobMovement(mobUnit)

    call UnitAddAbility(mobUnit, 'Aloc')

    call DestroyTimer(mobTimer)

    set mobUnit = null

    set mobTimer = null

endfunction    



private function MonsterSpawn_Actions takes nothing returns nothing

    local MonsterSpawn ms = MonsterSpawn(LoadInteger(ht, 0, GetHandleId(GetTriggeringTrigger())))

    local unit mobUnit = ms.createMob()

    local timer mobTimer = CreateTimer()

    call SaveInteger(ht, 1, GetHandleId(mobTimer), integer(ms))

    call SaveUnitHandle(ht, 2, GetHandleId(mobTimer), mobUnit)

    call TimerStart(mobTimer, DELAY_BETWEEN_SPAWN_AND_MOVEMENT, false, function MonsterStartMovement)

    call SetUnitOwner(mobUnit, ENNEMY_PLAYER, false)

    call ShowUnit(mobUnit, false)

    call UnitRemoveAbility(mobUnit, 'Aloc')

    call GroupAddUnit(ms.monsters, mobUnit)

    set mobUnit = null

    set mobTimer = null

endfunction



private function UnspawMonster_Actions takes nothing returns nothing

    local MonsterSpawn ms = MonsterSpawn(LoadInteger(ht, 0, GetHandleId(GetTriggeringTrigger())))

    if(IsUnitInGroup(GetTriggerUnit(), ms.monsters))then

        call GroupRemoveUnit(ms.monsters, GetTriggerUnit())

        call RemoveUnit(GetTriggerUnit())

    endif

endfunction

    





struct MonsterSpawn

    private static method onInit takes nothing returns nothing

        set ht = InitHashtable()

        //0, tSpawn --> MonsterSpawn

        //0, tUnspawn --> MonsterSpawn

        //1, timer --> MonsterSpawn

        //2, timer --> unité mob

    endmethod

    

    private string label

    private MonsterType mt

    private string sens //leftToRight, upToDown, rightToLeft, downToUp

    private real frequence

    private real minX

    private real minY

    private real maxX

    private real maxY

    private trigger tSpawn

    private trigger tUnspawn

    private region unspawnReg

    group monsters

    

    Level level

    integer arrayId

    

    

    public method getLabel takes nothing returns string

        return .label

    endmethod

    

    

    method desactivate takes nothing returns nothing

		if(.unspawnReg != null)then

            call RemoveRegion(.unspawnReg)

            set .unspawnReg = null

        endif

        if(.tSpawn != null)then

            call DestroyTrigger(.tSpawn)

            set .tSpawn = null

        endif

        if(.tUnspawn != null)then

            call DestroyTrigger(.tUnspawn)

            set .tUnspawn = null

        endif

        if(.monsters != null)then

            call ForGroup(.monsters, function RemoveEnumMonster)

            call DestroyGroup(.monsters)

            set .monsters = null

        endif

    endmethod

    

    private method createUnspawnReg takes nothing returns nothing

        local rect r

        local real x1

        local real y1

        local real x2

        local real y2

        //leftToRight, upToDown, rightToLeft, downToUp

        if(.sens == "leftToRight")then

            set x1 = .maxX

            set x2 = .maxX

            set y1 = .minY - DECALAGE_UNSPAWN

            set y2 = .maxY + DECALAGE_UNSPAWN

        elseif(.sens == "upToDown")then

            set x1 = .minX - DECALAGE_UNSPAWN

            set x2 = .maxX + DECALAGE_UNSPAWN

            set y1 = .minY

            set y2 = .minY

        elseif(.sens == "rightToLeft")then

            set x1 = .minX

            set x2 = .minX

            set y1 = .minY - DECALAGE_UNSPAWN

            set y2 = .maxY + DECALAGE_UNSPAWN

        else //downToUp

            set x1 = .minX - DECALAGE_UNSPAWN

            set x2 = .maxX + DECALAGE_UNSPAWN

            set y1 = .maxY

            set y2 = .maxY

        endif

        set r = Rect(x1, y1, x2, y2)

        set .unspawnReg = CreateRegion()

        call RegionAddRect(.unspawnReg, r)

        call RemoveRect(r)

    endmethod

    

    method activate takes nothing returns nothing

        set .monsters = CreateGroup()

        set .tSpawn = CreateTrigger()

        call SaveInteger(ht, 0, GetHandleId(.tSpawn), integer(this))

        call TriggerRegisterTimerEvent(.tSpawn, 1/.frequence, true)

        call TriggerAddAction(.tSpawn, function MonsterSpawn_Actions)

        call .createUnspawnReg()

        set .tUnspawn = CreateTrigger()

        call SaveInteger(ht, 0, GetHandleId(.tUnspawn), integer(this))

        call TriggerRegisterEnterRegion(.tUnspawn, .unspawnReg, null)

        call TriggerAddAction(.tUnspawn, function UnspawMonster_Actions)

    endmethod

    

    private method onDestroy takes nothing returns nothing

        call .desactivate()

        call .level.monsterSpawns.setMonsterSpawnNull(.arrayId)

    endmethod

	

	static method create takes string label, MonsterType mt, string sens, real frequence, real x1, real y1, real x2, real y2 returns MonsterSpawn

		local MonsterSpawn ms = MonsterSpawn.allocate()

        set ms.label = label

        set ms.mt = mt

        set ms.sens = sens

        set ms.frequence = frequence

        set ms.minX = RMinBJ(x1, x2)

        set ms.minY = RMinBJ(y1, y2)

        set ms.maxX = RMaxBJ(x1, x2)

        set ms.maxY = RMaxBJ(y1, y2)

		return ms

	endmethod

    

    method startMobMovement takes unit mobUnit returns nothing

        local player p

        local real x1

        local real y1

        local real x2

        local real y2

        //leftToRight, upToDown, rightToLeft, downToUp

        if(.sens == "leftToRight")then

            set x1 = .minX

            set x2 = .maxX + DECALAGE_UNSPAWN

            set y1 = GetRandomReal(.minY, .maxY)

            set y2 = y1

        elseif(.sens == "upToDown")then

            set x1 = GetRandomReal(.minX, .maxX)

            set x2 = x1

            set y1 = .maxY

            set y2 = .minY - DECALAGE_UNSPAWN

        elseif(.sens == "rightToLeft")then

            set x1 = .maxX

            set x2 = .minX - DECALAGE_UNSPAWN

            set y1 = GetRandomReal(.minY, .maxY)

            set y2 = y1

        else //downToUp

            set x1 = GetRandomReal(.minX, .maxX)

            set x2 = x1

            set y1 = .minY

            set y2 = .maxY + DECALAGE_UNSPAWN

        endif

        call SetUnitX(mobUnit, x1)

        call SetUnitY(mobUnit, y1)

        if (udg_monsterTypes.monsterUnit2MonsterType(mobUnit).isClickable()) then

            set p = ENNEMY_PLAYER

        else

            set p = GetCurrentMonsterPlayer()

        endif

        call SetUnitOwner(mobUnit, p, false)

        call ShowUnit(mobUnit, true)

        call IssuePointOrder(mobUnit, "move", x2, y2)

    endmethod

    

    public method createMob takes nothing returns unit

        local real angle

        //leftToRight, upToDown, rightToLeft, downToUp

        if(.sens == "leftToRight")then

            set angle = 180

        elseif(.sens == "upToDown")then

            set angle = 90

        elseif(.sens == "rightToLeft")then

            set angle = 0

        else //downToUp

            set angle = -90

        endif

        return NewImmobileMonsterForPlayer(.mt, ENNEMY_PLAYER, (.minX + .maxX)/2, (minY + .maxY)/2, angle)

    endmethod

    

    public method setLabel takes string newLabel returns nothing

        set .label = newLabel

    endmethod



    public method setMonsterType takes MonsterType mt returns nothing

        set .mt = mt

    endmethod

    

    public method setSens takes string sens returns nothing

        set .sens = sens

        call .desactivate()

        call .activate()

    endmethod

    

    public method setFrequence takes real frequence returns nothing

        set .frequence = frequence

        call DestroyTrigger(.tSpawn)

        set .tSpawn = CreateTrigger()

        call SaveInteger(ht, 0, GetHandleId(.tSpawn), integer(this))

        call TriggerRegisterTimerEvent(.tSpawn, 1/.frequence, true)

        call TriggerAddAction(.tSpawn, function MonsterSpawn_Actions)

    endmethod

    

    public method displayForPlayer takes player p returns nothing

        local string display = udg_colorCode[GREY] + .label + " : " + .mt.label + "   " + sens + "   " + R2S(frequence)

        call Text_P_timed(p, TERRAIN_DATA_DISPLAY_TIME, display)

    endmethod



    public method toString takes nothing returns string

        local string str = .label + CACHE_SEPARATEUR_PARAM

        if (.mt.alias != null and .mt.alias != "") then

            set str = str + .mt.alias + CACHE_SEPARATEUR_PARAM

        else

            set str = str + .mt.label + CACHE_SEPARATEUR_PARAM

        endif

        set str = str + .sens + CACHE_SEPARATEUR_PARAM + R2S(.frequence) + CACHE_SEPARATEUR_PARAM

        set str = str + I2S(R2I(.minX)) + CACHE_SEPARATEUR_PARAM + I2S(R2I(minY)) + CACHE_SEPARATEUR_PARAM + I2S(R2I(.maxX)) + CACHE_SEPARATEUR_PARAM + I2S(R2I(.maxY))

        return str

    endmethod



endstruct





endlibrary//===========================================================================

// Trigger: MonsterSpawnArray

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library MonsterSpawnArray needs MonsterSpawn





struct MonsterSpawnArray [20000] //200 levels * 100 monster spawns

    private MonsterSpawn array monsterSpawns[100]

	private integer lastInstance

	

	static method create takes nothing returns MonsterSpawnArray

		local MonsterSpawnArray msa = MonsterSpawnArray.allocate()

		set msa.lastInstance = -1

		return msa

	endmethod

	

	method getFirstEmpty takes nothing returns integer

		local integer i = 0

		loop

			exitwhen (i > .lastInstance or .monsterSpawns[i] == 0)

			set i = i + 1

		endloop

		return i

	endmethod	

	

    method get takes integer arrayId returns MonsterSpawn

        if (arrayId < 0 or arrayId > .lastInstance) then

            return 0

        endif

        return .monsterSpawns[arrayId]

    endmethod

    

    method getFromLabel takes string label returns MonsterSpawn

		local integer i = 0

		loop

			exitwhen (i > .lastInstance)

				if (.monsterSpawns[i].getLabel() == label) then

					return .monsterSpawns[i]

				endif

			set i = i + 1

		endloop

		return 0

	endmethod

    

    method getLastInstanceId takes nothing returns integer

        return .lastInstance

    endmethod

	

    method new takes string label, MonsterType mt, string sens, real frequence, real x1, real y1, real x2, real y2, boolean activate returns MonsterSpawn //retourne le monsterSpawn s'il a pu être créé, 0 sinon

		//local integer n = .getFirstEmpty()

        local integer n = .lastInstance + 1

		if (n >= MAX_NB_MONSTERS) then

			return 0

		endif

        if(.getFromLabel(label) != 0)then

            return 0

        endif

		//if (n > .lastInstance) then

			set .lastInstance = n

		//endif

        set .monsterSpawns[n] = MonsterSpawn.create(label, mt, sens, frequence, x1, y1, x2, y2)

        if(activate)then

            call .monsterSpawns[n].activate()

        endif

        set .monsterSpawns[n].level = udg_levels.getLevelFromMonsterSpawnArray(this)

        set .monsterSpawns[n].arrayId = n

		return .monsterSpawns[n]   

    endmethod

    

    method count takes nothing returns integer

		local integer n = 0

		local integer i = 0

		loop

			exitwhen (i > .lastInstance)

				if (.monsterSpawns[i] != 0) then

					set n = n + 1

				endif

			set i = i + 1

		endloop

		return n

	endmethod

    

    method onDestroy takes nothing returns nothing

        local integer i = 0

        loop

            exitwhen (i > .lastInstance)

                if (.monsterSpawns[i] != 0) then

                    call .monsterSpawns[i].destroy()

                endif

            set i = i + 1

        endloop

        set .lastInstance = -1

    endmethod

    

    method setMonsterSpawnNull takes integer monsterSpawnArrayId returns nothing

        set .monsterSpawns[monsterSpawnArrayId] = 0

    endmethod

    

    method clearMonsterSpawn takes string label returns boolean

        local MonsterSpawn ms = .getFromLabel(label)

        if(ms != 0)then

            call ms.destroy()

            set ms = 0

            return true

        else

            return false

        endif

    endmethod

    

    public method setMonsterType takes string label, MonsterType mt returns boolean

        local MonsterSpawn ms = .getFromLabel(label)

        if(ms == 0)then

            return false

        endif

        call ms.setMonsterType(mt)

        return true

    endmethod

    

    public method setSens takes string label, string sens returns boolean

        local MonsterSpawn ms = .getFromLabel(label)

        if(ms == 0)then

            return false

        endif

        call ms.setSens(sens)

        return true

    endmethod

    

    public method setFrequence takes string label, real frequence returns boolean

        local MonsterSpawn ms = .getFromLabel(label)

        if(ms == 0)then

            return false

        endif

        call ms.setFrequence(frequence)

        return true

    endmethod

    

    public method activate takes nothing returns nothing

        local integer i = 0

        loop

            exitwhen i > .lastInstance

                if(.monsterSpawns[i] != 0)then

                    call .monsterSpawns[i].activate()

                endif

            set i = i + 1

        endloop

    endmethod

    

    public method desactivate takes nothing returns nothing

        local integer i = 0

        loop

            exitwhen i > .lastInstance

                if(.monsterSpawns[i] != 0)then

                    call .monsterSpawns[i].desactivate()

                endif

            set i = i + 1

        endloop

    endmethod

    

    method displayForPlayer takes player p returns nothing

        local integer nbMs = 0

        local integer i = 0

        loop

            exitwhen (i > .lastInstance)

                if(.monsterSpawns[i] != 0)then

                    call .monsterSpawns[i].displayForPlayer(p)

                    set nbMs = nbMs + 1

                endif

            set i = i + 1

        endloop

        if (nbMs == 0) then

            call Text_erP(p, "no monster spawn for this level")

        endif

    endmethod

    

    method changeLabel takes string oldLabel, string newLabel returns boolean

        if(.getFromLabel(oldLabel) == 0 or .getFromLabel(newLabel) != 0)then

            return false

        endif

        call .getFromLabel(oldLabel).setLabel(newLabel)

        return true

    endmethod

endstruct





endlibrary

//===========================================================================

// Trigger: Terrain type functions

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library TerrainTypeFunctions





function TerrainTypeId2TerrainType takes integer terrainTypeId returns TerrainType

    local integer i = 0

    loop

        exitwhen (i >= udg_terrainTypes.numberOfWalk)

            if (udg_terrainTypes.getWalk(i).getTerrainTypeId() == terrainTypeId) then

                return udg_terrainTypes.getWalk(i)

            endif

        set i = i + 1

    endloop

    set i = 0

    loop

        exitwhen (i >= udg_terrainTypes.numberOfDeath)

            if (udg_terrainTypes.getDeath(i).getTerrainTypeId() == terrainTypeId) then

                return udg_terrainTypes.getDeath(i)

            endif

        set i = i + 1

    endloop

    set i = 0

    loop

        exitwhen (i >= udg_terrainTypes.numberOfSlide)

            if (udg_terrainTypes.getSlide(i).getTerrainTypeId() == terrainTypeId) then

                return udg_terrainTypes.getSlide(i)

            endif

        set i = i + 1

    endloop

    return 0

endfunction







function IsTerrainTypeOfKind takes integer terrainTypeId, string terrainTypeKind returns boolean

    local TerrainType terrainType = TerrainTypeId2TerrainType(terrainTypeId)

    if (terrainType == 0) then

        return false

    endif

    return (terrainTypeKind == terrainType.getKind())

endfunction









endlibrary//===========================================================================

// Trigger: TerrainType

//===========================================================================

//TESH.scrollpos=50

//TESH.alwaysfold=0

library TerrainType needs TerrainTypeFunctions, TerrainFunctions





struct TerrainType 

    string label

    string alias

    string kind

	integer terrainTypeId

	

	method setType takes integer terrainTypeId returns nothing

		set .terrainTypeId = terrainTypeId

	endmethod

    

	method setLabel takes string label returns nothing

		set .label = label

	endmethod

	

	method setAlias takes string alias returns nothing

		set .alias = alias

	endmethod

	

	method getTerrainTypeId takes nothing returns integer

		return .terrainTypeId

	endmethod

	

	method setTerrainTypeId takes integer terrainTypeId returns boolean

        if (not CanUseTerrain(terrainTypeId)) then

            return false

        endif 

		set .terrainTypeId = terrainTypeId

        return true

	endmethod

	

	method getKind takes nothing returns string

		return .kind

	endmethod

    

    method onDestroy takes nothing returns nothing

        set .label = null

        set .alias = null

        set .kind = null

        set .terrainTypeId = 0

    endmethod

    

    method displayForPlayer takes player p returns nothing

        local string space = "   "

        local TerrainTypeSlide slide

        local TerrainTypeWalk walk

        local TerrainTypeDeath death

        local string display

        if (.kind == "slide") then

            set slide = TerrainTypeSlide(integer(this))

            set display = COLOR_TERRAIN_SLIDE + .label + " " + .alias + " : '" + Ascii2String(.terrainTypeId) + "'" + space

            set display = display + I2S(R2I(slide.getSlideSpeed()/SLIDE_PERIOD))

        else

        if (.kind == "walk") then

            set walk = TerrainTypeWalk(integer(this))

            set display = COLOR_TERRAIN_WALK + .label + " " + .alias + " : '" + Ascii2String(.terrainTypeId) + "'" + space

            set display = display + I2S(R2I(walk.getWalkSpeed()))

        else

        if (.kind == "death") then

            set death = TerrainTypeDeath(integer(this))

            set display = COLOR_TERRAIN_DEATH + .label + " " + .alias + " : '" + Ascii2String(.terrainTypeId) + "'" + space

            set display = display + R2S(death.getTimeToKill()) + space + death.getKillingEffectStr()

        endif

        endif

        endif

        call Text_P_timed(p, TERRAIN_DATA_DISPLAY_TIME, display)

    endmethod

    

    method toString takes nothing returns string

        local TerrainTypeSlide slide

        local TerrainTypeWalk walk

        local TerrainTypeDeath death

        local string str = .label + CACHE_SEPARATEUR_PARAM + .alias + CACHE_SEPARATEUR_PARAM

        set str = str + .kind + CACHE_SEPARATEUR_PARAM + Ascii2String(.terrainTypeId) + CACHE_SEPARATEUR_PARAM

        if (.kind == "slide") then

            set slide = TerrainTypeSlide(integer(this))

            set str = str + I2S(R2I(slide.getSlideSpeed() / SLIDE_PERIOD))

        else

        if (.kind == "walk") then

            set walk = TerrainTypeWalk(integer(this))

            set str = str + I2S(R2I(walk.getWalkSpeed()))

        else

        if (.kind == "death") then

            set death = TerrainTypeDeath(integer(this))

            set str = str + death.getKillingEffectStr() + CACHE_SEPARATEUR_PARAM

            set str = str + R2S(death.getTimeToKill())

        endif

        endif

        endif

        return str

    endmethod

endstruct





endlibrary//===========================================================================

// Trigger: TerrainTypeWalk

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library TerrainTypeWalk needs TerrainType





struct TerrainTypeWalk extends TerrainType

	private real walkSpeed

	

	static method create takes string label, integer terrainTypeId, real walkSpeed returns TerrainTypeWalk

		local TerrainTypeWalk tt 

        if (not CanUseTerrain(terrainTypeId)) then

            return 0

        endif        

        set tt = TerrainTypeWalk.allocate()

		set tt.label = label

        set tt.alias = null

		set tt.terrainTypeId = terrainTypeId

        set tt.walkSpeed = walkSpeed

        set tt.kind = "walk"

        return tt

	endmethod

	

	method getWalkSpeed takes nothing returns real

		return .walkSpeed

	endmethod

	

	method setWalkSpeed takes real walkSpeed returns nothing

		set .walkSpeed = walkSpeed

	endmethod

endstruct











endlibrary//===========================================================================

// Trigger: TerrainTypeDeath functions

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library TerrainTypeDeathFunctions needs TerrainType









function TerrainKillTimer2Escaper takes timer theTimer returns Escaper

	local trigger terrainKillTrigger = GetTriggeringTrigger()

	local integer terrainTypeDeathMaxId = udg_terrainTypes.numberOfDeath - 1

	local integer terrainTypeDeathId 

	local integer escaperId = 0

	

	set terrainTypeDeathId = 0

	loop

		exitwhen (terrainTypeDeathId > terrainTypeDeathMaxId)

			set escaperId = 0

			loop

				exitwhen (escaperId > 11)

					if (theTimer == udg_terrainTypes.getDeath(terrainTypeDeathId).getTimer(escaperId)) then

                        return udg_escapers.get(escaperId)

                    endif

				set escaperId = escaperId + 1

			endloop

		set terrainTypeDeathId = terrainTypeDeathId + 1

	endloop

    

	return 0

endfunction





function DeathTerrainKillEscaper_Actions takes nothing returns nothing

	local Escaper escaper = TerrainKillTimer2Escaper(GetExpiredTimer())

    if (escaper == 0) then

        return

    endif

	call escaper.pause(false)

	call escaper.destroyTerrainKillEffect()	

	if (escaper.currentLevelTouchTerrainDeath == udg_levels.getCurrentLevel()) then

		call escaper.kill()

    else

        if(escaper.isAlive())then

            call escaper.enableCheckTerrain(true)

        endif

	endif

endfunction





endlibrary



//===========================================================================

// Trigger: TerrainTypeDeath KillingTimers

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library TerrainTypeDeathKillingTimers needs TerrainTypeDeathFunctions





struct KillingTimers

	private timer array timers [12]

    

	private method onDestroy takes nothing returns nothing

        local integer i = 0

		loop

			exitwhen (i > 11)

				call DestroyTimer(.timers[i])

				set .timers[i] = null

            set i = i + 1

		endloop

	endmethod

    

    static method create takes nothing returns KillingTimers

        local KillingTimers kt = KillingTimers.allocate()

        local integer i

        set i = 0

        loop

            exitwhen (i > 11)

                //if (udg_escapers.get(i) != 0) then //si l'escaper existe

                //si on laisse le filtre if les escapers apparus après le début (via un -createHero) ne meurent plus avec les terrains

                    set kt.timers[i] = CreateTimer()

                //endif

            set i = i + 1

        endloop

        return kt

    endmethod

	

	method start takes integer timerId, real time returns nothing

		call TimerStart(.timers[timerId], time, false, function DeathTerrainKillEscaper_Actions)

		set udg_escapers.get(timerId).currentLevelTouchTerrainDeath = udg_levels.getCurrentLevel()

	endmethod

    

    method get takes integer id returns timer

        return .timers[id]

    endmethod    

endstruct





endlibrary//===========================================================================

// Trigger: TerrainTypeDeath

//===========================================================================

//TESH.scrollpos=17

//TESH.alwaysfold=0

library TerrainTypeDeath needs TerrainTypeDeathKillingTimers





struct TerrainTypeDeath extends TerrainType

	private string killingEffectStr

	private real timeToKill  //en secondes

	private KillingTimers killingTimers

	

	static method create takes string label, integer terrainTypeId, string killingEffectStr, real timeToKill returns TerrainTypeDeath

		local integer i

		local TerrainTypeDeath tt

        if (not CanUseTerrain(terrainTypeId)) then

            return 0

        endif      

        set tt = TerrainTypeDeath.allocate()

		set tt.label = label

        set tt.alias = null

		set tt.terrainTypeId = terrainTypeId

		set tt.killingEffectStr = killingEffectStr

		set tt.timeToKill = timeToKill

		set tt.killingTimers = KillingTimers.create()

		set tt.kind = "death"

		return tt

	endmethod

	

	private method onDestroy takes nothing returns nothing

		call .killingTimers.destroy()			

	endmethod

	

	method setKillingEffectStr takes string killingEffectStr returns nothing

		set .killingEffectStr = killingEffectStr

	endmethod

	

	method getKillingEffectStr takes nothing returns string

		return .killingEffectStr

	endmethod

	

	method setTimeToKill takes real newTimeToKill returns boolean

        if (newTimeToKill < 0) then

            return false

        endif

		set .timeToKill = newTimeToKill

        return true

	endmethod

    

    method getTimeToKill takes nothing returns real

        return .timeToKill

    endmethod

	

	method killEscaper takes Escaper escaper returns nothing

		call escaper.enableCheckTerrain(false)

        call escaper.enableSlide(false)

        call escaper.pause(true)

		call escaper.createTerrainKillEffect(.killingEffectStr)

		call .killingTimers.start(escaper.getId(), .timeToKill)

	endmethod

    

    method getTimer takes integer escaperId returns timer

        return .killingTimers.get(escaperId)

    endmethod		

endstruct





endlibrary//===========================================================================

// Trigger: TerrainTypeSlide

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library TerrainTypeSlide needs TerrainType





struct TerrainTypeSlide extends TerrainType

	private real slideSpeed

	

	

	static method create takes string label, integer terrainTypeId, real slideSpeed returns TerrainTypeSlide

		local TerrainTypeSlide tt

        if (not CanUseTerrain(terrainTypeId)) then

            return 0

        endif   

        set tt = TerrainTypeSlide.allocate()

		set tt.label = label

        set tt.alias = null

		set tt.terrainTypeId = terrainTypeId

        set tt.kind = "slide"

		set tt.slideSpeed = slideSpeed * SLIDE_PERIOD

        return tt

	endmethod

    

    method getSlideSpeed takes nothing returns real

        return .slideSpeed

    endmethod

    

    method setSlideSpeed takes real slideSpeed returns nothing

        set .slideSpeed = slideSpeed * SLIDE_PERIOD

    endmethod

endstruct









endlibrary//===========================================================================

// Trigger: TerrainTypeArray

//===========================================================================

//TESH.scrollpos=224

//TESH.alwaysfold=0

library TerrainTypeArray needs TerrainTypeWalk, TerrainTypeDeath, TerrainTypeSlide





struct TerrainTypeArray

    private TerrainTypeWalk array ttWalk [177] //le nombre de terrains du jeu est de 177

    private TerrainTypeDeath array ttDeath [177]

    private TerrainTypeSlide array ttSlide [177]

    integer numberOfWalk

    integer numberOfDeath

    integer numberOfSlide

    

    static method create takes nothing returns TerrainTypeArray

        local TerrainTypeArray tta = TerrainTypeArray.allocate()

        set tta.numberOfWalk = 0

        set tta.numberOfDeath = 0

        set tta.numberOfSlide = 0

        return tta

    endmethod    

    

    method get takes string label returns TerrainType

		local integer i = 0

		loop

			exitwhen (i >= .numberOfWalk)

				if (.ttWalk[i].label == label or .ttWalk[i].alias == label) then

					return .ttWalk[i]

				endif

			set i = i + 1

		endloop

		set i = 0

		loop

			exitwhen (i >= .numberOfDeath)

				if (.ttDeath[i].label == label or .ttDeath[i].alias == label) then

					return .ttDeath[i]

				endif

			set i = i + 1

		endloop

		set i = 0

		loop

			exitwhen (i >= .numberOfSlide)

				if (.ttSlide[i].label == label or .ttSlide[i].alias == label) then

					return .ttSlide[i]

				endif

			set i = i + 1

		endloop

		return 0

	endmethod

	

	method getTerrainType takes real x, real y returns TerrainType

		local integer terrainTypeId = GetTerrainType(x, y)

		local integer i = 0

		loop

			exitwhen (i >= .numberOfWalk)

				if (.ttWalk[i].getTerrainTypeId() == terrainTypeId) then

					return .ttWalk[i]

				endif

			set i = i + 1

		endloop

		set i = 0

		loop

			exitwhen (i >= .numberOfDeath)

				if (.ttDeath[i].getTerrainTypeId() == terrainTypeId) then

					return .ttDeath[i]

				endif

			set i = i + 1

		endloop

		set i = 0

		loop

			exitwhen (i >= .numberOfSlide)

				if (.ttSlide[i].getTerrainTypeId() == terrainTypeId) then

					return .ttSlide[i]

				endif

			set i = i + 1

		endloop

		return 0

	endmethod

    

    method isTerrainTypeIdAlreadyUsed takes integer terrainTypeId returns boolean

        local integer i = 0

        loop

            exitwhen (i >= .numberOfWalk)

                if (terrainTypeId == .ttWalk[i].getTerrainTypeId()) then

                    return true

                endif

            set i = i + 1

        endloop

        set i = 0

        loop

            exitwhen (i >= .numberOfDeath)

                if (terrainTypeId == .ttDeath[i].getTerrainTypeId()) then

                    return true

                endif

            set i = i + 1

        endloop

        set i = 0

        loop

            exitwhen (i >= .numberOfSlide)

                if (terrainTypeId == .ttSlide[i].getTerrainTypeId()) then

                    return true

                endif

            set i = i + 1

        endloop

        return false

    endmethod

	

	method isLabelAlreadyUsed takes string label returns boolean

		return (.get(label) != 0)

	endmethod

    

    method newWalk takes string label, integer terrainTypeId, real walkspeed returns TerrainTypeWalk

        local integer n = .numberOfWalk

        if (.isLabelAlreadyUsed(label) or .isTerrainTypeIdAlreadyUsed(terrainTypeId) or terrainTypeId == 0) then

            return 0

        endif

        set .ttWalk[n] = TerrainTypeWalk.create(label, terrainTypeId, walkspeed)

        if (.ttWalk[n] != 0) then

            set .numberOfWalk = .numberOfWalk + 1

        endif

        return .ttWalk[n]

    endmethod

    

    method newDeath takes string label, integer terrainTypeId, string killingEffectStr, real timeToKill returns TerrainTypeDeath

        local integer n = .numberOfDeath

        if (.isLabelAlreadyUsed(label) or .isTerrainTypeIdAlreadyUsed(terrainTypeId) or terrainTypeId == 0) then

            return 0

        endif

        set .ttDeath[n] = TerrainTypeDeath.create(label, terrainTypeId, killingEffectStr, timeToKill)

        if (.ttDeath[n] != 0) then

            set .numberOfDeath = .numberOfDeath + 1

        endif

        return .ttDeath[n]

    endmethod

    

    method newSlide takes string label, integer terrainTypeId, real slideSpeed returns TerrainTypeSlide

        local integer n = .numberOfSlide

        if (.isLabelAlreadyUsed(label) or .isTerrainTypeIdAlreadyUsed(terrainTypeId) or terrainTypeId == 0) then

            return 0

        endif

        set .ttSlide[n] = TerrainTypeSlide.create(label, terrainTypeId, slideSpeed)

        if (.ttSlide[n] != 0) then

            set .numberOfSlide = .numberOfSlide + 1

        endif

        return .ttSlide[n]

    endmethod

    

    method remove takes string label returns boolean

        local integer position

        local integer i

        local TerrainType tt = .get(label)

        if (tt == 0) then

            return false

        endif

        if (tt.kind == "walk") then

            set i = 0

            loop

                exitwhen (.ttWalk[i].label == label or .ttWalk[i].alias == label or i >= .numberOfWalk)

                set i = i + 1

            endloop

            if (i < .numberOfWalk) then

                set position = i

                set i = i + 1

                loop

                    exitwhen (i >= .numberOfWalk)

                        set .ttWalk[i-1] = .ttWalk[i]

                    set i = i + 1

                endloop

                set .numberOfWalk = .numberOfWalk - 1

            endif

        endif

        if (tt.kind == "death") then

            set i = 0

            loop

                exitwhen (.ttDeath[i].label == label or .ttDeath[i].alias == label or i >= .numberOfDeath)

                set i = i + 1

            endloop

            if (i < .numberOfDeath) then

                set position = i

                set i = i + 1

                loop

                    exitwhen (i >= .numberOfDeath)

                        set .ttDeath[i-1] = .ttDeath[i]

                    set i = i + 1

                endloop

                set .numberOfDeath = .numberOfDeath - 1

            endif

        endif

        if (tt.kind == "slide") then

            set i = 0

            loop

                exitwhen (.ttSlide[i].label == label or .ttSlide[i].alias == label or i >= .numberOfSlide)

                set i = i + 1

            endloop

            if (i < .numberOfSlide) then

                set position = i

                set i = i + 1

                loop

                    exitwhen (i >= .numberOfSlide)

                        set .ttSlide[i-1] = .ttSlide[i]

                    set i = i + 1

                endloop

                set .numberOfSlide = .numberOfSlide - 1

            endif

        endif

        call tt.destroy()

        return true

    endmethod

    

    method getWalk takes integer id returns TerrainTypeWalk

        return .ttWalk[id]

    endmethod

    

    method getDeath takes integer id returns TerrainTypeDeath

        return .ttDeath[id]

    endmethod

    

    method getSlide takes integer id returns TerrainTypeSlide

        return .ttSlide[id]

    endmethod

    

    method displayForPlayer takes player p returns nothing

        local integer i = 0

        loop

            exitwhen (i >= .numberOfSlide)

                call .ttSlide[i].displayForPlayer(p)

            set i = i + 1

        endloop

        set i = 0

        loop

            exitwhen (i >= .numberOfWalk)

                call .ttWalk[i].displayForPlayer(p)

            set i = i + 1

        endloop

        set i = 0

        loop

            exitwhen (i >= .numberOfDeath)

                call .ttDeath[i].displayForPlayer(p)

            set i = i + 1

        endloop

        if (.numberOfSlide + .numberOfWalk + .numberOfDeath == 0) then

            call Text_erP(p, "no terrain saved")

        endif

    endmethod

    

    method saveInCache takes nothing returns nothing

        local integer i

        set stringArrayForCache = StringArrayForCache.create("terrain", "terrainConfig", true)

        set i = 0

        loop

            exitwhen (i >= .numberOfSlide)

                call stringArrayForCache.push(.ttSlide[i].toString())

            set i = i + 1

        endloop

        set i = 0

        loop

            exitwhen (i >= .numberOfWalk)

                call stringArrayForCache.push(.ttWalk[i].toString())

            set i = i + 1

        endloop

        set i = 0

        loop

            exitwhen (i >= .numberOfDeath)

                call stringArrayForCache.push(.ttDeath[i].toString())

            set i = i + 1

        endloop

        call stringArrayForCache.writeInCache()

    endmethod

endstruct

    

    





endlibrary//===========================================================================

// Trigger: Time of game trigger

//===========================================================================

//TESH.scrollpos=16

//TESH.alwaysfold=0

library GameTime initializer Init_GameTime



globals    

    private integer hours = 0

    private integer minuts = 0

    private integer seconds = 0

    player TIME_PLAYER = Player(0)

endglobals









function Trig_time_of_game_Actions takes nothing returns nothing

    local string timeStr

    local string hourStr

    local string minStr

    local string secStr

    

    //set integers

    if (seconds >= 59) then

        set seconds = 0

        if (minuts >= 59) then

            set minuts = 0

            set hours = hours + 1

        else

            set minuts = minuts + 1

        endif

    else

        set seconds = seconds + 1

    endif

    

    

    //set strings

    set hourStr = I2S(hours)

    

    if (minuts < 10) then

        set minStr = "0" + I2S(minuts)

    else

        set minStr = I2S(minuts)

    endif

    

    if (seconds < 10) then

        set secStr = "0" + I2S(seconds)

    else

        set secStr = I2S(seconds)

    endif

    

    set timeStr = "|Cfffed312 Game time :  " + hourStr + " h  " + minStr + " min  " + secStr + " s" 

    call LeaderboardSetPlayerItemLabelBJ(TIME_PLAYER, udg_lives.getLeaderboard(), timeStr)

endfunction







//===========================================================================

function Init_GameTime takes nothing returns nothing

    set gg_trg_Time_of_game_trigger = CreateTrigger(  )

    call TriggerAddAction( gg_trg_Time_of_game_trigger, function Trig_time_of_game_Actions )

    call TriggerRegisterTimerEvent( gg_trg_Time_of_game_trigger, 1., true)

endfunction





endlibrary

//===========================================================================

// Trigger: Lives and game time

//===========================================================================

//TESH.scrollpos=52

//TESH.alwaysfold=0

library Lives needs BasicFunctions





globals

    private player LIVES_PLAYER = Player(6) //GREEN

endglobals





struct Lives

	private integer nb

    private leaderboard lb

    

	

//leaderboard methods

    method display takes boolean show returns nothing

        call LeaderboardDisplay(.lb, show)

    endmethod

    

    method refresh takes nothing returns nothing

		call LeaderboardSetPlayerItemValueBJ(LIVES_PLAYER, .lb, .nb)

	endmethod

    

    method getLeaderboard takes nothing returns leaderboard

        return .lb

    endmethod

	



//creation methods

	static method create takes nothing returns Lives

        local Lives l = Lives.allocate()

        if (udg_levels.get(0) != 0) then

            set l.nb = udg_levels.get(0).getNbLives()

        else

            set l.nb = NB_LIVES_AT_BEGINNING

        endif

        set l.lb = CreateLeaderboardBJ(GetPlayersAll(), "")

        call LeaderboardAddItemBJ(Player(0), l.lb, "Game time", 0)

        call LeaderboardSetPlayerItemStyleBJ(Player(0), l.lb, true, false, false )

        call LeaderboardAddItemBJ(LIVES_PLAYER, l.lb, "Lives :", l.nb)

        call l.display(true)

        return l

    endmethod

    

    

	private method onDestroy takes nothing returns nothing

		call DestroyLeaderboard(.lb)

		set .lb = null

	endmethod



	

//lives methods

    method get takes nothing returns integer

        return .nb

    endmethod

	

	method setNb takes integer nbLives returns boolean

        local string wordLives

		if (nbLives < 0) then

			return false

		endif

		set .nb = nbLives

		call .refresh()

		if (nbLives > 1) then

            set wordLives = " lives."

        else

            set wordLives = " life."

        endif

		call Text_A(udg_colorCode[GetPlayerId(LIVES_PLAYER)] + "You have now " + I2S(nbLives) + wordLives)

        return true

	endmethod

    

    method add takes integer n returns nothing

        local string wordLives

        if (n > 1) then

            set wordLives = " lives !"

        else

            set wordLives = " life."

        endif

        set .nb = .nb + n

        call Text_A(udg_colorCode[1] + "You have earned " + I2S(n) + wordLives)

        call .refresh()

    endmethod

    

    method loseALife takes nothing returns nothing

        set .nb = .nb - 1

        if (.nb >= 0) then

            call .refresh()

        endif

    endmethod

endstruct









endlibrary







//===========================================================================

// Trigger: Meteor

//===========================================================================

//TESH.scrollpos=20

//TESH.alwaysfold=0

library Meteor





globals

    constant integer METEOR_NORMAL = 'MND1'

    constant integer METEOR_CHEAT = 'MCD1'

endglobals







struct Meteor [20000] //100 météores * 200 niveaux

    private real x

    private real y

    private item meteor

    Level level

    integer arrayId

    

    method getItem takes nothing returns item

        return .meteor

    endmethod

    

    static method create takes real x, real y returns Meteor

        local Meteor m = Meteor.allocate()

        set m.x = x

        set m.y = y

        return m

    endmethod

    

    method removeMeteor takes nothing returns nothing

        if (.meteor != null) then

            call RemoveItem(.meteor)

            set .meteor = null

        endif

    endmethod

    

    method createMeteor takes nothing returns nothing

        if (.meteor != null) then

            call .removeMeteor()

        endif

        set .meteor = CreateItem(METEOR_NORMAL, .x, .y)

        if (udg_terrainTypes.getTerrainType(.x, .y).getKind() == "slide") then

            call SetItemDroppable(.meteor, false)

        endif

        call SetItemUserData(.meteor, integer(this))

    endmethod

    

    private method onDestroy takes nothing returns nothing

        if (.meteor != null) then

            call .removeMeteor()

            set .meteor = null

        endif

        call .level.meteors.setMeteorNull(.arrayId)

    endmethod

    

    method replace takes nothing returns nothing

        call SetItemPosition(.meteor, .x, .y)

    endmethod

    

    method toString takes nothing returns string

        return (I2S(R2I(.x)) + CACHE_SEPARATEUR_PARAM + I2S(R2I(.y)))

    endmethod

endstruct







endlibrary

//===========================================================================

// Trigger: MeteorArray

//===========================================================================

//TESH.scrollpos=99

//TESH.alwaysfold=0

library MeteorArray needs Meteor



globals

    private constant integer MAX_NB_METEORS = 100 //par niveau

endglobals







struct MeteorArray [20000] //200 niveaux * 100 météores

    private Meteor array meteors [MAX_NB_METEORS]

    private integer lastInstance

    

	static method create takes nothing returns MeteorArray

		local MeteorArray ma = MeteorArray.allocate()

		set ma.lastInstance = -1

		return ma

	endmethod

	

	method getFirstEmpty takes nothing returns integer

		local integer i = 0

		loop

			exitwhen (i > .lastInstance or .meteors[i] == 0)

			set i = i + 1

		endloop

		return i

	endmethod	

	

    method get takes integer arrayId returns Meteor

        if (arrayId < 0 or arrayId > .lastInstance) then

            return 0

        endif

        return .meteors[arrayId]

    endmethod

	

    method new takes real x, real y, boolean createMeteor returns Meteor //retourne la météore si elle a pu être créée, 0 sinon

		//local integer n = .getFirstEmpty()

        local integer n = .lastInstance + 1

		if (n >= MAX_NB_METEORS) then

			return 0

		endif

		//if (n > .lastInstance) then

			set .lastInstance = n

		//endif

		set .meteors[n] = Meteor.create(x, y)

		if (createMeteor) then

			call .meteors[n].createMeteor()

		endif

        set .meteors[n].level = udg_levels.getLevelFromMeteorArray(this)

        set .meteors[n].arrayId = n

		return .meteors[n]   

    endmethod

    

    method setMeteorNull takes integer arrayId returns nothing

        set .meteors[arrayId] = 0

    endmethod

	

	method count takes nothing returns integer

		local integer n = 0

		local integer i = 0

		loop

			exitwhen (i > .lastInstance)

				if (.meteors[i] != 0) then

					set n = n + 1

				endif

			set i = i + 1

		endloop

		return n

	endmethod

    

    method onDestroy takes nothing returns nothing

        local integer i = 0

        loop

            exitwhen (i > .lastInstance)

                if (.meteors[i] != 0) then

                    call .meteors[i].destroy()

                endif

            set i = i + 1

        endloop

        set .lastInstance = -1

    endmethod

    

    method clearMeteor takes integer meteorId returns boolean

        local integer i = 0

        loop

            exitwhen (.meteors[i] == Meteor(meteorId) or i > .lastInstance)

            set i = i + 1

        endloop

        if (i > .lastInstance) then

            return false

        endif

        call .meteors[i].destroy()

        set .meteors[i] = 0

        return true

    endmethod

    

    method createMeteors takes nothing returns nothing

        local integer i = 0

        loop

            exitwhen (i > .lastInstance)

                if (.meteors[i] != 0) then

                    call .meteors[i].createMeteor()

                endif

            set i = i + 1

        endloop

    endmethod

    

    method removeMeteors takes nothing returns nothing

        local integer i = 0

        loop

            exitwhen (i > .lastInstance)

                if (.meteors[i] != 0) then

                    call .meteors[i].removeMeteor()

                endif

            set i = i + 1

        endloop

    endmethod

    

    method getMeteorNear takes real x, real y returns Meteor

        local real xMeteor

        local real yMeteor

        local integer i = 0

        loop

            exitwhen (i > .lastInstance)

                if (.meteors[i] != 0 and .meteors[i].getItem() != null) then

                    set xMeteor = GetItemX(.meteors[i].getItem())

                    set yMeteor = GetItemY(.meteors[i].getItem())

                    if (RAbsBJ(x - xMeteor) < MONSTER_NEAR_DIFF_MAX and RAbsBJ(y - yMeteor) < MONSTER_NEAR_DIFF_MAX) then

                        return .meteors[i]

                    endif

                endif

            set i = i + 1

        endloop

        return 0    

    endmethod

    

    method getLastInstanceId takes nothing returns integer

        return .lastInstance

    endmethod

endstruct









endlibrary



//===========================================================================

// Trigger: Meteor functions

//===========================================================================

//TESH.scrollpos=4

//TESH.alwaysfold=0

library MeteorFunctions needs Meteor





globals

    private item meteor

endglobals







function HeroAddCheatMeteor takes unit hero returns item

    set meteor = UnitAddItemById(hero, METEOR_CHEAT)

    if (udg_terrainTypes.getTerrainType(GetUnitX(hero), GetUnitY(hero)).getKind() == "slide") then

        call SetItemDroppable(meteor, false)

    endif

    return meteor

endfunction





function HeroComingToSlide_CheckItem takes unit hero returns nothing

    set meteor = UnitItemInSlot(hero, 0)

    if (meteor != null) then

        call SetItemDroppable(meteor, false)

    endif

endfunction





function HeroComingOutFromSlide_CheckItem takes unit hero returns nothing

    set meteor = UnitItemInSlot(hero, 0)

    if (meteor != null) then

        call SetItemDroppable(meteor, true)

    endif

endfunction





function ExecuteRightClicOnUnit takes unit hero, unit u returns nothing

    local item itemCarried = UnitItemInSlot(hero, 0)

    local integer itemCarriedType = GetItemTypeId(itemCarried)

    if ((itemCarriedType == METEOR_NORMAL or itemCarriedType == METEOR_CHEAT) and GetWidgetLife(u) > 0.) then

        call UnitUseItemTarget(hero, itemCarried, u)

    else

        call StopUnit(hero)

    endif 

    set itemCarried = null    

endfunction







endlibrary





//===========================================================================

// Trigger: Right click on widget

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

function Trig_right_click_on_widget_Conditions takes nothing returns boolean

    return (IsHero(GetTriggerUnit()) and IsIssuedOrder("smart"))

endfunction





function Trig_right_click_on_widget_Actions takes nothing returns nothing

    if (GetOrderTargetUnit() != null) then

        call ExecuteRightClicOnUnit(GetTriggerUnit(), GetOrderTargetUnit())  

    endif

endfunction





//===========================================================================

function InitTrig_Right_click_on_widget takes nothing returns nothing

    set gg_trg_Right_click_on_widget = CreateTrigger(  )

    call TriggerRegisterAnyUnitEventBJ(gg_trg_Right_click_on_widget, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER)

    call TriggerAddAction(gg_trg_Right_click_on_widget, function Trig_right_click_on_widget_Actions)

    call TriggerAddCondition(gg_trg_Right_click_on_widget, Condition(function Trig_right_click_on_widget_Conditions))

endfunction



//===========================================================================

// Trigger: Meteor being used

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

function Trig_meteor_being_used_Actions takes nothing returns nothing

    call SetUnitAnimation(GetTriggerUnit(), "attack")

    if (GetItemTypeId(GetManipulatedItem()) == METEOR_NORMAL) then

        call DisableTrigger(GetTriggeringTrigger())

        call EnableTrigger(gg_trg_Stop_using_normal_meteor)

        call Meteor(GetItemUserData(GetManipulatedItem())).removeMeteor()

        call Hero2Escaper(GetTriggerUnit()).removeEffectMeteor()

        call TriggerSleepAction(1.)

        call EnableTrigger(GetTriggeringTrigger())

        call DisableTrigger(gg_trg_Stop_using_normal_meteor)

    endif

endfunction



//===========================================================================

function InitTrig_Meteor_being_used takes nothing returns nothing

    set gg_trg_Meteor_being_used = CreateTrigger(  )

    call TriggerRegisterAnyUnitEventBJ( gg_trg_Meteor_being_used, EVENT_PLAYER_UNIT_USE_ITEM )

    call TriggerAddAction( gg_trg_Meteor_being_used, function Trig_meteor_being_used_Actions )

endfunction



//===========================================================================

// Trigger: Stop using normal meteor

//===========================================================================

function Trig_Stop_using_normal_meteor_Conditions takes nothing returns boolean

    if ( not ( GetSpellAbilityId() == 'A002' ) ) then

        return false

    endif

    return true

endfunction



function Trig_Stop_using_normal_meteor_Actions takes nothing returns nothing

    call IssueImmediateOrderBJ( GetTriggerUnit(), "stop" )

endfunction



//===========================================================================

function InitTrig_Stop_using_normal_meteor takes nothing returns nothing

    set gg_trg_Stop_using_normal_meteor = CreateTrigger(  )

    call DisableTrigger( gg_trg_Stop_using_normal_meteor )

    call TriggerRegisterAnyUnitEventBJ( gg_trg_Stop_using_normal_meteor, EVENT_PLAYER_UNIT_SPELL_CAST )

    call TriggerAddCondition( gg_trg_Stop_using_normal_meteor, Condition( function Trig_Stop_using_normal_meteor_Conditions ) )

    call TriggerAddAction( gg_trg_Stop_using_normal_meteor, function Trig_Stop_using_normal_meteor_Actions )

endfunction



//===========================================================================

// Trigger: Effect meteor on pick up

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

function Trig_Effect_meteor_on_pick_up_Conditions takes nothing returns boolean

    return GetItemTypeId(UnitItemInSlotBJ(GetTriggerUnit(), 1)) == METEOR_NORMAL

endfunction



function Trig_Effect_meteor_on_pick_up_Actions takes nothing returns nothing

    call Hero2Escaper(GetTriggerUnit()).addEffectMeteor()

endfunction



//===========================================================================

function InitTrig_Effect_meteor_on_pick_up takes nothing returns nothing

    set gg_trg_Effect_meteor_on_pick_up = CreateTrigger(  )

    call TriggerRegisterAnyUnitEventBJ( gg_trg_Effect_meteor_on_pick_up, EVENT_PLAYER_UNIT_PICKUP_ITEM )

    call TriggerAddCondition( gg_trg_Effect_meteor_on_pick_up, Condition( function Trig_Effect_meteor_on_pick_up_Conditions ) )

    call TriggerAddAction( gg_trg_Effect_meteor_on_pick_up, function Trig_Effect_meteor_on_pick_up_Actions )

endfunction



//===========================================================================

// Trigger: VisibilityModifier

//===========================================================================

//TESH.scrollpos=10

//TESH.alwaysfold=0

library VisibilityModifier





struct VisibilityModifier [20000]

	private real x1

	private real y1

	private real x2

	private real y2

	private fogmodifier fm

    Level level

    integer arrayId

	

	static method create takes real x1, real y1, real x2, real y2 returns VisibilityModifier

		local VisibilityModifier vm = VisibilityModifier.allocate()

		local rect visionRect = Rect(x1, y1, x2, y2)

		set vm.x1 = x1

		set vm.y1 = y1

		set vm.x2 = x2

		set vm.y2 = y2

        set vm.fm = CreateFogModifierRect(Player(0), FOG_OF_WAR_VISIBLE, visionRect, true, false)

		call RemoveRect(visionRect)

		set visionRect = null

        call RefreshHideAllVM()

		return vm

	endmethod

	

	private method onDestroy takes nothing returns nothing

		call DestroyFogModifier(.fm)

		set .fm = null

        call .level.visibilities.setNull(.arrayId)

	endmethod

	

	method activate takes boolean activ returns nothing

		if (activ) then

			call FogModifierStart(.fm)

		else

			call FogModifierStop(.fm)

		endif

	endmethod

    

    method copy takes nothing returns VisibilityModifier

        return VisibilityModifier.create(.x1, .y1, .x2, .y2) 

    endmethod

    

    method toString takes nothing returns string

        local string x1 = I2S(R2I(.x1))

        local string y1 = I2S(R2I(.y1))

        local string x2 = I2S(R2I(.x2))

        local string y2 = I2S(R2I(.y2))

        return (x1 + CACHE_SEPARATEUR_PARAM + y1 + CACHE_SEPARATEUR_PARAM + x2 + CACHE_SEPARATEUR_PARAM + y2)

    endmethod

endstruct









endlibrary//===========================================================================

// Trigger: VisibilityModifierArray

//===========================================================================

//TESH.scrollpos=62

//TESH.alwaysfold=0

library VisibilityModifierArray needs VisibilityModifier





struct VisibilityModifierArray [20000]

	private VisibilityModifier array vms [200] 

	private integer lastInstance

	

	

	static method create takes nothing returns VisibilityModifierArray

		local VisibilityModifierArray v = VisibilityModifierArray.allocate()

		set v.lastInstance = -1

		return v

	endmethod

    

	private method onDestroy takes nothing returns nothing

		local integer i = 0

		loop

			exitwhen (i > .lastInstance)

				call .vms[i].destroy()

			set i = i + 1

		endloop

		set .lastInstance = -1

	endmethod

    

	method new takes real x1, real y1, real x2, real y2 returns VisibilityModifier

		if (.lastInstance >= 199) then

			return 0

		endif

        set .lastInstance = .lastInstance + 1

        set .vms[.lastInstance] = VisibilityModifier.create(x1, y1, x2, y2)

        set .vms[.lastInstance].level = udg_levels.getLevelFromVisibilityModifierArray(this)

        set .vms[.lastInstance].arrayId = .lastInstance

		return .vms[.lastInstance]

	endmethod

    

    method newFromExisting takes VisibilityModifier vm returns VisibilityModifier

        if (.lastInstance >= 199) then

            return 0

        endif

        set .lastInstance = .lastInstance + 1

        set .vms[.lastInstance] = vm

        return vm

    endmethod

	

	method count takes nothing returns integer

        local integer n = 0

        local integer i = 0

        loop

            exitwhen (i > .lastInstance)

                if (.vms[i] != 0) then

                    set n = n + 1

                endif

            set i = i + 1

        endloop

		return n

	endmethod

    

    method get takes integer visibilityId returns VisibilityModifier

        if (visibilityId < 0 or visibilityId > .lastInstance) then

            return 0

        endif

        return .vms[visibilityId]

    endmethod

    

    method getLastInstanceId takes nothing returns integer

        return .lastInstance

    endmethod

    

    method setNull takes integer arrayId returns nothing

        if (arrayId >= 0 and arrayId <= .lastInstance) then

            set .vms[arrayId] = 0

        endif

    endmethod

    

    method removeAllVisibilityModifiers takes nothing returns nothing

        loop

            exitwhen (.lastInstance < 0)

                call .vms[.lastInstance].destroy()

            set .lastInstance = .lastInstance - 1

        endloop

    endmethod

	

	method removeLasts takes integer numberOfVMToRemove returns boolean //renvoie true si tous sont supprimés

		local integer i = numberOfVMToRemove

		loop

			exitwhen (i <= 0 or .lastInstance < 0)

				call .vms[.lastInstance].destroy()

				set .lastInstance = .lastInstance - 1

			set i = i - 1

		endloop	

        return (i == 0)

	endmethod

	

	method activate takes boolean activ returns nothing

		local integer i = 0

		loop

			exitwhen (i > .lastInstance)

				call .vms[i].activate(activ)

			set i = i + 1

		endloop

	endmethod

endstruct









endlibrary



			//===========================================================================

// Trigger: StartAndEnd

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library StartAndEnd initializer Init_StartAndEnd needs BasicFunctions, Escaper





interface RectInterface

    real minX

    real minY

    real maxX

    real maxY

    rect r

    method toString takes nothing returns string

endinterface





globals

    Start DEPART_PAR_DEFAUT

endglobals





struct Start extends RectInterface

    static method create takes real x1, real y1, real x2, real y2 returns Start

        local Start s = Start.allocate()

        set s.minX = RMinBJ(x1, x2)

        set s.minY = RMinBJ(y1, y2)

        set s.maxX = RMaxBJ(x1, x2)

        set s.maxY = RMaxBJ(y1, y2)

        set s.r  = Rect(s.minX, s.minY, s.maxX, s.maxY)

        return s

    endmethod

	

	private method onDestroy takes nothing returns nothing

		call RemoveRect(.r)

		set .r = null

	endmethod

	

	method getRandomX takes nothing returns real

		return GetRandomReal(.minX, .maxX)

    endmethod

    

	method getRandomY takes nothing returns real

		return GetRandomReal(.minY, .maxY )

    endmethod

	

	method getCenterX takes nothing returns real

		return GetRectCenterX(.r)

    endmethod

    

	method getCenterY takes nothing returns real

		return GetRectCenterY(.r)

    endmethod

    

    method toString takes nothing returns string

        local string minX = I2S(R2I(.minX))

        local string minY = I2S(R2I(.minY))

        local string maxX = I2S(R2I(.maxX))

        local string maxY = I2S(R2I(.maxY))

        return (minX + CACHE_SEPARATEUR_PARAM + minY + CACHE_SEPARATEUR_PARAM + maxX + CACHE_SEPARATEUR_PARAM + maxY)

    endmethod

endstruct











function EndReaching_Actions takes nothing returns nothing

    local Escaper finisher = Hero2Escaper(GetTriggerUnit())

    if (finisher == 0) then

        return

    endif

    if (not udg_levels.goToNextLevel(finisher)) then

        call Text_A("Good job ! You have finished the game.")

        call TriggerSleepAction(2)

        call Text_A("restart in 10 seconds")

        call TriggerSleepAction(10)

        call udg_levels.restartTheGame()

    endif

endfunction





struct End extends RectInterface

    private trigger endReaching



    static method create takes real x1, real y1, real x2, real y2 returns End

        local End e = End.allocate()

        set e.minX = RMinBJ(x1, x2)

        set e.minY = RMinBJ(y1, y2)

        set e.maxX = RMaxBJ(x1, x2)

        set e.maxY = RMaxBJ(y1, y2)

        set e.r  = Rect(e.minX, e.minY, e.maxX, e.maxY)

        set e.endReaching = CreateTrigger()

        call TriggerAddAction(e.endReaching, function EndReaching_Actions)

        call TriggerRegisterEnterRectSimple(e.endReaching, e.r)

        call DisableTrigger(e.endReaching)

        return e

    endmethod

    

    method activate takes boolean activ returns nothing

        if activ then

            call EnableTrigger(.endReaching)

        else

            call DisableTrigger(.endReaching)

        endif

    endmethod

    

    private method onDestroy takes nothing returns nothing

		call RemoveRect(.r)

		set .r = null

        call DestroyTrigger(.endReaching)

        set .endReaching = null

    endmethod   

    

    method toString takes nothing returns string

        local string minX = I2S(R2I(.minX))

        local string minY = I2S(R2I(.minY))

        local string maxX = I2S(R2I(.maxX))

        local string maxY = I2S(R2I(.maxY))

        return (minX + CACHE_SEPARATEUR_PARAM + minY + CACHE_SEPARATEUR_PARAM + maxX + CACHE_SEPARATEUR_PARAM + maxY)

    endmethod     

endstruct











//===========================================================================

function Init_StartAndEnd takes nothing returns nothing

    set DEPART_PAR_DEFAUT = Start.create(-500, -500, 500, 500)

endfunction







endlibrary

//===========================================================================

// Trigger: Triggers

//===========================================================================

//TESH.scrollpos=17

//TESH.alwaysfold=0

library Triggers





struct Trigger

    private trigger t

    

    

    private method onDestroy takes nothing returns nothing

        call DestroyTrigger(.t)

        set .t = null

    endmethod

    

    static method create takes nothing returns Trigger

        local Trigger t = Trigger.allocate()

        set t.t = CreateTrigger()

        return t

    endmethod

    

    method activate takes boolean activ returns nothing

        if (activ) then

            call EnableTrigger(.t)

        else

            call DisableTrigger(.t)

        endif

    endmethod

endstruct





struct TriggerArray

    private Trigger array triggers [200]

    private integer lastInstance

    

    

    static method create takes nothing returns TriggerArray

        local TriggerArray ta = TriggerArray.allocate()

        set ta.lastInstance = -1

        return ta

    endmethod

    

    private method onDestroy takes nothing returns nothing

        local integer i = 0

        loop

            exitwhen (i > .lastInstance)

                call .triggers[i].destroy()

            set i = i + 1

        endloop

        set .lastInstance = -1

    endmethod

    

    method activate takes boolean activ returns nothing

        local integer i = 0

        loop

            exitwhen (i > .lastInstance)

                if (.triggers[i] != 0) then

                    call .triggers[i].activate(activ)

                endif

            set i = i + 1

        endloop

    endmethod

endstruct







endlibrary//===========================================================================

// Trigger: Level

//===========================================================================

//TESH.scrollpos=154

//TESH.alwaysfold=0

library Level needs VisibilityModifierArray, StartAndEnd, Triggers, Lives



//nombre maximum de niveaux : 200. Nombre maximum de monstres de chaque type par niveau : 1000.





globals

    public boolean earningLivesActivated = true

endglobals





struct Level

    private boolean isActivatedB

    private string startMessage

    private integer livesEarnedAtBeginning

	private Start start

	private End end

	VisibilityModifierArray visibilities

	MonsterNoMoveArray monstersNoMove

	MonsterSimplePatrolArray monstersSimplePatrol

	MonsterMultiplePatrolsArray monstersMultiplePatrols

    MonsterSpawnArray monsterSpawns

    MeteorArray meteors

	private TriggerArray triggers

    

    static method create takes nothing returns Level

        local Level l = Level.allocate()

        set l.visibilities = VisibilityModifierArray.create()

        set l.triggers = TriggerArray.create()

        set l.monstersNoMove = MonsterNoMoveArray.create()

        set l.monstersSimplePatrol = MonsterSimplePatrolArray.create()

        set l.monstersMultiplePatrols = MonsterMultiplePatrolsArray.create()

        set l.monsterSpawns = MonsterSpawnArray.create()

        set l.meteors = MeteorArray.create()

        set l.livesEarnedAtBeginning = 1

        set l.isActivatedB = false

        return l

    endmethod

	

	method activate takes boolean activ returns nothing

        if (.isActivatedB == activ) then

            return

        endif

        call .end.activate(activ)

        call .triggers.activate(activ)

        if (activ) then

            if (.startMessage != null and .startMessage != "" and earningLivesActivated) then

                call Text_A(.startMessage)

            endif

            call .visibilities.activate(true)

            call .monstersNoMove.createMonsters()

            call .monstersSimplePatrol.createMonsters()

            call .monstersMultiplePatrols.createMonsters()

            call .monsterSpawns.activate()

            call .meteors.createMeteors()

            if (earningLivesActivated and .getId() > 0) then

                call udg_lives.add(.livesEarnedAtBeginning)

            endif

        else

            call .monstersNoMove.removeMonsters()

            call .monstersSimplePatrol.removeMonsters()

            call .monstersMultiplePatrols.removeMonsters()

            call .monsterSpawns.desactivate()

            call .meteors.removeMeteors()

            call udg_escapers.deleteSpecificActionsForLevel(this)

        endif

        set .isActivatedB = activ

    endmethod

    

    method checkpointReviveHeroes takes Escaper finisher returns nothing

        set TrigCheckpointReviveHeroes_levelForReviving = this

        set TrigCheckpointReviveHeroes_revivingFinisher = finisher

        call TriggerExecute(gg_trg____Trig_checkpoint_revive_heroes)    

    endmethod

    

    method getStart takes nothing returns Start

        return .start

    endmethod

    

    method getStartRandomX takes nothing returns real

        return .start.getRandomX()

    endmethod

    

    method getStartRandomY takes nothing returns real

        return .start.getRandomY()

    endmethod

    

    method newStart takes real x1, real y1, real x2, real y2 returns nothing

        call .start.destroy()

        set .start = Start.create(x1, y1, x2, y2)

    endmethod

    

    method newEnd takes real x1, real y1, real x2, real y2 returns nothing

        call .end.destroy()

        set .end = End.create(x1, y1, x2, y2)

        if (.isActivatedB) then

            call .end.activate(true)

        endif

    endmethod

    

    method getEnd takes nothing returns End

        return .end

    endmethod

	

	method getNbMonstersNoMove takes nothing returns integer

		return .monstersNoMove.count()

	endmethod

	

	method getNbMonstersSimplePatrol takes nothing returns integer

		return .monstersSimplePatrol.count()

	endmethod

	

	method getNbMonstersMultiplePatrols takes nothing returns integer

		return .monstersMultiplePatrols.count()

	endmethod

    

    method onDestroy takes nothing returns nothing

        call .start.destroy()

        call .end.destroy()

        call .visibilities.destroy()

        call .triggers.destroy()

        call .monstersNoMove.destroy()

        call .monstersSimplePatrol.destroy()

        call .monstersMultiplePatrols.destroy()

    endmethod

    

    method recreateMonstersOfType takes MonsterType mt returns nothing

        call .monstersNoMove.recreateMonstersOfType(mt)

        call .monstersSimplePatrol.recreateMonstersOfType(mt)

        call .monstersMultiplePatrols.recreateMonstersOfType(mt)

    endmethod

    

    method removeMonstersOfType takes MonsterType mt returns nothing

        call .monstersNoMove.removeMonstersOfType(mt)

        call .monstersSimplePatrol.removeMonstersOfType(mt)

        call .monstersMultiplePatrols.removeMonstersOfType(mt)

    endmethod

    

    method getId takes nothing returns integer

        local integer i = 0

        loop

            exitwhen (udg_levels.get(i) == 0)

                if (udg_levels.get(i) == this) then

                    return i

                endif

            set i = i + 1

        endloop

        return -1

    endmethod

    

    method isActivated takes nothing returns boolean

        return .isActivatedB

    endmethod

    

    method setIsActivated takes boolean activated returns nothing

        set .isActivatedB = activated

    endmethod

    

    method setNbLivesEarned takes integer nbLives returns boolean

        if (nbLives < 0) then

            return false

        endif

        set .livesEarnedAtBeginning = nbLives

        return true

    endmethod

    

    method getNbLives takes nothing returns integer

        return .livesEarnedAtBeginning

    endmethod

    

    method newVisibilityModifier takes real x1, real y1, real x2, real y2 returns VisibilityModifier

        return .visibilities.new(x1, y1, x2, y2)

    endmethod

    

    method newVisibilityModifierFromExisting takes VisibilityModifier vm returns VisibilityModifier

        return .visibilities.newFromExisting(vm)

    endmethod

    

    method removeVisibilities takes nothing returns nothing

        call .visibilities.removeAllVisibilityModifiers()

    endmethod

    

    method activateVisibilities takes boolean activate returns nothing

        call .visibilities.activate(activate)

    endmethod

    

    method setStartMessage takes string str returns nothing

        if (str == "") then

            set str = null

        endif

        set .startMessage = str

    endmethod

    

    method getStartMessage takes nothing returns string

        return .startMessage

    endmethod

endstruct

    





endlibrary

//===========================================================================

// Trigger:    Level functions

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library LevelFunctions





function IsLevelBeingMade takes Level level returns boolean

    local integer i = 0

    loop

        exitwhen (i > 11)

            if (udg_escapers.get(i) != 0) then

                if (udg_escapers.get(i).getMakingLevel() == level) then

                    return true

                endif

            endif

        set i = i + 1

    endloop

    return (udg_levels.getCurrentLevel() == level)

endfunction





endlibrary



//===========================================================================

// Trigger:    Trig checkpoint revive heroes

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library TrigCheckpointReviveHeroes initializer Init_Trig_checkpoint_revive_heroes needs ChangeAllTerrains





globals

    public Level levelForReviving

    public Escaper revivingFinisher

endglobals







function Trig_Trig_checkpoint_revive_heroes_Actions takes nothing returns nothing

    local Level l = levelForReviving

    local Escaper finisher = revivingFinisher

    local Escaper escaper

    local integer i = 0

    loop

        exitwhen (i > 11)

            set escaper = udg_escapers.get(i)

            if (escaper != 0 and escaper != finisher) then

                if (not escaper.reviveAtStart()) then

                    call escaper.moveHero(l.getStartRandomX(), l.getStartRandomY())

                    call StopUnit(escaper.getHero())

                    call escaper.pause(true)

                endif

            endif

        set i = i + 1

    endloop    

    call Text_A(udg_colorCode[GetPlayerId(finisher.getPlayer())] + "Good job " + GetPlayerName(finisher.getPlayer()) + " !")

    call TriggerSleepAction(1)

    set i = 0

    loop

        exitwhen (i > 11)

            set escaper = udg_escapers.get(i)

            if (escaper != 0 and escaper != finisher) then

                call escaper.pause(false)

            endif

        set i = i + 1

    endloop 

    if (udg_changeAllTerrainsAtRevive) then

        call TriggerSleepAction(1.00)

        call ChangeAllTerrains("normal")

    endif

endfunction



//===========================================================================

function Init_Trig_checkpoint_revive_heroes takes nothing returns nothing

    set gg_trg____Trig_checkpoint_revive_heroes = CreateTrigger(  )

    call TriggerAddAction( gg_trg____Trig_checkpoint_revive_heroes, function Trig_Trig_checkpoint_revive_heroes_Actions )

endfunction





endlibrary



//===========================================================================

// Trigger: LevelArray

//===========================================================================

//TESH.scrollpos=197

//TESH.alwaysfold=0

library LevelArray needs Level





globals

    constant integer NB_MAX_LEVELS = 200

endglobals





struct LevelArray

	private Level array levels [NB_MAX_LEVELS]

	private integer currentLevel

	private integer lastInstance

	

	

	static method create takes nothing returns LevelArray

		local real x1 = GetRectMinX(gg_rct_departLvl_0)

		local real y1 = GetRectMinY(gg_rct_departLvl_0)

		local real x2 = GetRectMaxX(gg_rct_departLvl_0)

		local real y2 = GetRectMaxY(gg_rct_departLvl_0)

		local LevelArray la = LevelArray.allocate()

        set la.levels[0] = Level.create()

		call la.levels[0].newStart(x1, y1, x2, y2)

        call la.levels[0].setNbLivesEarned(NB_LIVES_AT_BEGINNING)

        set la.currentLevel = 0

        set la.lastInstance = 0

		return la

	endmethod	

	

	method goToLevel takes Escaper finisher, integer levelId returns boolean

        local real xCam

        local real yCam

        local integer i

        local integer previousLevelId = .currentLevel

		if (levelId < 0 or levelId > .lastInstance or levelId == .currentLevel) then

			return false

		endif

		set .currentLevel = levelId

        if (previousLevelId != NB_MAX_LEVELS) then //cas spécial restart de la game

            if (not IsLevelBeingMade(.levels[previousLevelId])) then

                call udg_escapers.destroyMakesIfForSpecificLevel_currentLevel()

                call .levels[previousLevelId].activate(false)

            endif

        endif

		call .levels[.currentLevel].activate(true)

        call .levels[.currentLevel].checkpointReviveHeroes(finisher)

        if (previousLevelId != NB_MAX_LEVELS) then

            if (levelId > previousLevelId + 1) then

                set i = previousLevelId + 1

                loop

                    exitwhen (i >= levelId)

                        call .levels[i].activateVisibilities(true)

                    set i = i + 1

                endloop

            else

                if (levelId < previousLevelId) then

                    set i = levelId + 1

                    loop

                        exitwhen (i > previousLevelId)

                            call .levels[i].activateVisibilities(false)

                        set i = i + 1

                    endloop

                endif

            endif

        endif

        set xCam = .levels[levelId].getStart().getCenterX()

        set yCam = .levels[levelId].getStart().getCenterY()

        if (finisher != 0) then

            call MoveCamExceptForPlayer(finisher.getPlayer(), xCam, yCam)

        else

            call SetCameraPosition(xCam, yCam)

        endif

		return true

	endmethod

	

	method goToNextLevel takes Escaper finisher returns boolean //retourne false s'il n'y a pas de niveau suivant

        local real xCam

        local real yCam

        if (.currentLevel >= .lastInstance) then

			return false

		endif

		set .currentLevel = .currentLevel + 1

        if (not IsLevelBeingMade(.levels[.currentLevel - 1])) then

            call udg_escapers.destroyMakesIfForSpecificLevel_currentLevel()

            call .levels[.currentLevel - 1].activate(false)

        endif

		call .levels[.currentLevel].activate(true)

        call .levels[.currentLevel].checkpointReviveHeroes(finisher)

        set xCam = .levels[.currentLevel].getStart().getCenterX()

        set yCam = .levels[.currentLevel].getStart().getCenterY()

        if (finisher != 0) then

            call MoveCamExceptForPlayer(finisher.getPlayer(), xCam, yCam)

        else

            call SetCameraPosition(xCam, yCam)

        endif

        return true

	endmethod

    

    method restartTheGame takes nothing returns nothing

        if (.currentLevel == 0) then

            set .currentLevel = NB_MAX_LEVELS //pour assurer le changement de niveau

            call .levels[0].activate(false)

        endif

        call .goToLevel(0, 0)

        call udg_lives.setNb(.levels[0].getNbLives())

        call SetCameraPosition(.levels[0].getStart().getCenterX(), .levels[0].getStart().getCenterY())

    endmethod

	

	method new takes nothing returns boolean //retourne false si le nombre maximum de niveaux est déja atteint

		if (.lastInstance >= NB_MAX_LEVELS - 1) then

			return false

		endif

		set .lastInstance = .lastInstance + 1

		set .levels[.lastInstance] = Level.create()

        return true

	endmethod

    

    method destroyLastLevel takes nothing returns boolean

        if (.lastInstance <= 0) then

            return false

        endif

        call .levels[.lastInstance].destroy()

        set .lastInstance = .lastInstance - 1

        return true

    endmethod

	

	method count takes nothing returns integer

		return .lastInstance + 1

	endmethod

	

	method getCurrentLevel takes nothing returns Level

		return .levels[.currentLevel]

	endmethod

    

    method get takes integer levelId returns Level

        if (levelId > .lastInstance or levelId < 0) then

            return 0

        endif

        return .levels[levelId]

    endmethod

    

    method getLevelFromMonsterNoMoveArray takes MonsterNoMoveArray ma returns Level

        local integer i = 0

        loop

            exitwhen (i > .lastInstance or .levels[i].monstersNoMove == ma)

            set i = i + 1

        endloop

        if (i > .lastInstance) then

            return 0

        endif

        return .levels[i]

    endmethod

    method getLevelFromMonsterSimplePatrolArray takes MonsterSimplePatrolArray ma returns Level

        local integer i = 0

        loop

            exitwhen (i > .lastInstance or .levels[i].monstersSimplePatrol == ma)

            set i = i + 1

        endloop

        if (i > .lastInstance) then

            return 0

        endif

        return .levels[i]

    endmethod

    method getLevelFromMonsterMultiplePatrolsArray takes MonsterMultiplePatrolsArray ma returns Level

        local integer i = 0

        loop

            exitwhen (i > .lastInstance or .levels[i].monstersMultiplePatrols == ma)

            set i = i + 1

        endloop

        if (i > .lastInstance) then

            return 0

        endif

        return .levels[i]

    endmethod

    method getLevelFromMonsterSpawnArray takes MonsterSpawnArray msa returns Level

        local integer i = 0

        loop

            exitwhen (i > .lastInstance or .levels[i].monsterSpawns == msa)

            set i = i + 1

        endloop

        if (i > .lastInstance) then

            return 0

        endif

        return .levels[i]

    endmethod

    method getLevelFromMeteorArray takes MeteorArray ma returns Level

        local integer i = 0

        loop

            exitwhen (i > .lastInstance or .levels[i].meteors == ma)

            set i = i + 1

        endloop

        if (i > .lastInstance) then

            return 0

        endif

        return .levels[i]

    endmethod

    method getLevelFromVisibilityModifierArray takes VisibilityModifierArray vma returns Level

        local integer i = 0

        loop

            exitwhen (i > .lastInstance or .levels[i].visibilities == vma)

            set i = i + 1

        endloop

        if (i > .lastInstance) then

            return 0

        endif

        return .levels[i]

    endmethod

    

    method removeMonstersOfType takes MonsterType mt returns nothing

        local integer i = 0

        loop

            exitwhen (i > .lastInstance)

                call .levels[i].removeMonstersOfType(mt)

            set i = i + 1

        endloop

    endmethod

    

    method getLastLevelId takes nothing returns integer

        return .lastInstance

    endmethod

endstruct







function ForceGetLevel takes integer levelId returns Level

    local integer i

    local integer lastInstance

    if (levelId < 0 or levelId >= NB_MAX_LEVELS) then

        return 0

    endif

    if (udg_levels == 0) then

        set udg_levels = LevelArray.create()

    endif

    set lastInstance = udg_levels.getLastLevelId()

    loop

        exitwhen (lastInstance >= levelId)

            call udg_levels.new()

        set lastInstance = udg_levels.getLastLevelId()

    endloop

    return udg_levels.get(levelId)

endfunction







endlibrary//===========================================================================

// Trigger: EscaperEffect functions

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library EscaperEffectFunctions needs SlideTrigger, CheckTerrainTrigger, LevelFunctions





function String2BodyPartStr takes string S returns string 

    if (S == "leftHand" or S == "lh") then

        return "hand left"

    endif

    if (S == "rightHand" or S == "rh") then

        return "hand right"

    endif

    if (S == "leftFoot" or S == "lf") then

        return "foot left"

    endif

    if (S == "rightFoot" or S == "rf") then

        return "foot right"

    endif

    if (S == "overhead" or S == "oh") then

        return "overhead"

    endif

    if (S == "head" or S == "h") then

        return "head"

    endif

    if (S == "origin" or S == "o") then

        return "origin"

    endif

    if (S == "chest" or S == "c") then

        return "chest"

    endif

    return null

endfunction





function IsBodyPartStr takes string s returns boolean

    return String2BodyPartStr(s) != null

endfunction





function String2EffectStr takes string str returns string

    if (str == "light" or str == "l") then

        return "Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl"

    endif

    if (str == "fire" or str == "f") then

        return "Abilities\\Spells\\Items\\AIfb\\AIfbTarget.mdl"

    endif

    if (str == "ice" or str == "i") then

        return "Abilities\\Spells\\Items\\AIob\\AIobTarget.mdl"

    endif

    if (str == "corruption" or str == "c") then

        return "Abilities\\Spells\\Items\\OrbCorruption\\OrbCorruption.mdl"

    endif

    if (str == "poison" or str == "p") then

        return "Abilities\\Spells\\Items\\OrbVenom\\OrbVenom.mdl"

    endif

    if (str == "slow" or str == "s") then

        return "Abilities\\Spells\\Items\\OrbSlow\\OrbSlow.mdl"

    endif

    return null

endfunction





function IsEffectStr takes string str returns boolean

    return String2EffectStr(str) != null

endfunction







endlibrary

//===========================================================================

// Trigger: EscaperEffect

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library EscaperEffect needs EscaperEffectFunctions





struct EscaperEffect

	private effect ef

	private string efStr

	private string bodyPart

	



	static method create takes string efStr, unit u, string bodyPart returns EscaperEffect

		local EscaperEffect e = EscaperEffect.allocate()

		set e.efStr = efStr

		set e.bodyPart = bodyPart

		set e.ef = AddSpecialEffectTarget(efStr, u, bodyPart)

		return e

	endmethod

	

	private method onDestroy takes nothing returns nothing

        if(.ef != null)then

            call DestroyEffect(.ef)

            set .ef = null

        endif

	endmethod

	

	method recreate takes unit u returns nothing

		call .onDestroy()

		set .ef = AddSpecialEffectTarget(.efStr, u, .bodyPart)

	endmethod	



	method remove takes nothing returns nothing

		call DestroyEffect(.ef)

		set .ef = null

	endmethod

endstruct











endlibrary







//===========================================================================

// Trigger: EscaperEffectArray

//===========================================================================

//TESH.scrollpos=35

//TESH.alwaysfold=0

library EscaperEffectArray needs EscaperEffect





struct EscaperEffectArray [240]

	private EscaperEffect array efs [20]

	private integer lastInstance

	

	

	static method create takes nothing returns EscaperEffectArray

		local EscaperEffectArray e = EscaperEffectArray.allocate()

		set e.lastInstance = -1

		return e

	endmethod

	

	method new takes string efStr, unit u, string bodyPart returns nothing

		local integer i

		if (.lastInstance >= 19) then

			call .efs[0].destroy()

			set i = 0

			loop

				exitwhen (i >= 19)

					set .efs[i] = .efs[i+1]

				set i = i + 1

			endloop

		else

			set .lastInstance = .lastInstance + 1

		endif

		set .efs[.lastInstance] = EscaperEffect.create(efStr, u, bodyPart)

	endmethod

	

	method count takes nothing returns integer

		local integer n = 0

		local integer i = 0

		loop

			exitwhen (i > .lastInstance)

				if .efs[i] != 0 then

					set n = n + 1

				endif

			set i = i + 1

		endloop

		return n

	endmethod

	

	private method onDestroy takes nothing returns nothing

		loop

			exitwhen (.lastInstance < 0)

				call .efs[.lastInstance].destroy()

			set .lastInstance = .lastInstance - 1

		endloop

	endmethod

	

	method destroyLastEffects takes integer numEfToDestroy returns nothing

		local integer i = numEfToDestroy

		loop

			exitwhen (i <= 0 or .lastInstance < 0)

				call .efs[.lastInstance].destroy()

				set .lastInstance = .lastInstance - 1

			set i = i - 1

		endloop

	endmethod

	

	method hideEffects takes nothing returns nothing

		local integer i = 0

		loop

			exitwhen i > .lastInstance

				call .efs[i].remove()

			set i = i + 1

		endloop	

	endmethod

	

	method showEffects takes unit u returns nothing

		local integer i = 0

		loop

			exitwhen (i > .lastInstance)

				call .efs[i].recreate(u)

			set i = i + 1

		endloop	

	endmethod

endstruct

	



endlibrary//===========================================================================

// Trigger: Escaper functions

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library EscaperFunctions needs Text







function ColorInfo takes Escaper escaperToGetInfo, player playerToDisplay returns nothing

    local integer baseColor = escaperToGetInfo.getBaseColor()

	local string red = I2S(R2I(escaperToGetInfo.getVcRed()))

	local string green = I2S(R2I(escaperToGetInfo.getVcGreen()))

	local string blue = I2S(R2I(escaperToGetInfo.getVcBlue()))

	local string transparency = I2S(R2I(escaperToGetInfo.getVcTransparency()))

    call Text_P(playerToDisplay, "Base color : " + udg_colorCode[baseColor] + udg_baseColorString[baseColor])

    call Text_P(playerToDisplay, udg_colorCode[0] + "red     :  " + red + "  %")

    call Text_P(playerToDisplay, udg_colorCode[6] + "green :  " + green + "  %")

    call Text_P(playerToDisplay, udg_colorCode[1] + "blue   :  " + blue + "  %")

    call Text_P(playerToDisplay, udg_colorCode[8] + "transparency : " + transparency + "  %" )

endfunction





function Hero2Escaper takes unit hero returns Escaper

    if (GetUnitTypeId(hero) == HERO_TYPE_ID) then

        return udg_escapers.get(GetUnitUserData(hero))

    endif

    return 0

endfunction







endlibrary



//===========================================================================

// Trigger: Escaper disco

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library Disco





function ApplyRandomColor takes integer n returns nothing   

    local Escaper esc = udg_escapers.get(n)

    call esc.setBaseColorDisco(GetRandomInt(0, 12))

    call esc.setVcRed(GetRandomPercentageBJ())

    call esc.setVcGreen(GetRandomPercentageBJ())

    call esc.setVcBlue(GetRandomPercentageBJ())

    call esc.setVcTransparency(GetRandomReal(0, 25))

    call SetUnitVertexColorBJ(esc.getHero(), esc.getVcRed(), esc.getVcGreen(), esc.getVcBlue(), esc.getVcTransparency())

endfunction





function Disco_Actions takes nothing returns nothing

    local integer n = 0

    loop

        exitwhen (udg_escapers.get(n).discoTrigger == GetTriggeringTrigger())

            if (n > 11) then

                return

            endif

        set n = n + 1

    endloop

    call ApplyRandomColor(n)

endfunction







endlibrary//===========================================================================

// Trigger: Escaper

//===========================================================================

//TESH.scrollpos=761

//TESH.alwaysfold=0

library Escaper needs EscaperEffectArray, EscaperFunctions







globals

	constant boolean SHOW_REVIVE_EFFECTS = false

endglobals





struct Escaper

	private player p

    private unit hero

	private unit invisUnit

    private real walkSpeed

    private real slideSpeed

    private integer baseColorId

	private integer cameraField

	private TerrainType lastTerrainType

	

	private trigger slide

	private trigger checkTerrain

	

    private real vcRed

    private real vcGreen

    private real vcBlue

    private real vcTransparency

    trigger discoTrigger

    private EscaperEffectArray effects

	private effect terrainKillEffect

    private effect meteorEffect

	

	private boolean godMode

	private boolean godModeKills

	private boolean walkSpeedAbsolute

	private boolean slideSpeedAbsolute

	private boolean canTeleportB

	private boolean hasAutoreviveB

	

	private boolean canCheatB

	private boolean isMaximaxouB

	private boolean isTrueMaximaxouB

    

    private Make make

    private MakeLastActions makeLastActions

    private Level makingLevel

	

	Level currentLevelTouchTerrainDeath //pour le terrain qui tue, vérifie s'il faut bien tuer l'escaper

	private item itemInInventory //créer le déclo pour save ça

    

    

    

//item method

    method resetItem takes nothing returns boolean //renvoie true si le héros portait un item

        if (UnitHasItemOfTypeBJ(.hero, METEOR_NORMAL)) then

            call Meteor(GetItemUserData(UnitItemInSlot(.hero, 0))).replace()

            call DestroyEffect(.meteorEffect)

            set .meteorEffect = null

            return true

        endif

        return false

    endmethod

    

    method addEffectMeteor takes nothing returns nothing

        if(.meteorEffect == null)then

            set .meteorEffect = AddSpecialEffectTarget("Abilities\\Weapons\\DemonHunterMissile\\DemonHunterMissile.mdl", .hero, "hand right")

        endif

    endmethod

    

    method removeEffectMeteor takes nothing returns nothing

        if(.meteorEffect != null)then

            call DestroyEffect(.meteorEffect)

            set .meteorEffect = null

        endif

    endmethod

    

//select method

    method selectHero takes nothing returns nothing

        call SelectUnitAddForPlayer(.hero, .p)

    endmethod

	

//creation method

	method createHero takes real x, real y, real angle returns boolean //retourne false si le héros existe déja

		if (.hero != null) then

			return false

		endif

		set .hero = CreateUnit(.p, HERO_TYPE_ID, x, y, angle)

        call SetUnitUserData(.hero, GetPlayerId(.p))

        call ShowUnit(.hero, false)

        call ShowUnit(.hero, true)

        call UnitRemoveAbility(.hero, 'Aloc')

		call SetUnitMoveSpeed(.hero, .walkSpeed) //voir pour le nom de la fonction

        call .selectHero()

        if (.baseColorId == 0) then

            call SetUnitColor(.hero, PLAYER_COLOR_RED)

        else

            call SetUnitColor(.hero, ConvertPlayerColor(.baseColorId))

        endif

        call SetUnitVertexColorBJ(.hero, .vcRed, .vcGreen, .vcBlue, .vcTransparency)

        call SpecialIllidan(.hero)

		set .invisUnit = CreateUnit(NEUTRAL_PLAYER, INVIS_UNIT_TYPE_ID, x, y, angle)

        call SetUnitUserData(.invisUnit, GetPlayerId(.p)) 

        call TriggerRegisterUnitEvent(gg_trg_InvisUnit_is_getting_damage, .invisUnit, EVENT_UNIT_DAMAGED)

        call .effects.showEffects(.hero)

        set .lastTerrainType = 0

        call TimerStart(afkModeTimers[GetPlayerId(.p)], timeMinAfk, false, GetAfkModeTimeExpiresCodeFromId(GetPlayerId(.p)))

        call InitShortcutSkills(GetPlayerId(.p))

        call EnableTrigger(.checkTerrain)

        return true

	endmethod

	

	method createHeroAtStart takes nothing returns boolean

		local real x

		local real y

		local Start start = udg_levels.getCurrentLevel().getStart()

        local real angle

		if (start == 0) then //si le départ du niveau en cours n'existe pas

			set start = DEPART_PAR_DEFAUT

            set angle = HERO_START_ANGLE

        else

            set angle = GetRandomDirectionDeg()

		endif

		set x = start.getRandomX()

		set y = start.getRandomY()

		return .createHero(x, y, angle)

	endmethod

	

	static method create takes integer playerId returns Escaper //ne crée pas le héros

		local Escaper e = Escaper.allocate()

		set e.p = Player(playerId)

		set e.walkSpeed = HERO_WALK_SPEED

		set e.slideSpeed = HERO_SLIDE_SPEED

		set e.baseColorId = playerId

		set e.slide = CreateSlideTrigger(playerId)

        set e.checkTerrain = CreateCheckTerrainTrigger(playerId)

        set e.cameraField = DEFAULT_CAMERA_FIELD

        call SetCameraFieldForPlayer(e.p, CAMERA_FIELD_TARGET_DISTANCE, I2R(e.cameraField), 0)

        set e.effects = EscaperEffectArray.create()

        set e.vcRed = 100

        set e.vcGreen = 100

        set e.vcBlue = 100

        set e.vcTransparency = 0

        set e.lastTerrainType = 0

        set e.makingLevel = 0

        set e.make = 0

        set e.makeLastActions = MakeLastActions.create(e)

        set e.godMode = false

        set e.godModeKills = false

        set e.walkSpeedAbsolute = false

        set e.slideSpeedAbsolute = false

        set e.canTeleportB = false

        set e.hasAutoreviveB = false

        set e.canCheatB = false

        set e.isMaximaxouB = false

        set e.isTrueMaximaxouB = false

        set e.discoTrigger = null

		return e

	endmethod    

	

	method removeHero takes nothing returns nothing

		if (.hero == null) then

			return

		endif

		call .resetItem()

        if (IsUnitAliveBJ(.hero)) then

            call KillUnit(.hero)

        endif

		call RemoveUnit(.hero)

		set .hero = null

		call RemoveUnit(.invisUnit)

		set .invisUnit = null

		set .lastTerrainType = 0

        call .make.destroy()

        set .make = 0

        call .effects.hideEffects()

        call DisableTrigger(.checkTerrain)

        call DisableTrigger(.slide)

	endmethod

	

	private method onDestroy takes nothing returns nothing

		call .removeHero()

		call DestroyEffect(.terrainKillEffect)

		set .terrainKillEffect = null

		call .effects.destroy()

		call DestroyTrigger(.slide)

		set .slide = null

		call DestroyTrigger(.checkTerrain)

		set .checkTerrain = null

        call DestroyTrigger(.discoTrigger)

        set .discoTrigger = null

        call udg_escapers.nullify(GetPlayerId(.p))

	endmethod

    

//getId method

    method getId takes nothing returns integer

        local integer i = 0

        loop

            exitwhen (i > 11)

                if (this == udg_escapers.get(i)) then

                    return i

                endif

            set i = i + 1

        endloop

        return -1

    endmethod		

			

//trigger methods

	method enableSlide takes boolean doEnable returns boolean

		if (IsTriggerEnabled(.slide) == doEnable) then

			return false

		endif

		if (doEnable) then

			call EnableTrigger(.slide)

			call StopUnit(.hero)

		else

			call DisableTrigger(.slide)

		endif

		return true

	endmethod

	

	method enableCheckTerrain takes boolean doEnable returns boolean

		if (IsTriggerEnabled(.checkTerrain) == doEnable) then

			return false

		endif

		if (doEnable) then

			call EnableTrigger(.checkTerrain)

		else

			call DisableTrigger(.checkTerrain)

		endif

		return true

	endmethod

    

    method isSliding takes nothing returns boolean

        return IsTriggerEnabled(.slide)

    endmethod

    

    method doesCheckTerrain takes nothing returns boolean

        return IsTriggerEnabled(.checkTerrain)

    endmethod

	

	

//move methods

	method moveHero takes real x, real y returns nothing

		call SetUnitX(.hero, x)

		call SetUnitY(.hero, y)

	endmethod

	

	method moveInvisUnit takes real x, real y returns nothing

		call SetUnitX(.invisUnit, x)

		call SetUnitY(.invisUnit, y)

	endmethod	

	

	

//hero methods

	method getHero takes nothing returns unit

		return .hero

	endmethod

	

	method isAlive takes nothing returns boolean

		return IsUnitAliveBJ(.hero)

	endmethod

	

	method isPaused takes nothing returns boolean

		return IsUnitPaused(.hero)

	endmethod

	

	method kill takes nothing returns boolean

		if (.isAlive()) then

			call .resetItem()

			call KillUnit(.hero)

			set .lastTerrainType = 0

            call ShowUnit(.invisUnit, false)

            call .enableSlide(false)

            call .enableCheckTerrain(false)

			return true

		endif

		return false

	endmethod

	

	method pause takes boolean doPause returns boolean

		if (.isPaused() == doPause) then

            return false

		endif

        call PauseUnit(.hero, doPause)

        return true

	endmethod

	

	method specialIllidan takes nothing returns nothing

		call SetUnitAnimation(.hero, "Morph Alternate")

	endmethod

	

	method revive takes real x, real y returns boolean

		if (.isAlive()) then

			return false

		endif

		call ReviveHero(.hero, x, y, SHOW_REVIVE_EFFECTS)

		call SetUnitX(.invisUnit, x)

		call SetUnitY(.invisUnit, y)

		call ShowUnit(.invisUnit, true)

		call .enableCheckTerrain(true)

		call .specialIllidan()

		call .selectHero()

        return true

	endmethod

	

	method reviveAtStart takes nothing returns boolean

		local real x = udg_levels.getCurrentLevel().getStartRandomX()

		local real y = udg_levels.getCurrentLevel().getStartRandomY()

		return .revive(x, y)

	endmethod

    

    method turnInstantly takes real angle returns nothing

        local TerrainType lastTerrainType = .lastTerrainType

        local real x = GetUnitX(.hero)

		local real y = GetUnitY(.hero)

        local item meteor = UnitItemInSlot(.hero, 0)

		call .removeHero()

        call .createHero(x, y, angle)

        set .lastTerrainType = lastTerrainType

        call SetUnitAnimation(.getHero(), "stand")

        if (meteor != null) then

            call UnitAddItem(.hero, meteor)

        endif

        set meteor = null

    endmethod

	

	method reverse takes nothing returns nothing

		local real angle = GetUnitFacing(.hero) + 180 //à vérifier

		call .turnInstantly(angle)

	endmethod

	

//effects methods

	method newEffect takes string efStr, string bodyPart returns nothing

		call .effects.new(efStr, .hero, bodyPart)

	endmethod

	

	method destroyLastEffects takes integer numEfToDestroy returns nothing

		call .effects.destroyLastEffects(numEfToDestroy)

	endmethod

	

	method hideEffects takes nothing returns nothing

		call .effects.hideEffects()

	endmethod

	

	method showEffects takes nothing returns nothing

		call .effects.showEffects(.hero)

	endmethod

	

//terrainKill methods

	method destroyTerrainKillEffect takes nothing returns nothing

		call DestroyEffect(.terrainKillEffect)

		set .terrainKillEffect = null

	endmethod

	

	method createTerrainKillEffect takes string killEffectStr returns nothing

		if (.terrainKillEffect != null) then

			call .destroyTerrainKillEffect()

		endif

		set .terrainKillEffect = AddSpecialEffectTarget( killEffectStr, .hero, TERRAIN_KILL_EFFECT_BODY_PART )

	endmethod

	

//lastTerrainType methods

	method getLastTerrainType takes nothing returns TerrainType

		return .lastTerrainType

	endmethod

	

    method setLastTerrainType takes TerrainType terrainType returns nothing

		set .lastTerrainType = terrainType

	endmethod

	

//speed methods

	method setSlideSpeed takes real slideSpeed returns nothing

		set .slideSpeed = slideSpeed

	endmethod

	

	method setWalkSpeed takes real walkSpeed returns nothing

		set .walkSpeed = walkSpeed

		call SetUnitMoveSpeed(.hero, walkSpeed)

	endmethod

	

	method getSlideSpeed takes nothing returns real

		return .slideSpeed

	endmethod

	

	method getWalkSpeed takes nothing returns real

		return .walkSpeed

	endmethod

	

	method isAbsoluteSlideSpeed takes nothing returns boolean

		return .slideSpeedAbsolute

	endmethod

	

	method absoluteSlideSpeed takes real slideSpeed returns nothing

		set .slideSpeedAbsolute = true

		set .slideSpeed = slideSpeed

	endmethod

	

	method stopAbsoluteSlideSpeed takes nothing returns nothing

		set .slideSpeedAbsolute = false

	endmethod

	

	method isAbsoluteWalkSpeed takes nothing returns boolean

		return .walkSpeedAbsolute

	endmethod

	

	method absoluteWalkSpeed takes real walkSpeed returns nothing

		set .walkSpeedAbsolute = true

		call .setWalkSpeed( walkSpeed )

	endmethod

	

	method stopAbsoluteWalkSpeed takes nothing returns nothing

		set .walkSpeedAbsolute = false

	endmethod

	

//godMode methods    

    method setGodMode takes boolean godMode returns nothing

        set .godMode = godMode

    endmethod

    

    method setGodModeKills takes boolean godModeKills returns nothing

        set .godModeKills = godModeKills

    endmethod

	

	method isGodModeOn takes nothing returns boolean

		return .godMode

	endmethod



	method doesGodModeKills takes nothing returns boolean

		return .godModeKills

	endmethod

	

//color methods

	method setBaseColor takes integer baseColorId returns boolean

        if (baseColorId < 0 or baseColorId > 12) then

            return false

        endif

		set .baseColorId = baseColorId

		if (.hero != null) then

            if (baseColorId == 0) then

                call SetUnitColor(.hero, PLAYER_COLOR_RED)

            else

                call SetUnitColor(.hero, ConvertPlayerColor(baseColorId))

            endif

		endif

        call ColorInfo(this, .p)

        return true

	endmethod

    

	method setBaseColorDisco takes integer baseColorId returns boolean

        if (baseColorId < 0 or baseColorId > 12) then

            return false

        endif

		set .baseColorId = baseColorId

		if (.hero != null) then

            if (baseColorId == 0) then

                call SetUnitColor(.hero, PLAYER_COLOR_RED)

            else

                call SetUnitColor(.hero, ConvertPlayerColor(baseColorId))

            endif

		endif

        return true

	endmethod

    

    method getBaseColor takes nothing returns integer

        return .baseColorId

    endmethod

	

	method setVcRed takes real vcRed returns boolean

        if (vcRed < 0 or vcRed > 100) then

            return false

        endif

		set .vcRed = vcRed

        return true

	endmethod

	

	method setVcGreen takes real vcGreen returns boolean

        if (vcGreen < 0 or vcGreen > 100) then

            return false

        endif

		set .vcGreen = vcGreen

        return true

	endmethod

	

	method setVcBlue takes real vcBlue returns boolean

        if (vcBlue < 0 or vcBlue > 100) then

            return false

        endif

		set .vcBlue = vcBlue

        return true

	endmethod

	

	method setVcTransparency takes real vcTransparency returns boolean

        if (vcTransparency < 0 or vcTransparency > 100) then

            return false

        endif

		set .vcTransparency = vcTransparency

        return true

	endmethod

	

	method getVcRed takes nothing returns real

		return .vcRed

	endmethod

	

	method getVcGreen takes nothing returns real

		return .vcGreen

	endmethod

	

	method getVcBlue takes nothing returns real

		return .vcBlue

	endmethod

	

	method getVcTransparency takes nothing returns real

		return .vcTransparency

	endmethod

	

	method refreshVertexColor takes nothing returns nothing

		call SetUnitVertexColorBJ(.hero, .vcRed, .vcGreen, .vcBlue, .vcTransparency)

		call ColorInfo(this, .p)

	endmethod

	

//cheat methods

	method setCanCheat takes boolean canCheat returns nothing

        if (not canCheat) then

            set .isMaximaxouB = false

            set .isTrueMaximaxouB = false

        endif

		set .canCheatB = canCheat

	endmethod

	

	method setIsMaximaxou takes boolean isMaximaxou returns nothing

		if (isMaximaxou) then

			call .setCanCheat(true)

        else

            set .isTrueMaximaxouB = false

		endif

		set .isMaximaxouB = isMaximaxou

	endmethod

	

	method setIsTrueMaximaxou takes boolean isTrueMaximaxou returns nothing

		if (isTrueMaximaxou) then

			call .setIsMaximaxou(true)

		endif

		set .isTrueMaximaxouB = isTrueMaximaxou

	endmethod

	

	method canCheat takes nothing returns boolean

		return .canCheatB

	endmethod

	

	method isMaximaxou takes nothing returns boolean

		return .isMaximaxouB

	endmethod

	

	method isTrueMaximaxou takes nothing returns boolean

		return .isTrueMaximaxouB

	endmethod

	

    

//autres

	method getPlayer takes nothing returns player

		return .p

	endmethod

	

	method setCameraField takes integer cameraField returns nothing

		set .cameraField = cameraField

		call SetCameraFieldForPlayer(.p, CAMERA_FIELD_TARGET_DISTANCE, I2R(cameraField), 0)

	endmethod

    

    method getCameraField takes nothing returns integer

        return .cameraField

    endmethod

    

    method resetCamera takes nothing returns nothing

        call ResetToGameCameraForPlayer(.p, 0)

        call SetCameraFieldForPlayer(.p, CAMERA_FIELD_TARGET_DISTANCE, .cameraField, 0 )

    endmethod



	method kick takes Escaper kicked returns nothing

		call CustomDefeatBJ(kicked.getPlayer(), "You have been kicked by " + GetPlayerName(.p) + " !")

        call Text_A(udg_colorCode[GetPlayerId(kicked.getPlayer())] + GetPlayerName(kicked.getPlayer()) + " has been kicked by " + udg_colorCode[GetPlayerId(.p)] + GetPlayerName(.p) + " !")

		call .destroy()

	endmethod

	

    

//teleport methods

	method setCanTeleport takes boolean canTeleport returns nothing

		set .canTeleportB = canTeleport

	endmethod

	

	method canTeleport takes nothing returns boolean

		return .canTeleportB

	endmethod

	

    

//autorevive methods

	method hasAutorevive takes nothing returns boolean

		return .hasAutoreviveB

	endmethod

	

	method setHasAutorevive takes boolean hasAutorevive returns nothing

		set .hasAutoreviveB = hasAutorevive

	endmethod

    

    

//make methods

    method getMake takes nothing returns Make

        return .make

    endmethod

    

    method destroyMakeIfForSpecificLevel takes nothing returns nothing

        local boolean doDestroy

        if (.make != 0) then

            set doDestroy = (.make.getType() == MakeMonsterNoMove.typeid)

            set doDestroy = doDestroy or (.make.getType() == MakeMonsterSimplePatrol.typeid)

            set doDestroy = doDestroy or (.make.getType() == MakeMonsterMultiplePatrols.typeid)

            set doDestroy = doDestroy or (.make.getType() == MakeDeleteMonsters.typeid)

            set doDestroy = doDestroy or (.make.getType() == MakeMeteor.typeid)

            set doDestroy = doDestroy or (.make.getType() == MakeDeleteMeteors.typeid)

            set doDestroy = doDestroy or (.make.getType() == MakeStart.typeid)

            set doDestroy = doDestroy or (.make.getType() == MakeEnd.typeid)

            set doDestroy = doDestroy or (.make.getType() == MakeVisibilityModifier.typeid)

            if (doDestroy) then

                call .destroyMake()

            endif

        endif

    endmethod

    

    method setMakingLevel takes Level level returns boolean

        local Level oldMakingLevel

        if (.makingLevel == level) then

            return false

        endif

        set oldMakingLevel = .makingLevel

        set .makingLevel = level

        call .destroyMakeIfForSpecificLevel()

        if (not IsLevelBeingMade(oldMakingLevel)) then

            call oldMakingLevel.activate(false)

            if (udg_levels.getCurrentLevel().getId() < oldMakingLevel.getId()) then

                call oldMakingLevel.activateVisibilities(false)

            endif

        endif

        set Level_earningLivesActivated = false

        call level.activate(true)

        set Level_earningLivesActivated = true

        return true

    endmethod

    

    method getMakingLevel takes nothing returns Level

        if (.makingLevel == 0) then

            return udg_levels.getCurrentLevel()

        endif

        return .makingLevel

    endmethod

    

    method isMakingCurrentLevel takes nothing returns boolean

        return (.makingLevel == 0)

    endmethod

    

    method destroyMake takes nothing returns boolean

        if (.make == 0) then

            return false

        endif

        call .make.destroy()

        set .make = 0

        return true

    endmethod

    

    method makeCreateNoMoveMonsters takes MonsterType mt, real facingAngle returns nothing

        //mode : noMove

        call .destroyMake()

        set .make = MakeMonsterNoMove.create(.hero, mt, facingAngle)

    endmethod

    

	method makeCreateSimplePatrolMonsters takes string mode, MonsterType mt returns nothing

        call .destroyMake()

		//modes : normal, string, auto

		if (mode == "normal" or mode == "string" or mode == "auto") then

			set .make = MakeMonsterSimplePatrol.create(.hero, mode, mt)

		endif

	endmethod	

    

	method makeCreateMultiplePatrolsMonsters takes string mode, MonsterType mt returns nothing

        call .destroyMake()

        //modes : normal, string

		if (mode == "normal" or mode == "string") then

			set .make = MakeMonsterMultiplePatrols.create(.hero, mode, mt)

		endif

	endmethod	

    

    method makeMmpNext takes nothing returns boolean

        if (not(.make.getType() == MakeMonsterMultiplePatrols.typeid)) then

            return false

        endif

        call MakeMonsterMultiplePatrols(integer(.make)).nextMonster()

        return true

    endmethod

    

    method makeCreateMonsterSpawn takes string label, MonsterType mt, string sens, real frequence returns nothing

        call .destroyMake()

        set .make = MakeMonsterSpawn.create(.hero, label, mt, sens, frequence)

    endmethod

	

	method makeDeleteMonsters takes string mode returns nothing

		call .destroyMake()

		//delete modes : all, noMove, move, simplePatrol, multiplePatrols, oneByOne

		if (mode != "all" and mode != "noMove" and mode != "move" and mode != "simplePatrol" and mode != "multiplePatrols" and mode != "oneByOne") then

			return

		endif

		set .make = MakeDeleteMonsters.create(.hero, mode)

	endmethod

    

    method makeCreateMeteor takes nothing returns nothing

        call .destroyMake()

        set .make = MakeMeteor.create(.hero)

    endmethod

	

	method makeDeleteMeteors takes string mode returns nothing

		call .destroyMake()

		//delete modes : oneByOne, twoClics

		if (mode != "oneByOne" and mode != "twoClics") then

			return

		endif

		set .make = MakeDeleteMeteors.create(.hero, mode)

	endmethod

    

    method makeCreateTerrain takes TerrainType terrainType returns nothing

        call .destroyMake()

        set .make = MakeTerrainCreate.create(.hero, terrainType)    

    endmethod

    

    method makeTerrainCopyPaste takes nothing returns nothing

        call .destroyMake()

        set .make = MakeTerrainCopyPaste.create(.hero)

    endmethod

    

    method makeTerrainVerticalSymmetry takes nothing returns nothing

        call .destroyMake()

        set .make = MakeTerrainVerticalSymmetry.create(.hero)

    endmethod

    

    method makeTerrainHorizontalSymmetry takes nothing returns nothing

        call .destroyMake()

        set .make = MakeTerrainHorizontalSymmetry.create(.hero)

    endmethod

    

    method makeGetTerrainType takes nothing returns nothing

        call .destroyMake()

        set .make = MakeGetTerrainType.create(.hero)    

    endmethod

    

    method makeExchangeTerrains takes nothing returns nothing

        call .destroyMake()

        set .make = MakeExchangeTerrains.create(.hero)    

    endmethod  

    

    method makeCreateStart takes boolean forNext returns nothing

        call .destroyMake()

        set .make = MakeStart.create(.hero, forNext)

    endmethod 

    

    method makeCreateEnd takes nothing returns nothing

        call .destroyMake()

        set .make = MakeEnd.create(.hero)

    endmethod

    

    method makeCreateVisibilityModifier takes nothing returns nothing

        call .destroyMake()

        set .make = MakeVisibilityModifier.create(.hero)

    endmethod

    

    method cancelLastAction takes nothing returns boolean

        if (.make != 0) then

            if (.make.cancelLastAction()) then

                return true

            endif

        endif

        return .makeLastActions.cancelLastAction()

    endmethod

    

    method redoLastAction takes nothing returns boolean

        if (.makeLastActions.redoLastAction()) then

            return true

        endif

        if (.make != 0) then

            return .make.redoLastAction()

        endif

        return false

    endmethod

    

    method deleteSpecificActionsForLevel takes Level level returns nothing

        call .makeLastActions.deleteSpecificActionsForLevel(level)

    endmethod

    

    method newAction takes MakeAction action returns MakeAction

        return .makeLastActions.newAction(action)

    endmethod

    

    method destroyAllSavedActions takes nothing returns nothing

        call .makeLastActions.destroyAllActions()

    endmethod

    

    method destroyCancelledActions takes nothing returns nothing

        call .makeLastActions.destroyCancelledActions()

    endmethod

endstruct







endlibrary//===========================================================================

// Trigger: EscaperArray

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library EscaperArray needs Escaper





struct EscaperArray

	private Escaper array escapers [12]

	

	static method create takes nothing returns EscaperArray

		local EscaperArray e = EscaperArray.allocate()

		local integer playerId = 0

		loop

			exitwhen (playerId > 11)

				if (IsPlayerInGame(Player(playerId))) then

					set e.escapers[playerId] = Escaper.create(playerId)

				else

                    set e.escapers[playerId] = 0

                endif

			set playerId = playerId + 1

		endloop

		return e

	endmethod

    

    method newAt takes integer id returns nothing

        if (id < 0 or id > 11) then

            return

        endif

        if (.escapers[id] != 0) then

            return

        endif

        set .escapers[id] = Escaper.create(id)

    endmethod

	

	method count takes nothing returns integer

		local integer n = 0

		local integer i = 0

		loop

			exitwhen (i > 11)

				if (.escapers[i] != 0) then

					set n = n + 1

				endif

			set i = i + 1

		endloop

		return n

	endmethod

    

    method get takes integer id returns Escaper

        return .escapers[id]

    endmethod

    

    method nullify takes integer id returns nothing

        set .escapers[id] = 0

    endmethod

    

    method remove takes integer id returns nothing

        call .escapers[id].destroy()

        set .escapers[id] = 0

    endmethod

    

    method deleteSpecificActionsForLevel takes Level level returns nothing

        local integer i = 0

        loop

            exitwhen (i > 11)

                if (.escapers[i] != 0) then

                    call .escapers[i].deleteSpecificActionsForLevel(level)

                endif

            set i = i + 1

        endloop

    endmethod

    

    method destroyMakesIfForSpecificLevel_currentLevel takes nothing returns nothing

        //destroy le make des escapers si c'est un make pour spécifique level et que l'escaper make pour le "current_level"

        local boolean doDestroy

        local integer i = 0

        loop

            exitwhen (i > 11)

                if (.escapers[i] != 0 and .escapers[i].isMakingCurrentLevel()) then

                    call .escapers[i].destroyMakeIfForSpecificLevel()

                endif

            set i = i + 1

        endloop

    endmethod

endstruct







endlibrary//===========================================================================

// Trigger: EscaperSavedCommands

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library EscaperSavedCommands needs CommandExecution





globals

    EscaperSavedCommands udg_savedCommands

endglobals





struct EscaperSavedCommands

    private hashtable savedCommands

    

    

    static method create takes nothing returns EscaperSavedCommands

        local EscaperSavedCommands sc = EscaperSavedCommands.allocate()

        set sc.savedCommands = InitHashtable()

        return sc

    endmethod

    

    method new takes Escaper escaper, string commandName, string command returns nothing

        call SaveStr(.savedCommands, escaper, StringHash(commandName), command)

    endmethod

    

    method execute takes Escaper escaper, string commandName returns boolean

        local string cmd = LoadStr(.savedCommands, escaper, StringHash(commandName))

        if (cmd == null) then

            return false

        else

            call ExecuteCommand(escaper, cmd)

        endif

        return true

    endmethod

endstruct







endlibrary//===========================================================================

// Trigger: Make

//===========================================================================

//TESH.scrollpos=29

//TESH.alwaysfold=0

library Make needs MMNoMoveActions, MMSimplePatrolActions, MMMultiplePatrolsActions, MonsterSpawnMakingActions, MonsterDeleteActions, TerrainMakingActions, GettingTerrainTypeInfoActions, MakeExchangeTerrainsActions, StartMakingActions, EndMakingActions, VisibilityModifierMakingActions, TerrainCopyPasteActions, TerrainVerticalSymmetryActions, TerrainHorizontalSymmetryActions, MeteorMakingActions, MeteorDeleteActions



globals

	constant integer MAKE_LAST_CLIC_UNIT_ID = 'e001' //à remplacer par l'id de l'unité choisie (need couleur variable)

	constant string MAKE_CANT_CANCEL_MORE = "Nothing else to cancel !"

	constant string MAKE_CANT_REDO_MORE = "Nothing else to redo !"

endglobals





interface Make

    player makerOwner

    string kind //monsterMaking, monsterDeleting...

    trigger t

    unit maker

    method cancelLastAction takes nothing returns boolean

    method redoLastAction takes nothing returns boolean

endinterface





public function GetActions takes string kind returns code

    if (kind == "monsterCreateNoMove") then

        return function MonsterMakingNoMove_Actions

    endif

    if (kind == "monsterCreateSimplePatrol") then

        return function MonsterMakingSimplePatrol_Actions

    endif

    if (kind == "monsterCreateMultiplePatrols") then

        return function MonsterMakingMultiplePatrols_Actions

    endif

    if (kind == "monsterSpawnCreate") then

        return function MonsterSpawnMaking_Actions

    endif

    if (kind == "deleteMonsters") then

        return function MonsterDelete_Actions

    endif

    if (kind == "meteorCreate") then

        return function MeteorMaking_Actions

    endif

    if (kind == "deleteMeteors") then

        return function MeteorDelete_Actions

    endif

    if (kind == "terrainCreate") then

        return function TerrainMaking_Actions

    endif

    if (kind == "terrainCopyPaste") then

        return function TerrainCopyPaste_Actions

    endif

    if (kind == "terrainVerticalSymmetry") then

        return function TerrainVerticalSymmetry_Actions

    endif

    if (kind == "terrainHorizontalSymmetry") then

        return function TerrainHorizontalSymmetry_Actions

    endif

    if (kind == "getTerrainType") then

        return function GettingTerrainTypeInfo_Actions

    endif

    if (kind == "exchangeTerrains") then

        return function MakeExchangeTerrains_Actions

    endif

    if (kind == "startCreate") then

        return function StartMaking_Actions

    endif

    if (kind == "endCreate") then

        return function EndMaking_Actions

    endif

    if (kind == "visibilityModifierCreate") then

        return function VisibilityModifierMaking_Actions

    endif

    return null

endfunction







endlibrary





//===========================================================================

// Trigger: Monster making no move Actions

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library MMNoMoveActions needs BasicFunctions, Escaper







function MonsterMakingNoMove_Actions takes nothing returns nothing

    local Monster monster

    local Escaper escaper = Hero2Escaper(GetTriggerUnit())

    local Make mkGeneral = escaper.getMake()

	local MakeMonsterNoMove mk = MakeMonsterNoMove(integer(mkGeneral))

    local real x = GetOrderPointX()

    local real y = GetOrderPointY()



    if (not IsIssuedOrder("smart")) then

        return

    endif

    call StopUnit(mk.maker)

    

    set monster = escaper.getMakingLevel().monstersNoMove.new(mk.getMonsterType(), x, y, mk.getFacingAngle(), true)

    call escaper.newAction(MakeMonsterAction.create(escaper.getMakingLevel(), monster))

endfunction







endlibrary//===========================================================================

// Trigger: MakeMonsterNoMove

//===========================================================================

//TESH.scrollpos=7

//TESH.alwaysfold=0

library MakeMonsterNoMove needs Make









struct MakeMonsterNoMove extends Make    

    private MonsterType mt

    private real facingAngle

    

    method getMonsterType takes nothing returns MonsterType

        return .mt

    endmethod

    

    method getFacingAngle takes nothing returns real

        return .facingAngle

    endmethod

	

	static method create takes unit maker, MonsterType mt, real facingAngle returns MakeMonsterNoMove

        local MakeMonsterNoMove m

		if (maker == null or mt == 0) then

			return 0

		endif

        set m = MakeMonsterNoMove.allocate()

        set m.maker = maker

        set m.kind = "monsterCreateNoMove"

        set m.mt = mt

        set m.facingAngle = facingAngle

        set m.t = CreateTrigger()

        call TriggerAddAction(m.t, Make_GetActions(m.kind))

        call TriggerRegisterUnitEvent(m.t, m.maker, EVENT_UNIT_ISSUED_POINT_ORDER)

        return m

    endmethod

    

    method onDestroy takes nothing returns nothing

		call DestroyTrigger(.t)

		set .t = null

		set .maker = null

	endmethod

	

	method cancelLastAction takes nothing returns boolean

        return false

	endmethod

	

	method redoLastAction takes nothing returns boolean

        return false

	endmethod	

endstruct

	

	

	

	

endlibrary

	

//===========================================================================

// Trigger: Monster making simple patrol Actions

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library MMSimplePatrolActions needs TerrainTypeFunctions, Escaper



globals

    private constant real MIN_DIST = 5

    private constant real MAX_DIST = 2000

    private constant real ECART_DIST = 32

    private constant real ECART_ANGLE = 9

    private constant real DIST_ON_TERRAIN_MAX = 300

    private constant real DIST_ON_TERRAIN_DEFAULT = 50

    private real distOnTerrain = 50

endglobals





function MakeSimplePatrolAuto_ChangeDistOnTerrain takes real newDist returns boolean

    if (newDist < 0 or newDist > DIST_ON_TERRAIN_MAX) then

        return false

    endif

    set distOnTerrain = newDist

    return true

endfunction



function MakeSimplePatrolAuto_ChangeDistOnTerrainDefault takes nothing returns nothing

    set distOnTerrain = DIST_ON_TERRAIN_DEFAULT

endfunction





function MonsterMakingSimplePatrol_Actions takes nothing returns nothing

    local Monster monster

    local Escaper escaper = Hero2Escaper(GetTriggerUnit())

    local Make mkGeneral = escaper.getMake()

	local MakeMonsterSimplePatrol mk = MakeMonsterSimplePatrol(integer(mkGeneral))

    local real x = GetOrderPointX()

    local real y = GetOrderPointY()

    

    local real x1

    local real y1

    local real x2

    local real y2

    local real dist

    local real angle 

    local boolean found

    

    if (not IsIssuedOrder("smart")) then   

        return

    endif

    call StopUnit(mk.maker)

	

	

	if (mk.getMode() == "normal") then

		if (mk.isLastLocSavedUsed()) then

            if (GetLocDist(mk.lastX, mk.lastY, x, y) <= PATROL_DISTANCE_MIN) then

                call Text_erP(mk.makerOwner, "Too close to the start location !")

                return

            else

                set monster = escaper.getMakingLevel().monstersSimplePatrol.new(mk.getMonsterType(), mk.lastX, mk.lastY, x, y, true)

                call escaper.newAction(MakeMonsterAction.create(escaper.getMakingLevel(), monster))

                call mk.unsaveLocDefinitely()

            endif

		else

			call mk.saveLoc(x, y)

		endif

	endif

    

	

	if (mk.getMode() == "string") then

		if (mk.isLastLocSavedUsed()) then

            if (GetLocDist(mk.lastX, mk.lastY, x, y) <= PATROL_DISTANCE_MIN) then

                call Text_erP(mk.makerOwner, "Too close to the start location !")

                return

            else

                set monster = escaper.getMakingLevel().monstersSimplePatrol.new(mk.getMonsterType(), mk.lastX, mk.lastY, x, y, true)

                call escaper.newAction(MakeMonsterAction.create(escaper.getMakingLevel(), monster))

                call mk.unsaveLoc()

            endif

        endif

		call mk.saveLoc(x, y)

	endif

    

    

    if (mk.getMode() == "auto") then

        if (IsTerrainTypeOfKind(GetTerrainType(x, y), "death")) then

            call Text_erP(mk.makerOwner, "You clicked on a death terrain !")

            return

        endif

        

        //find approximatively first location

        set found = false

        set dist = MIN_DIST

        loop

            exitwhen (found or dist > MAX_DIST)

                set angle = 0

                set x1 = x + dist * CosBJ(angle)

                set y1 = y + dist * SinBJ(angle)

                set found = IsTerrainTypeOfKind(GetTerrainType(x1, y1), "death")

                exitwhen found

                

                set angle = 90

                set x1 = x + dist * CosBJ(angle)

                set y1 = y + dist * SinBJ(angle)

                set found = IsTerrainTypeOfKind(GetTerrainType(x1, y1), "death")

                exitwhen found

                

                set angle = 180

                set x1 = x + dist * CosBJ(angle)

                set y1 = y + dist * SinBJ(angle)

                set found = IsTerrainTypeOfKind(GetTerrainType(x1, y1), "death")

                exitwhen found

                

                set angle = 270

                set x1 = x + dist * CosBJ(angle)

                set y1 = y + dist * SinBJ(angle)

                set found = IsTerrainTypeOfKind(GetTerrainType(x1, y1), "death")

                exitwhen found

                

                set angle = 1

                loop

                    exitwhen (found or angle >= 360)

                        set x1 = x + dist * CosBJ(angle)

                        set y1 = y + dist * SinBJ(angle)

                        set found = IsTerrainTypeOfKind(GetTerrainType(x1, y1), "death")

                    set angle = angle + ECART_ANGLE

                endloop

                set angle = angle - ECART_ANGLE

                

            set dist = dist + ECART_DIST

        endloop

        

        //first location not found

        if (not found) then

            call Text_erP(mk.makerOwner, "Death terrain too far !")

            return

        endif

        

        //precise position of first location

        loop

            exitwhen (not IsTerrainTypeOfKind(GetTerrainType(x1, y1), "death"))

            set dist = dist - 1

                set x1 = x + dist * CosBJ(angle)

                set y1 = y + dist * SinBJ(angle)

        endloop

        set dist = dist + distOnTerrain + 1

        set x1 = x + dist * CosBJ(angle)

        set y1 = y + dist * SinBJ(angle)

        

        //prepare angle for the second location

        if (angle >= 180) then

            set angle = angle - 180

        else

            set angle = angle + 180

        endif

        

        //find approximatively second location

        set found = false

        set dist = MIN_DIST

        loop

            exitwhen (found or dist > MAX_DIST)

                set x2 = x + dist * CosBJ(angle)

                set y2 = y + dist * SinBJ(angle)        

                set found = IsTerrainTypeOfKind(GetTerrainType(x2, y2), "death")

            set dist = dist + ECART_DIST

        endloop

        

        //second location not found

        if (not found) then

            call Text_erP(mk.makerOwner, "Death terrain too far for the second location !")

            return

        endif

        

        //precise position of second location

        loop

            exitwhen (not IsTerrainTypeOfKind(GetTerrainType(x2, y2), "death"))

            set dist = dist - 1

                set x2 = x + dist * CosBJ(angle)

                set y2 = y + dist * SinBJ(angle)

        endloop

        set dist = dist + distOnTerrain + 1

        set x2 = x + dist * CosBJ(angle)

        set y2 = y + dist * SinBJ(angle)

        

        //the two locations were found, creating monster

        set monster = escaper.getMakingLevel().monstersSimplePatrol.new(mk.getMonsterType(), x1, y1, x2, y2, true)

        call escaper.newAction(MakeMonsterAction.create(escaper.getMakingLevel(), monster))

    endif

endfunction







endlibrary



//===========================================================================

// Trigger: MakeMonsterSimplePatrol

//===========================================================================

//TESH.scrollpos=52

//TESH.alwaysfold=0

library MakeMonsterSimplePatrol needs Make







struct MakeMonsterSimplePatrol extends Make

    private string mode

	private MonsterType mt

    real lastX

    real lastY

    private boolean lastLocIsSaved

	private boolean lastLocSavedIsUsed

    private unit unitLastClic

	

	method getMonsterType takes nothing returns MonsterType

        return .mt

    endmethod

    

	static method create takes unit maker, string mode, MonsterType mt returns MakeMonsterSimplePatrol

        local MakeMonsterSimplePatrol m

		if (maker == null or (mode != "normal" and mode != "string" and mode != "auto") or mt == 0) then

			return 0

		endif

        set m = MakeMonsterSimplePatrol.allocate()

        set m.maker = maker

		set m.makerOwner = GetOwningPlayer(maker)

        set m.kind = "monsterCreateSimplePatrol"

        set m.mode = mode

        set m.mt = mt

        set m.t = CreateTrigger()

        call TriggerAddAction(m.t, Make_GetActions(m.kind))

        call TriggerRegisterUnitEvent(m.t, maker, EVENT_UNIT_ISSUED_POINT_ORDER)

        set m.lastLocIsSaved = false

        set m.lastLocSavedIsUsed = false

        return m

    endmethod

    

    method onDestroy takes nothing returns nothing

		call DestroyTrigger(.t)

		set .t = null

		call RemoveUnit(.unitLastClic)

		set .unitLastClic = null

		set .maker = null

	endmethod	

	

	method saveLoc takes real x, real y returns nothing

		set .lastX = x

		set .lastY = y

        set .lastLocIsSaved = true

		set .lastLocSavedIsUsed = true

		if (.unitLastClic == null) then

			set .unitLastClic = CreateUnit(.makerOwner, MAKE_LAST_CLIC_UNIT_ID, x, y, GetRandomDirectionDeg())

		else

			call SetUnitX(.unitLastClic, x)

			call SetUnitY(.unitLastClic, y)

		endif

        call Hero2Escaper(.maker).destroyCancelledActions()

	endmethod

	

	method unsaveLoc takes nothing returns boolean

		if (not .lastLocSavedIsUsed) then

			return false

		endif

		call RemoveUnit(.unitLastClic)

		set .unitLastClic = null

		set .lastLocSavedIsUsed = false

		return true

	endmethod

    

    method unsaveLocDefinitely takes nothing returns nothing

        call .unsaveLoc()

        set .lastLocIsSaved = false

    endmethod

	

	method isLastLocSavedUsed takes nothing returns boolean

		return .lastLocSavedIsUsed

	endmethod

	

	method cancelLastAction takes nothing returns boolean

		return .unsaveLoc()

	endmethod

	

	method redoLastAction takes nothing returns boolean

		if (.lastLocIsSaved and not .lastLocSavedIsUsed) then

            call .saveLoc(.lastX, .lastY)

            return true

        endif

        return false

	endmethod	

    

    method getMode takes nothing returns string

        return .mode

    endmethod

endstruct

	

	

	

endlibrary



//===========================================================================

// Trigger: Monster making multiple patrols Actions

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library MMMultiplePatrolsActions needs BasicFunctions, Escaper





function MonsterMakingMultiplePatrols_Actions takes nothing returns nothing

    local Escaper escaper = Hero2Escaper(GetTriggerUnit())

    local Make mkGeneral = escaper.getMake()

	local MakeMonsterMultiplePatrols mk = MakeMonsterMultiplePatrols(integer(mkGeneral))

    local real x = GetOrderPointX()

    local real y = GetOrderPointY()

    local integer erreur



    if (not IsIssuedOrder("smart")) then

        return

    endif

    call StopUnit(mk.maker)

    

	

	if (mk.getLocPointeur() >= 0) then

        set erreur = mk.getMonster().addNewLoc(x, y)

        if (erreur > 0) then

            if (erreur == 3) then

                call Text_erP(mk.makerOwner, "Number limit of patrol locations reached for this monster ! ( " + I2S(MonsterMultiplePatrols.NB_MAX_LOC) + " )")

            endif

            if (erreur == 2) then

                call Text_erP(mk.makerOwner, "Too close to the last location !")

            endif

            if (erreur == 1) then

                call Text_erP(mk.makerOwner, "Too close to the first location !")

            endif

        else

			call mk.saveLoc(x, y)

		endif		

	else

		call MonsterMultiplePatrols.destroyLocs()

		call MonsterMultiplePatrols.storeNewLoc(x, y)

		call mk.saveLoc(x, y)

		call mk.setMonster(escaper.getMakingLevel().monstersMultiplePatrols.new(mk.getMonsterType(), mk.getMode(), true))

	endif

endfunction







endlibrary



//===========================================================================

// Trigger: MakeMonsterMultiplePatrols

//===========================================================================

//TESH.scrollpos=93

//TESH.alwaysfold=0

library MakeMonsterMultiplePatrols needs Make







struct MakeMonsterMultiplePatrols extends Make

    private MonsterType mt

    private string mode //normal ou string

    private real array lastX [20]

    private real array lastY [20]

	private integer lastLocId

	private integer locPointeur

    private unit unitLastClic

    private MonsterMultiplePatrols monster

    

	method getMonsterType takes nothing returns MonsterType

        return .mt

    endmethod

    

    method getMode takes nothing returns string

        return .mode

    endmethod

    

    method getMonster takes nothing returns MonsterMultiplePatrols

        return .monster

    endmethod

	

	static method create takes unit maker, string mode, MonsterType mt returns MakeMonsterMultiplePatrols

        local MakeMonsterMultiplePatrols m

		if (maker == null or mt == 0 or (mode != "normal" and mode != "string")) then

			return 0

		endif

        set m = MakeMonsterMultiplePatrols.allocate()

        set m.maker = maker

		set m.makerOwner = GetOwningPlayer(maker)

        set m.kind = "monsterCreateMultiplePatrols"

        set m.mt = mt

        set m.mode = mode

        set m.monster = 0

        set m.t = CreateTrigger()

        call TriggerAddAction(m.t, Make_GetActions(m.kind))

        call TriggerRegisterUnitEvent(m.t, m.maker, EVENT_UNIT_ISSUED_POINT_ORDER)

		set m.lastLocId = -1

		set m.locPointeur = -1

        return m

    endmethod

    

    method onDestroy takes nothing returns nothing

        local Escaper escaper

        if (.monster != 0 and .monster.u != null) then

            set escaper = Hero2Escaper(.maker)

            call escaper.newAction(MakeMonsterAction.create(escaper.getMakingLevel(), .monster))

        else

            call .monster.destroy()

        endif

		call DestroyTrigger(.t)

		set .t = null

		call RemoveUnit(.unitLastClic)

		set .unitLastClic = null

		set .maker = null

	endmethod	

    

    method nextMonster takes nothing returns nothing

        local Escaper escaper

        set .lastLocId = -1

        set .locPointeur = -1

		call RemoveUnit(.unitLastClic)

		set .unitLastClic = null

        if (.monster != 0 and .monster.u != null) then

            set escaper = Hero2Escaper(.maker)

            call escaper.newAction(MakeMonsterAction.create(escaper.getMakingLevel(), .monster))

        else

            call .monster.destroy()

        endif

        set .monster = 0

    endmethod

	

	method getLocPointeur takes nothing returns integer

		return .locPointeur

	endmethod

    

    method setUnitLastClicPosition takes real x, real y returns nothing

        if (.unitLastClic == null) then

			set .unitLastClic = CreateUnit(.makerOwner, MAKE_LAST_CLIC_UNIT_ID, x, y, GetRandomDirectionDeg())

		else

			call SetUnitX(.unitLastClic, x)

			call SetUnitY(.unitLastClic, y)

		endif

    endmethod

	

	method saveLoc takes real x, real y returns nothing

		if (.locPointeur > 19) then

			return

		endif

		set .locPointeur = .locPointeur + 1

		set .lastX[.locPointeur] = x

		set .lastY[.locPointeur] = y

		set .lastLocId = .locPointeur

		call .setUnitLastClicPosition(x, y)

        call Hero2Escaper(.maker).destroyCancelledActions()

	endmethod

	

	method unsaveLoc takes nothing returns boolean

		if (.locPointeur < 0) then

			return false

		endif

        call .monster.destroyLastLoc()

		set .locPointeur = .locPointeur - 1

		if (.locPointeur >= 0) then

			call SetUnitX(.unitLastClic, .lastX[.locPointeur])

			call SetUnitY(.unitLastClic, .lastY[.locPointeur])

		else

			call RemoveUnit(.unitLastClic)

			set .unitLastClic = null

            call .monster.removeUnit()

		endif

		return true

	endmethod

	

	method setMonster takes MonsterMultiplePatrols monster returns nothing //intègre le monstre créé au Make

		set .monster = monster

	endmethod

	

	method cancelLastAction takes nothing returns boolean

        return .unsaveLoc()

	endmethod

	

	method redoLastAction takes nothing returns boolean 

        if (.locPointeur < .lastLocId) then

            set .locPointeur = .locPointeur + 1

            call .monster.addNewLoc(.lastX[.locPointeur], .lastY[.locPointeur])

            call .setUnitLastClicPosition(.lastX[.locPointeur], .lastY[.locPointeur])

            return true

        endif

		return false

	endmethod	

endstruct

	

	

	

endlibrary//===========================================================================

// Trigger: Monster spawn making Actions

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library MonsterSpawnMakingActions needs Escaper







function MonsterSpawnMaking_Actions takes nothing returns nothing

    local Escaper escaper = Hero2Escaper(GetTriggerUnit())

    local Make mkGeneral = escaper.getMake()

	local MakeMonsterSpawn mk = MakeMonsterSpawn(integer(mkGeneral))

    local real x = GetOrderPointX()

    local real y = GetOrderPointY()

    local Level level

    

    if (not IsIssuedOrder("smart")) then   

        return

    endif

    call StopUnit(mk.maker)

    

	

    if (mk.isLastLocSavedUsed()) then

        set level = escaper.getMakingLevel()

        if(level.monsterSpawns.new(mk.label, mk.mt, mk.sens, mk.frequence, mk.lastX, mk.lastY, x, y, true) != 0)then

            call Text_mkP(mk.makerOwner, "monster spawn \"" + mk.label + "\" created")

            call escaper.destroyMake()

        else

            call Text_erP(mk.makerOwner, "impossible to create monster spawn \"" + mk.label + "\", label propably already in use")

        endif

    else

        call mk.saveLoc(x, y)

    endif

endfunction







endlibrary//===========================================================================

// Trigger: MakeMonsterSpawn

//===========================================================================

//TESH.scrollpos=42

//TESH.alwaysfold=0

library MakeMonsterSpawn needs Make







struct MakeMonsterSpawn extends Make

    real lastX

    real lastY

    private unit unitLastClic

    private boolean lastLocIsSaved

	private boolean lastLocSavedIsUsed

    string label

    MonsterType mt

    string sens

    real frequence

    

    

	static method create takes unit maker, string label, MonsterType mt, string sens, real frequence returns MakeMonsterSpawn

        local MakeMonsterSpawn m

		if (maker == null) then

			return 0

		endif

        set m = MakeMonsterSpawn.allocate()

        set m.maker = maker

		set m.makerOwner = GetOwningPlayer(maker)

        set m.kind = "monsterSpawnCreate"

        set m.label = label

        set m.mt = mt

        set m.sens = sens

        set m.frequence = frequence

        set m.t = CreateTrigger()

        call TriggerAddAction(m.t, Make_GetActions(m.kind))

        call TriggerRegisterUnitEvent(m.t, maker, EVENT_UNIT_ISSUED_POINT_ORDER)

        set m.lastLocIsSaved = false

        set m.lastLocSavedIsUsed = false

        return m

    endmethod

    

    method onDestroy takes nothing returns nothing

		call DestroyTrigger(.t)

		set .t = null

		call RemoveUnit(.unitLastClic)

		set .unitLastClic = null

		set .maker = null

	endmethod	

	

	method saveLoc takes real x, real y returns nothing

		set .lastX = x

		set .lastY = y

        set .lastLocIsSaved = true

		set .lastLocSavedIsUsed = true

		if (.unitLastClic == null) then

			set .unitLastClic = CreateUnit(.makerOwner, MAKE_LAST_CLIC_UNIT_ID, x, y, GetRandomDirectionDeg())

		else

			call SetUnitX(.unitLastClic, x)

			call SetUnitY(.unitLastClic, y)

		endif

        call Hero2Escaper(.maker).destroyCancelledActions()

	endmethod

	

	method unsaveLoc takes nothing returns boolean

		if (not .lastLocSavedIsUsed) then

			return false

		endif

		call RemoveUnit(.unitLastClic)

		set .unitLastClic = null

		set .lastLocSavedIsUsed = false

		return true

	endmethod

	

	method isLastLocSavedUsed takes nothing returns boolean

		return .lastLocSavedIsUsed

	endmethod

	

	method cancelLastAction takes nothing returns boolean

		return .unsaveLoc()

	endmethod

	

	method redoLastAction takes nothing returns boolean

        if (not .lastLocSavedIsUsed and .lastLocIsSaved) then

            call .saveLoc(.lastX, .lastY)

            return true

        endif

        return false

	endmethod

endstruct

	

	

	

endlibrary//===========================================================================

// Trigger: Monster delete Actions

//===========================================================================

//TESH.scrollpos=125

//TESH.alwaysfold=0

library MonsterDeleteActions needs BasicFunctions, Escaper





function MonsterDelete_Actions takes nothing returns nothing



//modes : oneByOne, all, noMove, move, simplePatrol, multiplePatrols



    local Escaper escaper = Hero2Escaper(GetTriggerUnit())

    local Make mkGeneral = escaper.getMake()

	local MakeDeleteMonsters mk = MakeDeleteMonsters(integer(mkGeneral))

    local MonsterNoMove Mnm

    local MonsterSimplePatrol Msp

	local MonsterMultiplePatrols Mmp

    local hashtable suppressionHashTable = InitHashtable()

    local integer nbMonstersRemoved = 0

    local real x = GetOrderPointX()

    local real y = GetOrderPointY()

	local integer i



    if (not IsIssuedOrder("smart")) then

        call FlushParentHashtable(suppressionHashTable)

        set suppressionHashTable = null

        return

    endif

    call StopUnit(mk.maker)

    

    

    if (mk.getMode() == "oneByOne") then

        set Mnm = escaper.getMakingLevel().monstersNoMove.getMonsterNear(x, y)

        if (Mnm != 0 and Mnm.u != null) then

            call Mnm.removeUnit()

            call SaveInteger(suppressionHashTable, 0, nbMonstersRemoved, integer(Mnm))

            set nbMonstersRemoved = 1

        else        

            set Msp = escaper.getMakingLevel().monstersSimplePatrol.getMonsterNear(x, y)

            if (Msp != 0 and Msp.u != null) then

                call Msp.removeUnit()

                call SaveInteger(suppressionHashTable, 0, nbMonstersRemoved, integer(Msp))

                set nbMonstersRemoved = 1

            else        

                set Mmp = escaper.getMakingLevel().monstersMultiplePatrols.getMonsterNear(x, y)

                if (Mmp != 0 and Mmp.u != null) then

                    call Mmp.removeUnit()

                    call SaveInteger(suppressionHashTable, 0, nbMonstersRemoved, integer(Mmp))

                    set nbMonstersRemoved = 1

                endif      

            endif

        endif

        

    else

    

        if (not mk.isLastLocSavedUsed()) then

            call mk.saveLoc(x, y)

            call FlushParentHashtable(suppressionHashTable)

            set suppressionHashTable = null

            return

        endif

        

        if (mk.getMode() == "all") then

            set i = 0

            loop

                exitwhen (i >= MAX_NB_MONSTERS_BY_LEVEL)

                    set Mnm = escaper.getMakingLevel().monstersNoMove.get(i)

                    if (Mnm != 0 and Mnm.u != null and IsUnitBetweenLocs(Mnm.u, mk.lastX, mk.lastY, x, y)) then

                        call Mnm.removeUnit()

                        call SaveInteger(suppressionHashTable, 0, nbMonstersRemoved, integer(Mnm))

                        set nbMonstersRemoved = nbMonstersRemoved + 1

                    endif

                    

                    set Msp = escaper.getMakingLevel().monstersSimplePatrol.get(i)

                    if (Msp != 0 and Msp.u != null and IsUnitBetweenLocs(Msp.u, mk.lastX, mk.lastY, x, y)) then

                        call Msp.removeUnit()

                        call SaveInteger(suppressionHashTable, 0, nbMonstersRemoved, integer(Msp))

                        set nbMonstersRemoved = nbMonstersRemoved + 1

                    endif

                    

                    set Mmp = escaper.getMakingLevel().monstersMultiplePatrols.get(i)

                    if (Mmp != 0 and Mmp.u != null and IsUnitBetweenLocs(Mmp.u, mk.lastX, mk.lastY ,x, y)) then

                        call Mmp.removeUnit()

                        call SaveInteger(suppressionHashTable, 0, nbMonstersRemoved, integer(Mmp))

                        set nbMonstersRemoved = nbMonstersRemoved + 1

                    endif

                set i = i + 1

            endloop

            

        endif

        

        if (mk.getMode() == "noMove") then

            set i = 0

            loop

                exitwhen (i >= MAX_NB_MONSTERS_BY_LEVEL)

                    set Mnm = escaper.getMakingLevel().monstersNoMove.get(i)

                    if (Mnm != 0 and Mnm.u != null and IsUnitBetweenLocs(Mnm.u, mk.lastX, mk.lastY, x, y)) then

                        call Mnm.removeUnit()

                        call SaveInteger(suppressionHashTable, 0, nbMonstersRemoved, integer(Mnm))

                        set nbMonstersRemoved = nbMonstersRemoved + 1

                    endif

                set i = i + 1

            endloop

        endif

        

        if (mk.getMode() == "move") then

            set i = 0

            loop

                exitwhen (i >= MAX_NB_MONSTERS_BY_LEVEL)

                    set Msp = escaper.getMakingLevel().monstersSimplePatrol.get(i)

                    if (Msp != 0 and Msp.u != null and IsUnitBetweenLocs(Msp.u, mk.lastX, mk.lastY, x, y)) then

                        call Msp.removeUnit()

                        call SaveInteger(suppressionHashTable, 0, nbMonstersRemoved, integer(Msp))

                        set nbMonstersRemoved = nbMonstersRemoved + 1

                    endif

                    

                    set Mmp = escaper.getMakingLevel().monstersMultiplePatrols.get(i)

                    if (Mmp != 0 and Mmp.u != null and IsUnitBetweenLocs(Mmp.u, mk.lastX, mk.lastY, x, y)) then

                        call Mmp.removeUnit()

                        call SaveInteger(suppressionHashTable, 0, nbMonstersRemoved, integer(Mmp))

                        set nbMonstersRemoved = nbMonstersRemoved + 1

                    endif

                set i = i + 1

            endloop

        endif

                        

        if (mk.getMode() == "simplePatrol") then

            set i = 0

            loop

                exitwhen (i >= MAX_NB_MONSTERS_BY_LEVEL)

                    set Msp = escaper.getMakingLevel().monstersSimplePatrol.get(i)

                    if (Msp != 0 and Msp.u != null and IsUnitBetweenLocs(Msp.u, mk.lastX, mk.lastY, x, y)) then

                        call Msp.removeUnit()

                        call SaveInteger(suppressionHashTable, 0, nbMonstersRemoved, integer(Msp))

                        set nbMonstersRemoved = nbMonstersRemoved + 1

                    endif

                set i = i + 1

            endloop

        endif

        

        if (mk.getMode() == "multiplePatrols") then

            set i = 0

            loop

                exitwhen i >= MAX_NB_MONSTERS_BY_LEVEL

                    set Mmp = escaper.getMakingLevel().monstersMultiplePatrols.get(i)

                    if (Mmp != 0 and Mmp.u != null and IsUnitBetweenLocs(Mmp.u, mk.lastX, mk.lastY, x, y)) then

                        call Mmp.removeUnit()

                        call SaveInteger(suppressionHashTable, 0, nbMonstersRemoved, integer(Mmp))

                        set nbMonstersRemoved = nbMonstersRemoved + 1

                    endif

                set i = i + 1

            endloop

        endif

    endif

    

    if (nbMonstersRemoved <= 1) then

        call Text_mkP(mk.makerOwner, I2S(nbMonstersRemoved) + " monster removed.")

    else

        call Text_mkP(mk.makerOwner, I2S(nbMonstersRemoved) + " monsters removed.")

    endif

    

	if (nbMonstersRemoved > 0) then

		call escaper.newAction(MakeDeleteMonstersAction.create(escaper.getMakingLevel(), suppressionHashTable))

    endif

    

    call mk.unsaveLocDefinitely()

    

    call FlushParentHashtable(suppressionHashTable)

    set suppressionHashTable = null

endfunction







endlibrary



//===========================================================================

// Trigger: MakeDeleteMonsters

//

//                 if Monster( monsters[ i ] ).getType() == MonsterNoMove.typeid then

//                     call MonsterNoMove( monsters[ i ] ).createUnit()

//                 endif

//                 if Monster( monsters[ i ] ).getType() == MonsterSimplePatrol.typeid then

//                     call MonsterSimplePatrol( monsters[ i ] ).createUnit()

//                 endif

//                 if Monster( monsters[ i ] ).getType() == MonsterMultiplePatrols.typeid then

//                     call Text.A("Mmp")

//                     call MonsterMultiplePatrols( monsters[ i ] ).createUnit()

//                 endif

//===========================================================================

//TESH.scrollpos=46

//TESH.alwaysfold=0

library MakeDeleteMonsters needs Make









struct MakeDeleteMonsters extends Make

    real lastX

    real lastY

    private boolean lastLocIsSaved

	private boolean lastLocSavedIsUsed

    private unit unitLastClic

    private string mode

	

	method isLastLocSavedUsed takes nothing returns boolean

		return .lastLocSavedIsUsed

	endmethod

    

    static method create takes unit maker, string mode returns MakeDeleteMonsters

	    local MakeDeleteMonsters m

		if (maker == null) then

			return 0

		endif

        set m = MakeDeleteMonsters.allocate()

        set m.maker = maker

		set m.makerOwner = GetOwningPlayer(maker)

        set m.kind = "deleteMonsters"

        set m.mode = mode

        set m.lastLocIsSaved = false

        set m.lastLocSavedIsUsed = false

        set m.t = CreateTrigger()

        call TriggerAddAction(m.t, Make_GetActions(m.kind))

        call TriggerRegisterUnitEvent(m.t, m.maker, EVENT_UNIT_ISSUED_POINT_ORDER)

        return m

	endmethod

    

    method onDestroy takes nothing returns nothing

		call DestroyTrigger(.t)

		set .t = null

		set .maker = null

        call RemoveUnit(.unitLastClic)

        set .unitLastClic = null

    endmethod

    

	method saveLoc takes real x, real y returns nothing

		set .lastX = x

		set .lastY = y

        set .lastLocIsSaved = true

		set .lastLocSavedIsUsed = true

		if (.unitLastClic == null) then

			set .unitLastClic = CreateUnit(.makerOwner, MAKE_LAST_CLIC_UNIT_ID, x, y, GetRandomDirectionDeg())

		else

			call SetUnitX(.unitLastClic, x)

			call SetUnitY(.unitLastClic, y)

		endif

        call Hero2Escaper(.maker).destroyCancelledActions()

	endmethod

	

	method unsaveLoc takes nothing returns boolean

		if (not .lastLocSavedIsUsed) then

			return false

		endif

		call RemoveUnit(.unitLastClic)

		set .unitLastClic = null

		set .lastLocSavedIsUsed = false

		return true

	endmethod

    

    method unsaveLocDefinitely takes nothing returns nothing

        call .unsaveLoc()

        set .lastLocIsSaved = false

    endmethod

    

    method cancelLastAction takes nothing returns boolean

        return .unsaveLoc()

    endmethod

	

	method redoLastAction takes nothing returns boolean

		if (.lastLocIsSaved and not .lastLocSavedIsUsed) then

            call .saveLoc(.lastX, .lastY)

            return true

        endif

        return false

	endmethod	

    

    method getMode takes nothing returns string

        return .mode

    endmethod

endstruct







endlibrary

//===========================================================================

// Trigger: Meteor making Actions

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library MeteorMakingActions needs BasicFunctions, Escaper







function MeteorMaking_Actions takes nothing returns nothing

    local Meteor meteor

    local Escaper escaper = Hero2Escaper(GetTriggerUnit())

    local Make mkGeneral = escaper.getMake()

	local MakeMeteor mk = MakeMeteor(integer(mkGeneral))

    local real x = GetOrderPointX()

    local real y = GetOrderPointY()



    if (not IsIssuedOrder("smart")) then

        return

    endif

    call StopUnit(mk.maker)

    

    set meteor = escaper.getMakingLevel().meteors.new(x, y, true)

    call escaper.newAction(MakeMeteorAction.create(escaper.getMakingLevel(), meteor))

endfunction







endlibrary//===========================================================================

// Trigger: MakeMeteor

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library MakeMeteor needs Make







struct MakeMeteor extends Make    	

	static method create takes unit maker returns MakeMeteor

        local MakeMeteor m

		if (maker == null) then

			return 0

		endif

        set m = MakeMeteor.allocate()

        set m.maker = maker

        set m.kind = "meteorCreate"

        set m.t = CreateTrigger()

        call TriggerAddAction(m.t, Make_GetActions(m.kind))

        call TriggerRegisterUnitEvent(m.t, m.maker, EVENT_UNIT_ISSUED_POINT_ORDER)

        return m

    endmethod

    

    method onDestroy takes nothing returns nothing

		call DestroyTrigger(.t)

		set .t = null

		set .maker = null

	endmethod

	

	method cancelLastAction takes nothing returns boolean

        return false

	endmethod

	

	method redoLastAction takes nothing returns boolean

        return false

	endmethod	

endstruct

	

	

	

	

endlibrary

//===========================================================================

// Trigger: Meteor delete Actions

//===========================================================================

//TESH.scrollpos=33

//TESH.alwaysfold=0

library MeteorDeleteActions needs BasicFunctions, Escaper





function MeteorDelete_Actions takes nothing returns nothing



//modes : oneByOne, twoClics



    local Escaper escaper = Hero2Escaper(GetTriggerUnit())

    local Make mkGeneral = escaper.getMake()

	local MakeDeleteMeteors mk = MakeDeleteMeteors(integer(mkGeneral))

    local Meteor meteor

    local hashtable suppressionHashTable = InitHashtable()

    local integer nbMeteorsRemoved = 0

    local real x = GetOrderPointX()

    local real y = GetOrderPointY()

	local integer i



    if (not IsIssuedOrder("smart")) then

        call FlushParentHashtable(suppressionHashTable)

        set suppressionHashTable = null

        return

    endif

    call StopUnit(mk.maker)

    

    

    if (mk.getMode() == "oneByOne") then

        if (GetItemTypeId(GetOrderTargetItem()) != METEOR_NORMAL) then

            call FlushParentHashtable(suppressionHashTable)

            set suppressionHashTable = null

            return

        endif        

        set meteor = Meteor(GetItemUserData(GetOrderTargetItem()))

        if (meteor != 0 and meteor.getItem() != null) then

            call meteor.removeMeteor()

            call SaveInteger(suppressionHashTable, 0, nbMeteorsRemoved, integer(meteor))

            set nbMeteorsRemoved = 1

        endif

    else

        //mode twoClics

        if (not mk.isLastLocSavedUsed()) then

            call mk.saveLoc(x, y)

            call FlushParentHashtable(suppressionHashTable)

            set suppressionHashTable = null

            return

        endif

        

        set i = 0

        loop

            exitwhen (i > escaper.getMakingLevel().meteors.getLastInstanceId())

                set meteor = escaper.getMakingLevel().meteors.get(i)

                if (meteor != 0 and meteor.getItem() != null and IsItemBetweenLocs(meteor.getItem(), mk.lastX, mk.lastY, x, y)) then

                    call meteor.removeMeteor()

                    call SaveInteger(suppressionHashTable, 0, nbMeteorsRemoved, integer(meteor))

                    set nbMeteorsRemoved = nbMeteorsRemoved + 1

                endif

            set i = i + 1

        endloop

    endif

    

    if (nbMeteorsRemoved <= 1) then

        call Text_mkP(mk.makerOwner, I2S(nbMeteorsRemoved) + " meteor removed.")

    else

        call Text_mkP(mk.makerOwner, I2S(nbMeteorsRemoved) + " meteors removed.")

    endif

    

	if (nbMeteorsRemoved > 0) then

		call escaper.newAction(MakeDeleteMeteorsAction.create(escaper.getMakingLevel(), suppressionHashTable))

	endif

    

    call mk.unsaveLocDefinitely()

    

    call FlushParentHashtable(suppressionHashTable)

    set suppressionHashTable = null

endfunction







endlibrary



//===========================================================================

// Trigger: MakeDeleteMeteors

//

//                 if Monster( monsters[ i ] ).getType() == MonsterNoMove.typeid then

//                     call MonsterNoMove( monsters[ i ] ).createUnit()

//                 endif

//                 if Monster( monsters[ i ] ).getType() == MonsterSimplePatrol.typeid then

//                     call MonsterSimplePatrol( monsters[ i ] ).createUnit()

//                 endif

//                 if Monster( monsters[ i ] ).getType() == MonsterMultiplePatrols.typeid then

//                     call Text.A("Mmp")

//                     call MonsterMultiplePatrols( monsters[ i ] ).createUnit()

//                 endif

//===========================================================================

//TESH.scrollpos=49

//TESH.alwaysfold=0

library MakeDeleteMeteors needs Make







struct MakeDeleteMeteors extends Make

    real lastX

    real lastY

    private boolean lastLocIsSaved

	private boolean lastLocSavedIsUsed

    private unit unitLastClic

    private string mode

	

	method isLastLocSavedUsed takes nothing returns boolean

		return .lastLocSavedIsUsed

	endmethod

    

    static method create takes unit maker, string mode returns MakeDeleteMeteors

        //modes : oneByOne, twoClics

	    local MakeDeleteMeteors m

		if (maker == null or (mode != "oneByOne" and mode != "twoClics")) then

			return 0

		endif

        set m = MakeDeleteMeteors.allocate()

        set m.maker = maker

		set m.makerOwner = GetOwningPlayer(maker)

        set m.kind = "deleteMeteors"

        set m.mode = mode

        set m.lastLocIsSaved = false

        set m.lastLocSavedIsUsed = false

        set m.t = CreateTrigger()

        call TriggerAddAction(m.t, Make_GetActions(m.kind))

        call TriggerRegisterUnitEvent(m.t, m.maker, EVENT_UNIT_ISSUED_POINT_ORDER)

        if (mode == "oneByOne") then

            call TriggerRegisterUnitEvent(m.t, m.maker, EVENT_UNIT_ISSUED_TARGET_ORDER)

        endif

        return m

	endmethod

    

    method onDestroy takes nothing returns nothing

		call DestroyTrigger(.t)

		set .t = null

		set .maker = null

        call RemoveUnit(.unitLastClic)

        set .unitLastClic = null

    endmethod

    

	method saveLoc takes real x, real y returns nothing

		set .lastX = x

		set .lastY = y

        set .lastLocIsSaved = true

		set .lastLocSavedIsUsed = true

		if (.unitLastClic == null) then

			set .unitLastClic = CreateUnit(.makerOwner, MAKE_LAST_CLIC_UNIT_ID, x, y, GetRandomDirectionDeg())

		else

			call SetUnitX(.unitLastClic, x)

			call SetUnitY(.unitLastClic, y)

		endif

        call Hero2Escaper(.maker).destroyCancelledActions()

	endmethod

	

	method unsaveLoc takes nothing returns boolean

		if (not .lastLocSavedIsUsed) then

			return false

		endif

		call RemoveUnit(.unitLastClic)

		set .unitLastClic = null

		set .lastLocSavedIsUsed = false

		return true

	endmethod

    

    method unsaveLocDefinitely takes nothing returns nothing

        call .unsaveLoc()

        set .lastLocIsSaved = false

    endmethod

    

    method cancelLastAction takes nothing returns boolean

        return .unsaveLoc()

    endmethod

	

	method redoLastAction takes nothing returns boolean

		if (.lastLocIsSaved and not .lastLocSavedIsUsed) then

            call .saveLoc(.lastX, .lastY)

            return true

        endif

        return false

	endmethod	

    

    method getMode takes nothing returns string

        return .mode

    endmethod

endstruct







endlibrary

//===========================================================================

// Trigger: Terrain making Actions

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library TerrainMakingActions needs Escaper





function TerrainMaking_Actions takes nothing returns nothing

    local MakeAction action

    local Escaper escaper = Hero2Escaper(GetTriggerUnit())

    local Make mkGeneral = escaper.getMake()

	local MakeTerrainCreate mk = MakeTerrainCreate(integer(mkGeneral))

    local real x = GetOrderPointX()

    local real y = GetOrderPointY() 

    

    if (not IsIssuedOrder("smart")) then

        return

    endif

    call StopUnit(mk.maker)	

    

    if (mk.isLastLocSavedUsed()) then

        set action = MakeTerrainCreateAction.create(mk.getTerrainType(), mk.lastX, mk.lastY, x, y)

        if (action == -1) then

            call Text_erP(escaper.getPlayer(), "this terrain type doesn't exist anymore")

        else

            if (action == 0) then

                call Text_erP(escaper.getPlayer(), "too big zone")

            else

                call escaper.newAction(action)

                call mk.unsaveLocDefinitely()

            endif

        endif

    else

        call mk.saveLoc(x, y)

    endif

endfunction





endlibrary//===========================================================================

// Trigger: MakeTerrainCreate

//===========================================================================

//TESH.scrollpos=45

//TESH.alwaysfold=0

library MakeTerrainCreate needs Make, BasicFunctions, ModifyTerrainFunctions







struct MakeTerrainCreate extends Make    

    real lastX

    real lastY

    private boolean lastLocIsSaved

	private boolean lastLocSavedIsUsed

    private unit unitLastClic

    private TerrainType terrainType

	

	method isLastLocSavedUsed takes nothing returns boolean

		return .lastLocSavedIsUsed

	endmethod

	

    method getTerrainType takes nothing returns TerrainType

        return .terrainType

    endmethod

	

	static method create takes unit maker, TerrainType terrainType returns MakeTerrainCreate

        local MakeTerrainCreate m

		if (maker == null or terrainType == 0) then

			return 0

		endif

        set m = MakeTerrainCreate.allocate()

        set m.maker = maker

		set m.makerOwner = GetOwningPlayer(maker)

        set m.terrainType = terrainType

        set m.kind = "terrainCreate"

        set m.t = CreateTrigger()

        call TriggerAddAction(m.t, Make_GetActions(m.kind))

        call TriggerRegisterUnitEvent(m.t, maker, EVENT_UNIT_ISSUED_POINT_ORDER)

        set m.lastLocIsSaved = false

        set m.lastLocSavedIsUsed = false

        return m

    endmethod

    

    method onDestroy takes nothing returns nothing

		call DestroyTrigger(.t)

		set .t = null

		call RemoveUnit(.unitLastClic)

		set .unitLastClic = null

		set .maker = null

	endmethod	

	

	method saveLoc takes real x, real y returns nothing

		set .lastX = x

		set .lastY = y

        set .lastLocIsSaved = true

		set .lastLocSavedIsUsed = true

		if (.unitLastClic == null) then

			set .unitLastClic = CreateUnit(.makerOwner, MAKE_LAST_CLIC_UNIT_ID, x, y, GetRandomDirectionDeg())

		else

			call SetUnitX(.unitLastClic, x)

			call SetUnitY(.unitLastClic, y)

		endif

        call Hero2Escaper(.maker).destroyCancelledActions()

	endmethod

	

	method unsaveLoc takes nothing returns boolean

		if (not .lastLocSavedIsUsed) then

			return false

		endif

		call RemoveUnit(.unitLastClic)

		set .unitLastClic = null

		set .lastLocSavedIsUsed = false

		return true

	endmethod

    

    method unsaveLocDefinitely takes nothing returns nothing

        call .unsaveLoc()

        set .lastLocIsSaved = false

    endmethod

    

    method cancelLastAction takes nothing returns boolean

        return .unsaveLoc()

    endmethod

    

    method redoLastAction takes nothing returns boolean

        if (.lastLocIsSaved and not .lastLocSavedIsUsed) then

            call .saveLoc(.lastX, .lastY)

            return true

        endif

        return false

    endmethod

endstruct







endlibrary

//===========================================================================

// Trigger: Terrain copy paste Actions

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library TerrainCopyPasteActions needs Escaper





function TerrainCopyPaste_Actions takes nothing returns nothing

    local Escaper escaper = Hero2Escaper(GetTriggerUnit())

    local Make mkGeneral = escaper.getMake()

	local MakeTerrainCopyPaste mk = MakeTerrainCopyPaste(integer(mkGeneral))

    local real x = GetOrderPointX()

    local real y = GetOrderPointY() 

    

    if (not IsIssuedOrder("smart")) then

        return

    endif

    call StopUnit(mk.maker)	

    

    call mk.saveLoc(x, y)

endfunction







endlibrary//===========================================================================

// Trigger: MakeTerrainCopyPaste

//===========================================================================

//TESH.scrollpos=142

//TESH.alwaysfold=0

library MakeTerrainCopyPaste needs Make, BasicFunctions, ModifyTerrainFunctions, Escaper







struct MakeTerrainCopyPaste extends Make

    real x1

    real y1

    real x2

    real y2

    real x3

    real y3

    private unit unitLastClic1

    private unit unitLastClic2

    private unit unitLastClic3

    private boolean isPoint1Saved

    private boolean isPoint2Saved

    private boolean isPoint3Saved

    private boolean isPoint1Used

    private boolean isPoint2Used

    private boolean isPoint3Used

    

	

	static method create takes unit maker returns MakeTerrainCopyPaste

        local MakeTerrainCopyPaste m

		if (maker == null) then

			return 0

		endif

        set m = MakeTerrainCopyPaste.allocate()

        set m.maker = maker

		set m.makerOwner = GetOwningPlayer(maker)

        set m.kind = "terrainCopyPaste"

        set m.t = CreateTrigger()

        call TriggerAddAction(m.t, Make_GetActions(m.kind))

        call TriggerRegisterUnitEvent(m.t, maker, EVENT_UNIT_ISSUED_POINT_ORDER)

        set m.isPoint1Saved = false

        set m.isPoint2Saved = false

        set m.isPoint3Saved = false

        set m.isPoint1Used = false

        set m.isPoint2Used = false

        set m.isPoint3Used = false

        return m

    endmethod

    

    method onDestroy takes nothing returns nothing

		call DestroyTrigger(.t)

		set .t = null

		call RemoveUnit(.unitLastClic1)

		set .unitLastClic1 = null

		call RemoveUnit(.unitLastClic2)

		set .unitLastClic2 = null

		call RemoveUnit(.unitLastClic3)

		set .unitLastClic3 = null

		set .maker = null

	endmethod	

    

    private method createUnitClic takes unit u, real x, real y returns unit

		if (u == null) then

			set u = CreateUnit(.makerOwner, MAKE_LAST_CLIC_UNIT_ID, x, y, GetRandomDirectionDeg())

		else

			call SetUnitX(u, x)

			call SetUnitY(u, y)

		endif

        return u

    endmethod

    

    method unsaveLoc takes integer locId returns nothing

        if (locId == 1) then

            set .isPoint1Used = false

            call RemoveUnit(.unitLastClic1)

            set .unitLastClic1 = null

        else

            if (locId == 2) then

                set .isPoint2Used = false

                call RemoveUnit(.unitLastClic2)

                set .unitLastClic2 = null

            else

                if (locId == 3) then

                    set .isPoint3Used = false

                    call RemoveUnit(.unitLastClic3)

                    set .unitLastClic3 = null

                endif

            endif

        endif

    endmethod

    

    method unsaveLocDefinitely takes integer locId returns nothing

        call .unsaveLoc(locId)

        if (locId == 1) then

            set .isPoint1Saved = false

        else

            if (locId == 2) then

                set .isPoint2Saved = false

            else

                if (locId == 3) then

                    set .isPoint3Saved = false

                endif

            endif

        endif

    endmethod

    

    method unsaveLocsDefinitely takes nothing returns nothing

        call .unsaveLocDefinitely(1)

        call .unsaveLocDefinitely(2)

        call .unsaveLocDefinitely(3)

    endmethod

     

	method saveLoc takes real x, real y returns nothing

        local MakeAction action

        if (not .isPoint1Used) then

            set .unitLastClic1 = .createUnitClic(.unitLastClic1, x, y)

            set .x1 = x

            set .y1 = y

            set .isPoint1Saved = true

            set .isPoint1Used = true

            call .unsaveLocDefinitely(2)

            call .unsaveLocDefinitely(3)

        else

            if (not .isPoint2Used) then

                if (GetNbCaseBetween(.x1, .y1, x, y) > NB_MAX_TILES_MODIFIED) then

                    call Text_erP(.makerOwner, "Too big zone !")

                    return

                endif

                set .unitLastClic2 = .createUnitClic(.unitLastClic2, x, y)

                set .x2 = x

                set .y2 = y

                set .isPoint2Saved = true

                set .isPoint2Used = true

                call .unsaveLocDefinitely(3)

            else

                if (not .isPoint3Used) then

                    set .unitLastClic3 = .createUnitClic(.unitLastClic3, x, y)

                    set .x3 = x

                    set .y3 = y

                    set .isPoint3Saved = true

                    set .isPoint3Used = true

                else

                    set action = MakeTerrainCopyPasteAction.create(.x1, .y1, .x2, .y2, .x3, .y3, x, y)

                    if (action != 0) then

                        call .unsaveLocsDefinitely()

                        call Hero2Escaper(.maker).newAction(action)

                    else

                        call Text_erP(.makerOwner, "paste zone out of bounds")

                    endif

                endif

            endif

        endif

        call Hero2Escaper(.maker).destroyCancelledActions()

	endmethod

    

    method cancelLastAction takes nothing returns boolean

        if (.isPoint3Used) then

            call .unsaveLoc(3)

            return true

        else

            if (.isPoint2Used) then

                call .unsaveLoc(2)

                return true

            else

                if (.isPoint1Used) then

                    call .unsaveLoc(1)

                    return true

                endif

            endif

        endif

        return false

    endmethod

    

    method redoLastAction takes nothing returns boolean

        if (.isPoint1Saved and not .isPoint1Used) then

            call .saveLoc(.x1, .y1)

            return true

        else

            if (.isPoint2Saved and not .isPoint2Used) then

                call .saveLoc(.x2, .y2)

                return true

            else

                if (.isPoint3Saved and not .isPoint3Used) then

                    call .saveLoc(.x3, .y3)

                    return true

                endif

            endif

        endif

        return false

    endmethod

endstruct







endlibrary//===========================================================================

// Trigger: Terrain vertical symmetry Actions

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library TerrainVerticalSymmetryActions needs Escaper





function TerrainVerticalSymmetry_Actions takes nothing returns nothing

    local MakeAction action

    local Escaper escaper = Hero2Escaper(GetTriggerUnit())

    local Make mkGeneral = escaper.getMake()

	local MakeTerrainVerticalSymmetry mk = MakeTerrainVerticalSymmetry(integer(mkGeneral))

    local real x = GetOrderPointX()

    local real y = GetOrderPointY() 

    

    if (not IsIssuedOrder("smart")) then

        return

    endif

    call StopUnit(mk.maker)	

    

    if (mk.isLastLocSavedUsed()) then

        set action = MakeTerrainVerticalSymmetryAction.create(mk.lastX, mk.lastY, x, y)

        if (action == 0) then

            call Text_erP(escaper.getPlayer(), "too big zone")

        else

            call escaper.newAction(action)

            call mk.unsaveLocDefinitely()

        endif

    else

        call mk.saveLoc(x, y)

    endif

endfunction





endlibrary//===========================================================================

// Trigger: MakeTerrainVerticalSymmetry

//===========================================================================

//TESH.scrollpos=38

//TESH.alwaysfold=0

library MakeTerrainVerticalSymmetry needs Make, BasicFunctions, ModifyTerrainFunctions







struct MakeTerrainVerticalSymmetry extends Make    

    real lastX

    real lastY

    private boolean lastLocIsSaved

	private boolean lastLocSavedIsUsed

    private unit unitLastClic

	

	method isLastLocSavedUsed takes nothing returns boolean

		return .lastLocSavedIsUsed

	endmethod

	

	static method create takes unit maker returns MakeTerrainVerticalSymmetry

        local MakeTerrainVerticalSymmetry m

		if (maker == null) then

			return 0

		endif

        set m = MakeTerrainVerticalSymmetry.allocate()

        set m.maker = maker

		set m.makerOwner = GetOwningPlayer(maker)

        set m.kind = "terrainVerticalSymmetry"

        set m.t = CreateTrigger()

        call TriggerAddAction(m.t, Make_GetActions(m.kind))

        call TriggerRegisterUnitEvent(m.t, maker, EVENT_UNIT_ISSUED_POINT_ORDER)

        set m.lastLocIsSaved = false

        set m.lastLocSavedIsUsed = false

        return m

    endmethod

    

    method onDestroy takes nothing returns nothing

		call DestroyTrigger(.t)

		set .t = null

		call RemoveUnit(.unitLastClic)

		set .unitLastClic = null

		set .maker = null

	endmethod	

	

	method saveLoc takes real x, real y returns nothing

		set .lastX = x

		set .lastY = y

        set .lastLocIsSaved = true

		set .lastLocSavedIsUsed = true

		if (.unitLastClic == null) then

			set .unitLastClic = CreateUnit(.makerOwner, MAKE_LAST_CLIC_UNIT_ID, x, y, GetRandomDirectionDeg())

		else

			call SetUnitX(.unitLastClic, x)

			call SetUnitY(.unitLastClic, y)

		endif

        call Hero2Escaper(.maker).destroyCancelledActions()

	endmethod

	

	method unsaveLoc takes nothing returns boolean

		if (not .lastLocSavedIsUsed) then

			return false

		endif

		call RemoveUnit(.unitLastClic)

		set .unitLastClic = null

		set .lastLocSavedIsUsed = false

		return true

	endmethod

    

    method unsaveLocDefinitely takes nothing returns nothing

        call .unsaveLoc()

        set .lastLocIsSaved = false

    endmethod

    

    method cancelLastAction takes nothing returns boolean

        return .unsaveLoc()

    endmethod

    

    method redoLastAction takes nothing returns boolean

        if (.lastLocIsSaved and not .lastLocSavedIsUsed) then

            call .saveLoc(.lastX, .lastY)

            return true

        endif

        return false

    endmethod

endstruct







endlibrary//===========================================================================

// Trigger: Terrain horizontal symmetry Actions

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library TerrainHorizontalSymmetryActions needs Escaper





function TerrainHorizontalSymmetry_Actions takes nothing returns nothing

    local MakeAction action

    local Escaper escaper = Hero2Escaper(GetTriggerUnit())

    local Make mkGeneral = escaper.getMake()

	local MakeTerrainHorizontalSymmetry mk = MakeTerrainHorizontalSymmetry(integer(mkGeneral))

    local real x = GetOrderPointX()

    local real y = GetOrderPointY() 

    

    if (not IsIssuedOrder("smart")) then

        return

    endif

    call StopUnit(mk.maker)	

    

    if (mk.isLastLocSavedUsed()) then

        set action = MakeTerrainHorizontalSymmetryAction.create(mk.lastX, mk.lastY, x, y)

        if (action == 0) then

            call Text_erP(escaper.getPlayer(), "too big zone")

        else

            call escaper.newAction(action)

            call mk.unsaveLocDefinitely()

        endif

    else

        call mk.saveLoc(x, y)

    endif

endfunction





endlibrary//===========================================================================

// Trigger: MakeTerrainHorizontalSymmetry

//===========================================================================

//TESH.scrollpos=38

//TESH.alwaysfold=0

library MakeTerrainHorizontalSymmetry needs Make, BasicFunctions, ModifyTerrainFunctions







struct MakeTerrainHorizontalSymmetry extends Make    

    real lastX

    real lastY

    private boolean lastLocIsSaved

	private boolean lastLocSavedIsUsed

    private unit unitLastClic

	

	method isLastLocSavedUsed takes nothing returns boolean

		return .lastLocSavedIsUsed

	endmethod

	

	static method create takes unit maker returns MakeTerrainHorizontalSymmetry

        local MakeTerrainHorizontalSymmetry m

		if (maker == null) then

			return 0

		endif

        set m = MakeTerrainHorizontalSymmetry.allocate()

        set m.maker = maker

		set m.makerOwner = GetOwningPlayer(maker)

        set m.kind = "terrainHorizontalSymmetry"

        set m.t = CreateTrigger()

        call TriggerAddAction(m.t, Make_GetActions(m.kind))

        call TriggerRegisterUnitEvent(m.t, maker, EVENT_UNIT_ISSUED_POINT_ORDER)

        set m.lastLocIsSaved = false

        set m.lastLocSavedIsUsed = false

        return m

    endmethod

    

    method onDestroy takes nothing returns nothing

		call DestroyTrigger(.t)

		set .t = null

		call RemoveUnit(.unitLastClic)

		set .unitLastClic = null

		set .maker = null

	endmethod	

	

	method saveLoc takes real x, real y returns nothing

		set .lastX = x

		set .lastY = y

        set .lastLocIsSaved = true

		set .lastLocSavedIsUsed = true

		if (.unitLastClic == null) then

			set .unitLastClic = CreateUnit(.makerOwner, MAKE_LAST_CLIC_UNIT_ID, x, y, GetRandomDirectionDeg())

		else

			call SetUnitX(.unitLastClic, x)

			call SetUnitY(.unitLastClic, y)

		endif

        call Hero2Escaper(.maker).destroyCancelledActions()

	endmethod

	

	method unsaveLoc takes nothing returns boolean

		if (not .lastLocSavedIsUsed) then

			return false

		endif

		call RemoveUnit(.unitLastClic)

		set .unitLastClic = null

		set .lastLocSavedIsUsed = false

		return true

	endmethod

    

    method unsaveLocDefinitely takes nothing returns nothing

        call .unsaveLoc()

        set .lastLocIsSaved = false

    endmethod

    

    method cancelLastAction takes nothing returns boolean

        return .unsaveLoc()

    endmethod

    

    method redoLastAction takes nothing returns boolean

        if (.lastLocIsSaved and not .lastLocSavedIsUsed) then

            call .saveLoc(.lastX, .lastY)

            return true

        endif

        return false

    endmethod

endstruct







endlibrary//===========================================================================

// Trigger: Make exchange terrains Actions

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library MakeExchangeTerrainsActions needs Escaper, ExchangeTerrains





function MakeExchangeTerrains_Actions takes nothing returns nothing

    local Escaper escaper = Hero2Escaper(GetTriggerUnit())

    local Make mkGeneral = escaper.getMake()

	local MakeExchangeTerrains mk = MakeExchangeTerrains(integer(mkGeneral))

    local real x = GetOrderPointX()

    local real y = GetOrderPointY() 

    local TerrainType terrainTypeA

    local TerrainType terrainTypeB

    

    if (not IsIssuedOrder("smart")) then

        return

    endif

    call StopUnit(mk.maker)	

    

    if (mk.isLastLocSavedUsed()) then

        set terrainTypeA = udg_terrainTypes.getTerrainType(mk.lastX, mk.lastY)

        set terrainTypeB = udg_terrainTypes.getTerrainType(x, y)

        call ExchangeTerrains(terrainTypeA.label, terrainTypeB.label)

        call mk.unsaveLocDefinitely()

    else

        call mk.saveLoc(x, y)

    endif

endfunction





endlibrary

//===========================================================================

// Trigger: MakeExchangeTerrains

//===========================================================================

//TESH.scrollpos=39

//TESH.alwaysfold=0

library MakeExchangeTerrains needs Make, BasicFunctions, ModifyTerrainFunctions







struct MakeExchangeTerrains extends Make    

    real lastX

    real lastY

    private boolean lastLocIsSaved

	private boolean lastLocSavedIsUsed

    private unit unitLastClic

	

    	

	static method create takes unit maker returns MakeExchangeTerrains

        local MakeExchangeTerrains m

		if (maker == null) then

			return 0

		endif

        set m = MakeExchangeTerrains.allocate()

        set m.maker = maker

		set m.makerOwner = GetOwningPlayer(maker)

        set m.kind = "exchangeTerrains"

        set m.t = CreateTrigger()

        call TriggerAddAction(m.t, Make_GetActions(m.kind))

        call TriggerRegisterUnitEvent(m.t, maker, EVENT_UNIT_ISSUED_POINT_ORDER)

        set m.lastLocIsSaved = false

        set m.lastLocSavedIsUsed = false

        return m

    endmethod

    

    method onDestroy takes nothing returns nothing

		call DestroyTrigger(.t)

		set .t = null

		call RemoveUnit(.unitLastClic)

		set .unitLastClic = null

		set .maker = null

	endmethod	

	

	method saveLoc takes real x, real y returns nothing

		set .lastX = x

		set .lastY = y

        set .lastLocIsSaved = true

		set .lastLocSavedIsUsed = true

		if (.unitLastClic == null) then

			set .unitLastClic = CreateUnit(.makerOwner, MAKE_LAST_CLIC_UNIT_ID, x, y, GetRandomDirectionDeg())

		else

			call SetUnitX(.unitLastClic, x)

			call SetUnitY(.unitLastClic, y)

		endif

        call Hero2Escaper(.maker).destroyCancelledActions()

	endmethod

	

	method unsaveLoc takes nothing returns boolean

		if (not .lastLocSavedIsUsed) then

			return false

		endif

		call RemoveUnit(.unitLastClic)

		set .unitLastClic = null

		set .lastLocSavedIsUsed = false

		return true

	endmethod

    

    method unsaveLocDefinitely takes nothing returns nothing

        call .unsaveLoc()

        set .lastLocIsSaved = false

    endmethod

	

	method isLastLocSavedUsed takes nothing returns boolean

		return .lastLocSavedIsUsed

	endmethod

    

    method cancelLastAction takes nothing returns boolean

        return .unsaveLoc()

    endmethod

    

    method redoLastAction takes nothing returns boolean

        if (.lastLocIsSaved and not .lastLocSavedIsUsed) then

            call .saveLoc(.lastX, .lastY)

            return true

        endif

        return false

    endmethod

endstruct







endlibrary//===========================================================================

// Trigger: Start making Actions

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library StartMakingActions needs Escaper







function StartMaking_Actions takes nothing returns nothing

    local Escaper escaper = Hero2Escaper(GetTriggerUnit())

    local Make mkGeneral = escaper.getMake()

	local MakeStart mk = MakeStart(integer(mkGeneral))

    local real x = GetOrderPointX()

    local real y = GetOrderPointY()

    local Level level

    

    if (not IsIssuedOrder("smart")) then   

        return

    endif

    call StopUnit(mk.maker)

    

	

    if (mk.isLastLocSavedUsed()) then

        set level = escaper.getMakingLevel()

        if (mk.forNext()) then

            if (udg_levels.get(level.getId() + 1) == 0) then

                if (not udg_levels.new()) then

                    call Text_erP(escaper.getPlayer(), "nombre maximum de niveaux atteint")

                    call escaper.destroyMake()

                    return

                endif

            endif

            set level = udg_levels.get(level.getId() + 1)

            if (level == 0) then

                call Text_erP(escaper.getPlayer(), "erreur d'origine inconnue")

                call escaper.destroyMake()

                return

            endif

        endif

        call level.newStart(mk.lastX, mk.lastY, x, y)

        call Text_mkP(mk.makerOwner, "start made for level " + I2S(level.getId()))

        call escaper.destroyMake()

    else

        call mk.saveLoc(x, y)

    endif

endfunction







endlibrary

//===========================================================================

// Trigger: MakeStart

//===========================================================================

//TESH.scrollpos=39

//TESH.alwaysfold=0

library MakeStart needs Make







struct MakeStart extends Make

    real lastX

    real lastY

    private unit unitLastClic

    private boolean lastLocIsSaved

	private boolean lastLocSavedIsUsed

    private boolean forNextB //à true si on veut créer le start du niveau suivant

    

	static method create takes unit maker, boolean forNext returns MakeStart

        local MakeStart m

		if (maker == null) then

			return 0

		endif

        set m = MakeStart.allocate()

        set m.maker = maker

		set m.makerOwner = GetOwningPlayer(maker)

        set m.kind = "startCreate"

        set m.t = CreateTrigger()

        call TriggerAddAction(m.t, Make_GetActions(m.kind))

        call TriggerRegisterUnitEvent(m.t, maker, EVENT_UNIT_ISSUED_POINT_ORDER)

        set m.lastLocIsSaved = false

        set m.lastLocSavedIsUsed = false

        set m.forNextB = forNext

        return m

    endmethod

    

    method onDestroy takes nothing returns nothing

		call DestroyTrigger(.t)

		set .t = null

		call RemoveUnit(.unitLastClic)

		set .unitLastClic = null

		set .maker = null

	endmethod	

	

	method saveLoc takes real x, real y returns nothing

		set .lastX = x

		set .lastY = y

        set .lastLocIsSaved = true

		set .lastLocSavedIsUsed = true

		if (.unitLastClic == null) then

			set .unitLastClic = CreateUnit(.makerOwner, MAKE_LAST_CLIC_UNIT_ID, x, y, GetRandomDirectionDeg())

		else

			call SetUnitX(.unitLastClic, x)

			call SetUnitY(.unitLastClic, y)

		endif

        call Hero2Escaper(.maker).destroyCancelledActions()

	endmethod

	

	method unsaveLoc takes nothing returns boolean

		if (not .lastLocSavedIsUsed) then

			return false

		endif

		call RemoveUnit(.unitLastClic)

		set .unitLastClic = null

		set .lastLocSavedIsUsed = false

		return true

	endmethod

	

	method isLastLocSavedUsed takes nothing returns boolean

		return .lastLocSavedIsUsed

	endmethod

	

	method cancelLastAction takes nothing returns boolean

		return .unsaveLoc()

	endmethod

	

	method redoLastAction takes nothing returns boolean

        if (not .lastLocSavedIsUsed and .lastLocIsSaved) then

            call .saveLoc(.lastX, .lastY)

            return true

        endif

        return false

	endmethod

    

    method forNext takes nothing returns boolean

        return .forNextB

    endmethod

endstruct

	

	

	

endlibrary//===========================================================================

// Trigger: End making Actions

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library EndMakingActions needs Escaper







function EndMaking_Actions takes nothing returns nothing

    local Escaper escaper = Hero2Escaper(GetTriggerUnit())

    local Make mkGeneral = escaper.getMake()

	local MakeEnd mk = MakeEnd(integer(mkGeneral))

    local real x = GetOrderPointX()

    local real y = GetOrderPointY()

    

    if (not IsIssuedOrder("smart")) then   

        return

    endif

    call StopUnit(mk.maker)

    

	

    if (mk.isLastLocSavedUsed()) then

        call escaper.getMakingLevel().newEnd(mk.lastX, mk.lastY, x, y)

        call Text_mkP(mk.makerOwner, "end made for level " + I2S(escaper.getMakingLevel().getId()))

        call escaper.destroyMake()

    else

        call mk.saveLoc(x, y)

    endif

endfunction







endlibrary//===========================================================================

// Trigger: MakeEnd

//===========================================================================

//TESH.scrollpos=33

//TESH.alwaysfold=0

library MakeEnd needs Make







struct MakeEnd extends Make

    real lastX

    real lastY

    private unit unitLastClic

    private boolean lastLocIsSaved

	private boolean lastLocSavedIsUsed

    

	static method create takes unit maker returns MakeEnd

        local MakeEnd m

		if (maker == null) then

			return 0

		endif

        set m = MakeEnd.allocate()

        set m.maker = maker

		set m.makerOwner = GetOwningPlayer(maker)

        set m.kind = "endCreate"

        set m.t = CreateTrigger()

        call TriggerAddAction(m.t, Make_GetActions(m.kind))

        call TriggerRegisterUnitEvent(m.t, maker, EVENT_UNIT_ISSUED_POINT_ORDER)

        set m.lastLocIsSaved = false

        set m.lastLocSavedIsUsed = false

        return m

    endmethod

    

    method onDestroy takes nothing returns nothing

		call DestroyTrigger(.t)

		set .t = null

		call RemoveUnit(.unitLastClic)

		set .unitLastClic = null

		set .maker = null

	endmethod	

	

	method saveLoc takes real x, real y returns nothing

		set .lastX = x

		set .lastY = y

        set .lastLocIsSaved = true

		set .lastLocSavedIsUsed = true

		if (.unitLastClic == null) then

			set .unitLastClic = CreateUnit(.makerOwner, MAKE_LAST_CLIC_UNIT_ID, x, y, GetRandomDirectionDeg())

		else

			call SetUnitX(.unitLastClic, x)

			call SetUnitY(.unitLastClic, y)

		endif

        call Hero2Escaper(.maker).destroyCancelledActions()

	endmethod

	

	method unsaveLoc takes nothing returns boolean

		if (not .lastLocSavedIsUsed) then

			return false

		endif

		call RemoveUnit(.unitLastClic)

		set .unitLastClic = null

		set .lastLocSavedIsUsed = false

		return true

	endmethod

	

	method isLastLocSavedUsed takes nothing returns boolean

		return .lastLocSavedIsUsed

	endmethod

	

	method cancelLastAction takes nothing returns boolean

		return .unsaveLoc()

	endmethod

	

	method redoLastAction takes nothing returns boolean

        if (not .lastLocSavedIsUsed and .lastLocIsSaved) then

            call .saveLoc(.lastX, .lastY)

            return true

        endif

        return false

	endmethod

endstruct

	

	

	

endlibrary//===========================================================================

// Trigger: VisibilityModifier making Actions

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library VisibilityModifierMakingActions needs Escaper







function VisibilityModifierMaking_Actions takes nothing returns nothing

    local VisibilityModifier newVisibilityModifier

    local Escaper escaper = Hero2Escaper(GetTriggerUnit())

    local Make mkGeneral = escaper.getMake()

	local MakeVisibilityModifier mk = MakeVisibilityModifier(integer(mkGeneral))

    local real x = GetOrderPointX()

    local real y = GetOrderPointY()

    

    if (not IsIssuedOrder("smart")) then   

        return

    endif

    call StopUnit(mk.maker)

    

	

    if (mk.isLastLocSavedUsed()) then

        set newVisibilityModifier = escaper.getMakingLevel().newVisibilityModifier(mk.lastX, mk.lastY, x, y)

        if (newVisibilityModifier == 0) then

            call Text_erP(mk.makerOwner, "can't create visibility, full for this level")

        else

            call newVisibilityModifier.activate(true)

            call escaper.newAction(MakeVisibilityModifierAction.create(escaper.getMakingLevel(), newVisibilityModifier))

            call Text_mkP(mk.makerOwner, "visibility rectangle made for level " + I2S(escaper.getMakingLevel().getId()))

         endif

        call mk.unsaveLocDefinitely()

    else

        call mk.saveLoc(x, y)

    endif

endfunction







endlibrary//===========================================================================

// Trigger: MakeVisibilityModifier

//===========================================================================

//TESH.scrollpos=38

//TESH.alwaysfold=0

library MakeVisibilityModifier needs Make







struct MakeVisibilityModifier extends Make

    real lastX

    real lastY

    private unit unitLastClic

    private boolean lastLocIsSaved

	private boolean lastLocSavedIsUsed

    

	static method create takes unit maker returns MakeVisibilityModifier

        local MakeVisibilityModifier m

		if (maker == null) then

			return 0

		endif

        set m = MakeVisibilityModifier.allocate()

        set m.maker = maker

		set m.makerOwner = GetOwningPlayer(maker)

        set m.kind = "visibilityModifierCreate"

        set m.t = CreateTrigger()

        call TriggerAddAction(m.t, Make_GetActions(m.kind))

        call TriggerRegisterUnitEvent(m.t, maker, EVENT_UNIT_ISSUED_POINT_ORDER)

        set m.lastLocIsSaved = false

        set m.lastLocSavedIsUsed = false

        return m

    endmethod

    

    method onDestroy takes nothing returns nothing

		call DestroyTrigger(.t)

		set .t = null

		call RemoveUnit(.unitLastClic)

		set .unitLastClic = null

		set .maker = null

	endmethod	

	

	method saveLoc takes real x, real y returns nothing

		set .lastX = x

		set .lastY = y

        set .lastLocIsSaved = true

		set .lastLocSavedIsUsed = true

		if (.unitLastClic == null) then

			set .unitLastClic = CreateUnit(.makerOwner, MAKE_LAST_CLIC_UNIT_ID, x, y, GetRandomDirectionDeg())

		else

			call SetUnitX(.unitLastClic, x)

			call SetUnitY(.unitLastClic, y)

		endif

        call Hero2Escaper(.maker).destroyCancelledActions()

	endmethod

	

	method unsaveLoc takes nothing returns boolean

		if (not .lastLocSavedIsUsed) then

			return false

		endif

		call RemoveUnit(.unitLastClic)

		set .unitLastClic = null

		set .lastLocSavedIsUsed = false

		return true

	endmethod

    

    method unsaveLocDefinitely takes nothing returns nothing

        call .unsaveLoc()

        set .lastLocIsSaved = false

    endmethod

	

	method isLastLocSavedUsed takes nothing returns boolean

		return .lastLocSavedIsUsed

	endmethod

	

	method cancelLastAction takes nothing returns boolean

		return .unsaveLoc()

	endmethod

	

	method redoLastAction takes nothing returns boolean

        if (not .lastLocSavedIsUsed and .lastLocIsSaved) then

            call .saveLoc(.lastX, .lastY)

            return true

        endif

        return false

	endmethod

endstruct

	

	

	

endlibrary//===========================================================================

// Trigger: Getting terrain type info Actions

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library GettingTerrainTypeInfoActions needs Escaper







function GettingTerrainTypeInfo_Actions takes nothing returns nothing

    local Escaper escaper = Hero2Escaper(GetTriggerUnit())

    local Make mkGeneral = escaper.getMake()

	local MakeGetTerrainType mk = MakeGetTerrainType(integer(mkGeneral))

    local real x = GetOrderPointX()

    local real y = GetOrderPointY()



    if (not IsIssuedOrder("smart")) then

        return

    endif

    call StopUnit(mk.maker)

	

    call Text_P(mk.makerOwner, GetTerrainData(GetTerrainType(x, y)))

endfunction











endlibrary//===========================================================================

// Trigger: MakeGetTerrainType

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library MakeGetTerrainType needs Make







struct MakeGetTerrainType extends Make

	static method create takes unit maker returns MakeGetTerrainType

        local MakeGetTerrainType m

		if (maker == null) then

			return 0

		endif

        set m = MakeGetTerrainType.allocate()

        set m.maker = maker

        set m.makerOwner = GetOwningPlayer(maker)

        set m.kind = "getTerrainType"

        set m.t = CreateTrigger()

        call TriggerAddAction(m.t, Make_GetActions(m.kind))

        call TriggerRegisterUnitEvent(m.t, m.maker, EVENT_UNIT_ISSUED_POINT_ORDER)

        return m

    endmethod

    

    method onDestroy takes nothing returns nothing

		call DestroyTrigger(.t)

		set .t = null

		set .maker = null

	endmethod		

    

    method cancelLastAction takes nothing returns boolean

        return false

    endmethod

    

    method redoLastAction takes nothing returns boolean

        return false

    endmethod

endstruct







endlibrary//===========================================================================

// Trigger: MakeAction

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library MakeAction





interface MakeAction

    boolean isActionMadeB

    Escaper owner

    method cancel takes nothing returns boolean

    method redo takes nothing returns boolean

endinterface





endlibrary//===========================================================================

// Trigger: MakeMonsterAction

//===========================================================================

//TESH.scrollpos=8

//TESH.alwaysfold=0

library MakeMonsterAction needs MakeAction







struct MakeMonsterAction extends MakeAction

    private Monster monster

    private Level level

    

    method getLevel takes nothing returns Level

        return .level

    endmethod



    static method create takes Level level, Monster monster returns MakeMonsterAction

        local MakeMonsterAction a 

        if (monster == 0 or monster.u == null) then

            return 0

        endif

        set a = MakeMonsterAction.allocate()

        set a.isActionMadeB = true

        set a.monster = monster

        set a.level = level

        return a

    endmethod

    

    method onDestroy takes nothing returns nothing

        if (not .isActionMadeB) then //si le monstre a été supprimé

            call .monster.destroy()

        endif

    endmethod

    

	method cancel takes nothing returns boolean

        if (not .isActionMadeB) then

            return false

        endif

		call .monster.removeUnit()

        set .isActionMadeB = false

        call Text_mkP(.owner.getPlayer(), "monster creation cancelled")

        return true

	endmethod

	

	method redo takes nothing returns boolean

        if (.isActionMadeB) then

            return false

        endif

		call .monster.createUnit()

        set .isActionMadeB = true

        call Text_mkP(.owner.getPlayer(), "monster creation redone")

        return true

	endmethod	

endstruct









endlibrary//===========================================================================

// Trigger: MakeDeleteMonstersAction

//===========================================================================

//TESH.scrollpos=56

//TESH.alwaysfold=0

library MakeDeleteMonstersAction needs MakeAction







struct MakeDeleteMonstersAction extends MakeAction

    static hashtable suppressions

    static integer suppressionLastId

    

    private static method onInit takes nothing returns nothing

        set MakeDeleteMonstersAction.suppressions = InitHashtable()

        set MakeDeleteMonstersAction.suppressionLastId = -1

    endmethod

    

    static method newSuppression takes hashtable suppression returns integer

        local integer i

        local integer suppressionId = MakeDeleteMonstersAction.suppressionLastId + 1

        set MakeDeleteMonstersAction.suppressionLastId = suppressionId

        set i = 0

        loop

            exitwhen (not HaveSavedInteger(suppression, 0, i))

                call SaveInteger(MakeDeleteMonstersAction.suppressions, suppressionId, i, LoadInteger(suppression, 0, i))

            set i = i + 1

        endloop

        return suppressionId

    endmethod

    

    static method removeSuppression takes integer suppressionId returns nothing

        call FlushChildHashtable(MakeDeleteMonstersAction.suppressions, suppressionId)

    endmethod    

    

    

    private integer suppressionId

    private Level level

    

    method getLevel takes nothing returns Level

        return .level

    endmethod



    static method create takes Level level, hashtable suppression returns MakeDeleteMonstersAction

        local MakeDeleteMonstersAction a 

        if (suppression == null) then

            return 0

        endif

        set a = MakeDeleteMonstersAction.allocate()

        set a.isActionMadeB = true

        set a.suppressionId = MakeDeleteMonstersAction.newSuppression(suppression)

        set a.level = level

        return a

    endmethod

    

    method onDestroy takes nothing returns nothing

        local integer i

        if (.isActionMadeB) then

            //suppression définitive des mobs

            set i = 0

            loop

                exitwhen (not HaveSavedInteger(MakeDeleteMonstersAction.suppressions, .suppressionId, i))

                    call Monster(LoadInteger(MakeDeleteMonstersAction.suppressions, .suppressionId, i)).destroy()

                set i = i + 1

            endloop

        endif

        call MakeDeleteMonstersAction.removeSuppression(.suppressionId)

    endmethod

    

	method cancel takes nothing returns boolean

        local integer i

        if (not .isActionMadeB) then

            return false

        endif

		//création des monstres supprimés

        set i = 0

        loop

            exitwhen (not HaveSavedInteger(MakeDeleteMonstersAction.suppressions, .suppressionId, i))

                call Monster(LoadInteger(MakeDeleteMonstersAction.suppressions, .suppressionId, i)).createUnit()

            set i = i + 1

        endloop

        set .isActionMadeB = false

        call Text_mkP(.owner.getPlayer(), "monster deleting cancelled")

        return true

	endmethod

	

	method redo takes nothing returns boolean

        local integer i

        if (.isActionMadeB) then

            return false

        endif

		//suppression des monstres recréés

        set i = 0

        loop

            exitwhen (not HaveSavedInteger(MakeDeleteMonstersAction.suppressions, .suppressionId, i))

                call Monster(LoadInteger(MakeDeleteMonstersAction.suppressions, .suppressionId, i)).removeUnit()

            set i = i + 1

        endloop

        set .isActionMadeB = true

        call Text_mkP(.owner.getPlayer(), "monster deleting redone")

        return true

	endmethod	

endstruct









endlibrary//===========================================================================

// Trigger: MakeMeteorAction

//===========================================================================

//TESH.scrollpos=8

//TESH.alwaysfold=0

library MakeMeteorAction needs MakeAction







struct MakeMeteorAction extends MakeAction

    private Meteor meteor

    private Level level

    

    method getLevel takes nothing returns Level

        return .level

    endmethod



    static method create takes Level level, Meteor meteor returns MakeMeteorAction

        local MakeMeteorAction a 

        if (meteor == 0 or meteor.getItem() == null) then

            return 0

        endif

        set a = MakeMeteorAction.allocate()

        set a.isActionMadeB = true

        set a.meteor = meteor

        set a.level = level

        return a

    endmethod

    

    method onDestroy takes nothing returns nothing

        if (not .isActionMadeB) then //si le monstre a été supprimé

            call .meteor.destroy()

        endif

    endmethod

    

	method cancel takes nothing returns boolean

        if (not .isActionMadeB) then

            return false

        endif

		call .meteor.removeMeteor()

        set .isActionMadeB = false

        call Text_mkP(.owner.getPlayer(), "meteor creation cancelled")

        return true

	endmethod

	

	method redo takes nothing returns boolean

        if (.isActionMadeB) then

            return false

        endif

		call .meteor.createMeteor()

        set .isActionMadeB = true

        call Text_mkP(.owner.getPlayer(), "meteor creation redone")

        return true

	endmethod	

endstruct









endlibrary//===========================================================================

// Trigger: MakeDeleteMeteorsAction

//===========================================================================

//TESH.scrollpos=56

//TESH.alwaysfold=0

library MakeDeleteMeteorsAction needs MakeAction







struct MakeDeleteMeteorsAction extends MakeAction

    static hashtable suppressions

    static integer suppressionLastId

    

    private static method onInit takes nothing returns nothing

        set MakeDeleteMeteorsAction.suppressions = InitHashtable()

        set MakeDeleteMeteorsAction.suppressionLastId = -1

    endmethod

    

    static method newSuppression takes hashtable suppression returns integer

        local integer i

        local integer suppressionId = MakeDeleteMeteorsAction.suppressionLastId + 1

        set MakeDeleteMeteorsAction.suppressionLastId = suppressionId

        set i = 0

        loop

            exitwhen (not HaveSavedInteger(suppression, 0, i))

                call SaveInteger(MakeDeleteMeteorsAction.suppressions, suppressionId, i, LoadInteger(suppression, 0, i))

            set i = i + 1

        endloop

        return suppressionId

    endmethod

    

    static method removeSuppression takes integer suppressionId returns nothing

        call FlushChildHashtable(MakeDeleteMeteorsAction.suppressions, suppressionId)

    endmethod    

    

    

    private integer suppressionId

    private Level level

    

    method getLevel takes nothing returns Level

        return .level

    endmethod



    static method create takes Level level, hashtable suppression returns MakeDeleteMeteorsAction

        local MakeDeleteMeteorsAction a 

        if (suppression == null) then

            return 0

        endif

        set a = MakeDeleteMeteorsAction.allocate()

        set a.isActionMadeB = true

        set a.suppressionId = MakeDeleteMeteorsAction.newSuppression(suppression)

        set a.level = level

        return a

    endmethod

    

    method onDestroy takes nothing returns nothing

        local integer i

        if (.isActionMadeB) then

            //suppression définitive des météores

            set i = 0

            loop

                exitwhen (not HaveSavedInteger(MakeDeleteMeteorsAction.suppressions, .suppressionId, i))

                    call Meteor(LoadInteger(MakeDeleteMeteorsAction.suppressions, .suppressionId, i)).destroy()

                set i = i + 1

            endloop

        endif

        call MakeDeleteMeteorsAction.removeSuppression(.suppressionId)

    endmethod

    

	method cancel takes nothing returns boolean

        local integer i

        if (not .isActionMadeB) then

            return false

        endif

		//création des météores supprimées

        set i = 0

        loop

            exitwhen (not HaveSavedInteger(MakeDeleteMeteorsAction.suppressions, .suppressionId, i))

                call Meteor(LoadInteger(MakeDeleteMeteorsAction.suppressions, .suppressionId, i)).createMeteor()

            set i = i + 1

        endloop

        set .isActionMadeB = false

        call Text_mkP(.owner.getPlayer(), "meteor deleting cancelled")

        return true

	endmethod

	

	method redo takes nothing returns boolean

        local integer i

        if (.isActionMadeB) then

            return false

        endif

		//suppression des météores recréés

        set i = 0

        loop

            exitwhen (not HaveSavedInteger(MakeDeleteMeteorsAction.suppressions, .suppressionId, i))

                call Meteor(LoadInteger(MakeDeleteMeteorsAction.suppressions, .suppressionId, i)).removeMeteor()

            set i = i + 1

        endloop

        set .isActionMadeB = true

        call Text_mkP(.owner.getPlayer(), "meteor deleting redone")

        return true

	endmethod	

endstruct









endlibrary//===========================================================================

// Trigger: MakeTerrainCreateAction

//===========================================================================

//TESH.scrollpos=95

//TESH.alwaysfold=0

library MakeTerrainCreateAction needs MakeAction, ModifyTerrainFunctions





struct MakeTerrainCreateAction extends MakeAction

    static hashtable terrainSaves

    static integer terrainSaveLastId

    

    private static method onInit takes nothing returns nothing

        set MakeTerrainCreateAction.terrainSaves = InitHashtable()

        set MakeTerrainCreateAction.terrainSaveLastId = -1

    endmethod

    

    static method newTerrainSaveId takes nothing returns integer

        set MakeTerrainCreateAction.terrainSaveLastId = MakeTerrainCreateAction.terrainSaveLastId + 1

        return MakeTerrainCreateAction.terrainSaveLastId

    endmethod

    

    static method removeTerrainSave takes integer terrainSaveId returns nothing

        call FlushChildHashtable(MakeTerrainCreateAction.terrainSaves, terrainSaveId)

    endmethod    

    

    

    

    private integer terrainSaveId

    private TerrainType terrainTypeNew

    private real minX

    private real minY

    private real maxX

    private real maxY



    static method create takes TerrainType terrainTypeNew, real x1, real y1, real x2, real y2 returns MakeTerrainCreateAction

        local hashtable terrainSave

        local integer terrainSaveId

        local MakeTerrainCreateAction a

        local real x

        local real y

        local integer i

       

        local real minX = RMinBJ(x1, x2)

        local real maxX = RMaxBJ(x1, x2)

        local real minY = RMinBJ(y1, y2)

        local real maxY = RMaxBJ(y1, y2)

        

        if (terrainTypeNew == 0 or terrainTypeNew.getTerrainTypeId() == 0) then

            return -1

        endif

        if (GetNbCaseBetween(minX, minY, maxX, maxY) > NB_MAX_TILES_MODIFIED) then

            return 0

        endif

        set a = MakeTerrainCreateAction.allocate()

        set terrainSave = MakeTerrainCreateAction.terrainSaves

        set a.terrainSaveId = MakeTerrainCreateAction.newTerrainSaveId()

        

        set i = 0

        set x = minX

        set y = minY

        loop

            exitwhen (y > maxY)

                loop

                    exitwhen (x > maxX)

                        call SaveInteger(terrainSave, a.terrainSaveId, i, integer(udg_terrainTypes.getTerrainType(x, y)))

                        set i = i + 1

                    set x = x + LARGEUR_CASE

                endloop

                set x = minX

            set y = y + LARGEUR_CASE

        endloop 

        set terrainSave = null

        

        call ChangeTerrainBetween(terrainTypeNew.getTerrainTypeId(), minX, minY, maxX, maxY)

        set a.terrainTypeNew = terrainTypeNew

        set a.minX = minX

        set a.maxX = maxX

        set a.minY = minY

        set a.maxY = maxY

        set a.isActionMadeB = true

        return a

    endmethod

    

    private method onDestroy takes nothing returns nothing

        call MakeTerrainCreateAction.removeTerrainSave(.terrainSaveId)

    endmethod

    

    method terrainModificationCancel takes nothing returns nothing 

        local TerrainType terrainType

        local real x

        local real y

        local integer i

       

        set i = 0

        set x = .minX

        set y = .minY

        loop

            exitwhen (y > .maxY)

                loop

                    exitwhen (x > .maxX)

                        set terrainType = TerrainType(LoadInteger(MakeTerrainCreateAction.terrainSaves, .terrainSaveId, i))

                        if (terrainType != 0 and terrainType.getTerrainTypeId() != 0) then

                            call ChangeTerrainType(x, y, terrainType.getTerrainTypeId())

                        endif

                        set i = i + 1

                    set x = x + LARGEUR_CASE

                endloop

                set x = .minX

            set y = y + LARGEUR_CASE

        endloop

    endmethod

    

    method terrainModificationRedo takes nothing returns nothing 

        local integer terrainTypeId = .terrainTypeNew.getTerrainTypeId()

        if (terrainTypeId == 0) then

            call Text_erP(.owner.getPlayer(), "the terrain type for this action doesn't exist anymore")

        else

            call ChangeTerrainBetween(terrainTypeId, .minX, .minY, .maxX, .maxY)

        endif

    endmethod

    

	method cancel takes nothing returns boolean

        if (not .isActionMadeB) then

            return false

        endif

        call .terrainModificationCancel()

        set .isActionMadeB = false

        call Text_mkP(.owner.getPlayer(), "terrain creation cancelled")

        return true

	endmethod

	

	method redo takes nothing returns boolean

        if (.isActionMadeB) then

            return false

        endif

        call .terrainModificationRedo()

        set .isActionMadeB = true

        call Text_mkP(.owner.getPlayer(), "terrain creation redone")

        return true

	endmethod		

endstruct









endlibrary//===========================================================================

// Trigger: MakeTerrainCopyPasteAction

//===========================================================================

//TESH.scrollpos=141

//TESH.alwaysfold=0

library MakeTerrainCopyPasteAction needs MakeAction, ModifyTerrainFunctions





struct MakeTerrainCopyPasteAction extends MakeAction

    static hashtable terrainSavesBefore

    static hashtable terrainSavesAfter

    static integer terrainSaveLastId

    

    private static method onInit takes nothing returns nothing

        set MakeTerrainCopyPasteAction.terrainSavesBefore = InitHashtable()

        set MakeTerrainCopyPasteAction.terrainSavesAfter = InitHashtable()

        set MakeTerrainCopyPasteAction.terrainSaveLastId = -1

    endmethod

    

    static method newTerrainSaveId takes nothing returns integer

        set MakeTerrainCopyPasteAction.terrainSaveLastId = MakeTerrainCopyPasteAction.terrainSaveLastId + 1

        return MakeTerrainCopyPasteAction.terrainSaveLastId

    endmethod

    

    static method removeTerrainSave takes integer terrainSaveId returns nothing

        call FlushChildHashtable(MakeTerrainCopyPasteAction.terrainSavesBefore, terrainSaveId)

        call FlushChildHashtable(MakeTerrainCopyPasteAction.terrainSavesAfter, terrainSaveId)

    endmethod    

    

    

    private integer terrainSaveId

    private real minX

    private real minY

    private real maxX

    private real maxY



    static method create takes real x1, real y1, real x2, real y2, real x3, real y3, real x4, real y4 returns MakeTerrainCopyPasteAction

        local MakeTerrainCopyPasteAction a

        local real xCopy

        local real yCopy

        local real xPaste

        local real yPaste

        local integer i

        local TerrainType terrainType

        local integer terrainTypeId

       

        local real minXcopy = RMinBJ(x1, x2)

        local real maxXcopy = RMaxBJ(x1, x2)

        local real minYcopy = RMinBJ(y1, y2)

        local real maxYcopy = RMaxBJ(y1, y2)

        

        local real diffX = maxXcopy - minXcopy

        local real diffY = maxYcopy - minYcopy

        

        local real minXpaste

        local real minYpaste

        if (x4 > x3) then 

            //direction droite

            set minXpaste = x3

        else    

            //direction gauche

            set minXpaste = x3 - diffX

        endif

        if (y4 > y3) then 

            //direction haut

            set minYpaste = y3

        else    

            //direction bas

            set minYpaste = y3 - diffY

        endif

        

        if (minXpaste < MAP_MIN_X or minXpaste + diffX > MAP_MAX_X or minYpaste < MAP_MIN_Y or minYpaste + diffY > MAP_MAX_Y) then

            return 0

        endif

        

        set a = MakeTerrainCopyPasteAction.allocate()

        set a.terrainSaveId = MakeTerrainCopyPasteAction.newTerrainSaveId()

        set a.minX = minXpaste

        set a.minY = minYpaste

        set a.maxX = minXpaste + diffX

        set a.maxY = minYpaste + diffY

        

        set i = 0

        set xPaste = minXpaste

        set yPaste = minYpaste

        set xCopy = minXcopy

        set yCopy = minYcopy

        loop

            exitwhen (yCopy > maxYcopy)

                loop

                    exitwhen (xCopy > maxXcopy)

                        call SaveInteger(MakeTerrainCopyPasteAction.terrainSavesBefore, a.terrainSaveId, i, integer(udg_terrainTypes.getTerrainType(xPaste, yPaste)))

                        set terrainType = udg_terrainTypes.getTerrainType(xCopy, yCopy)

                        call SaveInteger(MakeTerrainCopyPasteAction.terrainSavesAfter, a.terrainSaveId, i, integer(udg_terrainTypes.getTerrainType(xCopy, yCopy)))

                        if (terrainType != 0) then

                            set terrainTypeId = terrainType.getTerrainTypeId()

                            if (terrainTypeId != 0) then

                                call ChangeTerrainType(xPaste, yPaste, terrainTypeId)

                            endif

                        endif                        

                        set i = i + 1

                        set xPaste = xPaste + LARGEUR_CASE

                    set xCopy = xCopy + LARGEUR_CASE

                endloop

                set xPaste = minXpaste

                set xCopy = minXcopy

                set yPaste = yPaste + LARGEUR_CASE

            set yCopy = yCopy + LARGEUR_CASE

        endloop

        

        set a.isActionMadeB = true

        return a

    endmethod

    

    private method onDestroy takes nothing returns nothing

        call MakeTerrainCopyPasteAction.removeTerrainSave(.terrainSaveId)

    endmethod

    

    method terrainModificationCancel takes nothing returns nothing 

        local TerrainType terrainType

        local real x

        local real y

        local integer i

       

        set i = 0

        set x = .minX

        set y = .minY

        loop

            exitwhen (y > .maxY)

                loop

                    exitwhen (x > .maxX)

                        set terrainType = TerrainType(LoadInteger(MakeTerrainCopyPasteAction.terrainSavesBefore, .terrainSaveId, i))

                        if (terrainType != 0 and terrainType.getTerrainTypeId() != 0) then

                            call ChangeTerrainType(x, y, terrainType.getTerrainTypeId())

                        endif

                        set i = i + 1

                    set x = x + LARGEUR_CASE

                endloop

                set x = .minX

            set y = y + LARGEUR_CASE

        endloop

    endmethod

    

    method terrainModificationRedo takes nothing returns nothing

        local TerrainType terrainType

        local real x

        local real y

        local integer i

       

        set i = 0

        set x = .minX

        set y = .minY

        loop

            exitwhen (y > .maxY)

                loop

                    exitwhen (x > .maxX)

                        set terrainType = TerrainType(LoadInteger(MakeTerrainCopyPasteAction.terrainSavesAfter, .terrainSaveId, i))

                        if (terrainType != 0 and terrainType.getTerrainTypeId() != 0) then

                            call ChangeTerrainType(x, y, terrainType.getTerrainTypeId())

                        endif

                        set i = i + 1

                    set x = x + LARGEUR_CASE

                endloop

                set x = .minX

            set y = y + LARGEUR_CASE

        endloop

    endmethod

    

	method cancel takes nothing returns boolean

        if (not .isActionMadeB) then

            return false

        endif

        call .terrainModificationCancel()

        set .isActionMadeB = false

        call Text_mkP(.owner.getPlayer(), "terrain copy/paste cancelled")

        return true

	endmethod

	

	method redo takes nothing returns boolean

        if (.isActionMadeB) then

            return false

        endif

        call .terrainModificationRedo()

        set .isActionMadeB = true

        call Text_mkP(.owner.getPlayer(), "terrain copy/paste redone")

        return true

	endmethod		

endstruct









endlibrary//===========================================================================

// Trigger: MakeTerrainVerticalSymmetryAction

//===========================================================================

//TESH.scrollpos=53

//TESH.alwaysfold=0

library MakeTerrainVerticalSymmetryAction needs MakeAction, ModifyTerrainFunctions





struct MakeTerrainVerticalSymmetryAction extends MakeAction   

    private real minX

    private real minY

    private real maxX

    private real maxY



    static method create takes real x1, real y1, real x2, real y2 returns MakeTerrainVerticalSymmetryAction

        local MakeTerrainVerticalSymmetryAction a

       

        local real minX = RMinBJ(x1, x2)

        local real maxX = RMaxBJ(x1, x2)

        local real minY = RMinBJ(y1, y2)

        local real maxY = RMaxBJ(y1, y2)

        

        //pour éviter les ptits décalages

        set minX = I2R(R2I(minX / LARGEUR_CASE)) * LARGEUR_CASE

        set minY = I2R(R2I(minY / LARGEUR_CASE)) * LARGEUR_CASE

        set maxX = I2R(R2I(maxX / LARGEUR_CASE)) * LARGEUR_CASE

        set maxY = I2R(R2I(maxY / LARGEUR_CASE)) * LARGEUR_CASE

        

        if (GetNbCaseBetween(minX, minY, maxX, maxY) > NB_MAX_TILES_MODIFIED) then

            return 0

        endif

        set a = MakeTerrainVerticalSymmetryAction.allocate()

        set a.minX = minX

        set a.minY = minY

        set a.maxX = maxX

        set a.maxY = maxY

        call a.applySymmetry()        

        set a.isActionMadeB = true

        return a

    endmethod

    

    method applySymmetry takes nothing returns nothing

        local integer i

        local real x

        local real y

        local integer array terrainTypeIds

        

        //sauvegarde du terrain

        set i = 0

        set x = .minX

        set y = .minY

        loop

            exitwhen (y > .maxY)

                loop

                    exitwhen (x > .maxX)

                        set terrainTypeIds[i] = GetTerrainType(x, y)

                        set i = i + 1

                    set x = x + LARGEUR_CASE

                endloop

                set x = .minX

            set y = y + LARGEUR_CASE

        endloop

        

        //application de la symétrie

        set i = 0

        set x = .minX

        set y = .maxY

        loop

            exitwhen (y < .minY)

                loop

                    exitwhen (x > .maxX)

                        call ChangeTerrainType(x, y, terrainTypeIds[i])

                        set i = i + 1

                    set x = x + LARGEUR_CASE

                endloop

                set x = .minX

            set y = y - LARGEUR_CASE

        endloop  

    endmethod

    

	method cancel takes nothing returns boolean

        if (not .isActionMadeB) then

            return false

        endif

        call .applySymmetry()

        set .isActionMadeB = false

        call Text_mkP(.owner.getPlayer(), "terrain vertical symmetry cancelled")

        return true

	endmethod

	

	method redo takes nothing returns boolean

        if (.isActionMadeB) then

            return false

        endif

        call .applySymmetry()

        set .isActionMadeB = true

        call Text_mkP(.owner.getPlayer(), "terrain vertical symmetry redone")

        return true

	endmethod		

endstruct









endlibrary//===========================================================================

// Trigger: MakeTerrainHorizontalSymmetryAction

//===========================================================================

//TESH.scrollpos=53

//TESH.alwaysfold=0

library MakeTerrainHorizontalSymmetryAction needs MakeAction, ModifyTerrainFunctions





struct MakeTerrainHorizontalSymmetryAction extends MakeAction   

    private real minX

    private real minY

    private real maxX

    private real maxY



    static method create takes real x1, real y1, real x2, real y2 returns MakeTerrainHorizontalSymmetryAction

        local MakeTerrainHorizontalSymmetryAction a

       

        local real minX = RMinBJ(x1, x2)

        local real maxX = RMaxBJ(x1, x2)

        local real minY = RMinBJ(y1, y2)

        local real maxY = RMaxBJ(y1, y2)

        

        //pour éviter les ptits décalages

        set minX = I2R(R2I(minX / LARGEUR_CASE)) * LARGEUR_CASE

        set minY = I2R(R2I(minY / LARGEUR_CASE)) * LARGEUR_CASE

        set maxX = I2R(R2I(maxX / LARGEUR_CASE)) * LARGEUR_CASE

        set maxY = I2R(R2I(maxY / LARGEUR_CASE)) * LARGEUR_CASE

        

        if (GetNbCaseBetween(minX, minY, maxX, maxY) > NB_MAX_TILES_MODIFIED) then

            return 0

        endif

        set a = MakeTerrainHorizontalSymmetryAction.allocate()

        set a.minX = minX

        set a.minY = minY

        set a.maxX = maxX

        set a.maxY = maxY

        call a.applySymmetry()        

        set a.isActionMadeB = true

        return a

    endmethod

    

    method applySymmetry takes nothing returns nothing

        local integer i

        local real x

        local real y

        local integer array terrainTypeIds

        

        //sauvegarde du terrain

        set i = 0

        set x = .minX

        set y = .minY

        loop

            exitwhen (y > .maxY)

                loop

                    exitwhen (x > .maxX)

                        set terrainTypeIds[i] = GetTerrainType(x, y)

                        set i = i + 1

                    set x = x + LARGEUR_CASE

                endloop

                set x = .minX

            set y = y + LARGEUR_CASE

        endloop

        

        //application de la symétrie

        set i = 0

        set x = .maxX

        set y = .minY

        loop

            exitwhen (y > .maxY)

                loop

                    exitwhen (x < .minX)

                        call ChangeTerrainType(x, y, terrainTypeIds[i])

                        set i = i + 1

                    set x = x - LARGEUR_CASE

                endloop

                set x = .maxX

            set y = y + LARGEUR_CASE

        endloop  

    endmethod

    

	method cancel takes nothing returns boolean

        if (not .isActionMadeB) then

            return false

        endif

        call .applySymmetry()

        set .isActionMadeB = false

        call Text_mkP(.owner.getPlayer(), "terrain vertical symmetry cancelled")

        return true

	endmethod

	

	method redo takes nothing returns boolean

        if (.isActionMadeB) then

            return false

        endif

        call .applySymmetry()

        set .isActionMadeB = true

        call Text_mkP(.owner.getPlayer(), "terrain vertical symmetry redone")

        return true

	endmethod		

endstruct









endlibrary//===========================================================================

// Trigger: MakeVisibilityModifierAction

//===========================================================================

//TESH.scrollpos=17

//TESH.alwaysfold=0

library MakeVisibilityModifierAction needs MakeAction







struct MakeVisibilityModifierAction extends MakeAction

    private Level level

    private VisibilityModifier visibilityModifierSave

    private VisibilityModifier visibilityModifierPointeur //pointe vers le vm effectif

    

    method getLevel takes nothing returns Level

        return .level

    endmethod



    static method create takes Level level, VisibilityModifier visibilityModifier returns MakeVisibilityModifierAction

        local MakeVisibilityModifierAction a 

        if (visibilityModifier == 0) then

            return 0

        endif

        set a = MakeVisibilityModifierAction.allocate()

        set a.isActionMadeB = true

        set a.level = level

        set a.visibilityModifierSave = 0

        set a.visibilityModifierPointeur = visibilityModifier

        return a

    endmethod

    

    method onDestroy takes nothing returns nothing

        if (.visibilityModifierSave != 0) then

            call .visibilityModifierSave.destroy()

        endif

    endmethod

    

	method cancel takes nothing returns boolean

        if (not .isActionMadeB) then

            return false

        endif

		set .visibilityModifierSave = .visibilityModifierPointeur.copy()

        call .visibilityModifierPointeur.destroy()

        set .isActionMadeB = false

        call Text_mkP(.owner.getPlayer(), "visibility creation cancelled")

        return true

	endmethod

	

	method redo takes nothing returns boolean

        if (.isActionMadeB) then

            return false

        endif

        set .visibilityModifierPointeur = .level.newVisibilityModifierFromExisting(.visibilityModifierSave)

		if (.visibilityModifierPointeur == 0) then

            call Text_erP(.owner.getPlayer(), "can't recreate visibility, full for this level")

        else

            call .visibilityModifierPointeur.activate(true)

        endif

        set .visibilityModifierSave = 0

        set .isActionMadeB = true

        call Text_mkP(.owner.getPlayer(), "visibility creation redone")

        return true

	endmethod	

endstruct









endlibrary//===========================================================================

// Trigger: MakeLastActions

//===========================================================================

//TESH.scrollpos=123

//TESH.alwaysfold=0

library MakeLastActions needs Text





globals

    private constant integer NB_MAX_ACTIONS_SAVED = 30

endglobals







struct MakeLastActions

    private MakeAction array lastActions [NB_MAX_ACTIONS_SAVED]

    private integer lastActionId

    private integer lastActionEffective //anciennement appelé "pointeur"

    private Escaper owner

    

    static method create takes Escaper owner returns MakeLastActions

        local MakeLastActions la = MakeLastActions.allocate()

        set la.lastActionId = -1

        set la.lastActionEffective = -1

        set la.owner = owner

        return la

    endmethod   

    

    private method onDestroy takes nothing returns nothing

        local integer i = 0

        loop

            exitwhen (i > .lastActionId)

                call .lastActions[i].destroy()

            set i = i + 1

        endloop

    endmethod

    

    method newAction takes MakeAction action returns MakeAction

        local integer i

        if (.lastActionEffective < .lastActionId) then

            //suppression des actions annulées (à l'ajout d'une nouvelle action)

            set i = .lastActionEffective + 1

            loop

                exitwhen (i > .lastActionId)

                    call .lastActions[i].destroy()

                set i = i + 1

            endloop

        endif

        if (.lastActionEffective == NB_MAX_ACTIONS_SAVED - 1) then

            //suppression de la plus ancienne des actions et décalage de tout le tableau

            call .lastActions[0].destroy()

            set i = 0

            loop

                exitwhen (i == NB_MAX_ACTIONS_SAVED - 1)

                    set .lastActions[i] = .lastActions[i + 1]

                set i = i + 1

            endloop

        else

            set .lastActionEffective = .lastActionEffective + 1

        endif

        //sauvegarde de l'action

        set .lastActions[.lastActionEffective] = action

        set .lastActionId = .lastActionEffective

        //assignation du "owner" de l'action

        set action.owner = .owner

        return action

    endmethod

    

    method cancelLastAction takes nothing returns boolean

        if (.lastActionEffective < 0) then

            return false

        endif

        if (.lastActions[.lastActionEffective] == 0) then //action obsolète

            call Text_erP(.owner.getPlayer(), "action obsolète")

        else

            //annulation de l'action

            if (not .lastActions[.lastActionEffective].cancel()) then

                call Text_erA("error : action already cancelled for player " + I2S(GetPlayerId(.owner.getPlayer())))

            endif

        endif

        set .lastActionEffective = .lastActionEffective - 1

        return true

    endmethod

    

    method redoLastAction takes nothing returns boolean

        if (.lastActionEffective == .lastActionId) then

            return false

        endif

        set .lastActionEffective = .lastActionEffective + 1

        if (.lastActions[.lastActionEffective] == 0) then //action obsolète

            call Text_erP(.owner.getPlayer(), "action obsolète")

        else

            //réexécution de l'action

            if (not .lastActions[.lastActionEffective].redo()) then

                call Text_erA("error : action already redone for player " + I2S(GetPlayerId(.owner.getPlayer())))

            endif

        endif

        return true

    endmethod

    

    method deleteSpecificActionsForLevel takes Level level returns nothing

        //actions spécifiques à un niveau :

            //MakeMonsterAction

            //MakeDeleteMonstersAction

            //MakeVisibilityModifierAction

            //MakeMeteor

            //MakeDeleteMeteors

        //////

        local integer i = 0

        loop

            exitwhen (i > .lastActionId)

                if (.lastActions[i].getType() == MakeMonsterAction.typeid) then

                    if (MakeMonsterAction(integer(.lastActions[i])).getLevel() == level) then

                        call .lastActions[i].destroy()

                        set .lastActions[i] = 0

                    endif

                else

                    if (.lastActions[i].getType() == MakeDeleteMonstersAction.typeid) then

                        if (MakeDeleteMonstersAction(integer(.lastActions[i])).getLevel() == level) then

                            call .lastActions[i].destroy()

                            set .lastActions[i] = 0

                        endif

                    else

                        if (.lastActions[i].getType() == MakeVisibilityModifierAction.typeid) then

                            if (MakeVisibilityModifierAction(integer(.lastActions[i])).getLevel() == level) then

                                call .lastActions[i].destroy()

                                set .lastActions[i] = 0

                            endif

                        else

                            if (.lastActions[i].getType() == MakeMeteorAction.typeid) then

                                if (MakeMeteorAction(integer(.lastActions[i])).getLevel() == level) then

                                    call .lastActions[i].destroy()

                                    set .lastActions[i] = 0

                                endif

                            else

                                if (.lastActions[i].getType() == MakeDeleteMeteorsAction.typeid) then

                                    if (MakeDeleteMeteorsAction(integer(.lastActions[i])).getLevel() == level) then

                                        call .lastActions[i].destroy()

                                        set .lastActions[i] = 0

                                    endif

                                endif

                            endif

                        endif

                    endif

                endif

            set i = i + 1

        endloop

    endmethod

    

    method destroyCancelledActions takes nothing returns nothing

        if (.lastActionEffective == .lastActionId) then

            return

        endif

        loop

            exitwhen (.lastActionId <= .lastActionEffective)

                call .lastActions[.lastActionId].destroy()

            set .lastActionId = .lastActionId - 1

        endloop

    endmethod

    

    method destroyAllActions takes nothing returns nothing

        local integer i = 0

        loop

            exitwhen (i > .lastActionId)

                call .lastActions[i].destroy()

            set i = i + 1

        endloop

        set .lastActionId = -1

        set .lastActionEffective = -1

    endmethod

endstruct







endlibrary//===========================================================================

// Trigger: Command functions

//===========================================================================

//TESH.scrollpos=103

//TESH.alwaysfold=0

library CommandsFunctions needs Escaper, MonstersClickableSetLife, MonsterNoMoveArray, MonsterSimplePatrolArray, MonsterMultiplePatrolsArray









//gives the name of the entered command  ////the name of the entered command is <command_name>

function CmdName takes string str returns string

  local integer length = StringLength(str)

  local string outputStr = "" 

  local string car

  local integer i = 0



  if (SubString(str, 0, 1) == "-" and length > 1) then

    set car = SubString(str, 1, 2)

    set i = 1   

    loop

      exitwhen (i >= length or car == " ")

      set outputStr = outputStr + car

      set i = i + 1

      set car = SubString(str, i, i + 1)

    endloop

  endif

  if (StringLength(outputStr) >= 1) then

    return outputStr

  endif

  return null

endfunction 



function IsCmd takes string str returns boolean

    return CmdName(str) != null 

endfunction





//gives the parameter number 'paramNumber' of the entered command : <paramX>

function CmdParam takes string str, integer paramNumber returns string

  local integer length = StringLength(str)

  local integer nameLength = StringLength(CmdName(str))

  local string outputStr = null

  local string char

  local integer i = 0

  local integer currentParamNumber = 1

  local integer lastSpaceFound_pos = nameLength + 2   

  

  if (not IsCmd(str)) then 

     return null

  endif     

  

  set i = lastSpaceFound_pos + 1

  

  if (paramNumber == 0) then

    return SubStringBJ(str, i, length)

  endif

     

  loop

  exitwhen (currentParamNumber == paramNumber or i > length)

	set char = SubStringBJ(str, i, i) 

	if ((char == " ") and (i - 1 == lastSpaceFound_pos)) then

	    return null

    endif

	if (char == " ") then

	  set lastSpaceFound_pos = i

	  set currentParamNumber = currentParamNumber + 1

	endif

	set i = i + 1

  endloop	

  

  if (currentParamNumber == paramNumber) then

    loop

    exitwhen (i > length)

      set char = SubStringBJ(str, i, i)

      exitwhen (char == " ")

      set outputStr = outputStr + char

      set i = i + 1

    endloop

    return outputStr

  endif

  return null

endfunction





function NbParam takes string str returns integer

    local integer i = 1

    loop

        exitwhen (CmdParam(str, i) == null)

        set i = i + 1

    endloop

    return i-1

endfunction





function NoParam takes string str returns boolean

    return CmdParam(str, 0) == null

endfunction





function ColorString2Id takes string colorString returns integer

    if (colorString == "red" or colorString == "rd") then

        return 0

    endif

    if (colorString == "blue" or colorString == "be") then

        return 1

    endif

    if (colorString == "teal" or colorString == "tl") then

        return 2

    endif

    if (colorString == "purple" or colorString == "pe") then

        return 3

    endif

    if (colorString == "yellow" or colorString == "yw") then

        return 4

    endif

    if (colorString == "orange" or colorString == "oe") then

        return 5

    endif

    if (colorString == "green" or colorString == "gn") then

        return 6

    endif

    if (colorString == "pink" or colorString == "pk") then

        return 7

    endif

    if (colorString == "grey" or colorString == "gray" or colorString == "gy") then

        return 8

    endif

    if (colorString == "lightblue" or colorString == "lb") then

        return 9

    endif

    if (colorString == "darkgreen" or colorString == "dg") then

        return 10

    endif

    if (colorString == "brown" or colorString == "bn") then

        return 11

    endif

    if (colorString == "black" or colorString == "bk") then

        return 12

    endif

    return 13

endfunction



function IsColorString takes string colorString returns boolean

    return (ColorString2Id(colorString) <= 12)

endfunction



function IsPlayerColorString takes string colorString returns boolean

    return (ColorString2Id(colorString) <= 11)

endfunction









endlibrary//===========================================================================

// Trigger: Teleport once only

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library TeleportOnceOnly needs BasicFunctions





globals

    private trigger array teleTriggers

endglobals





function TeleportOnceOnly_Actions takes nothing returns nothing

    local unit hero = GetTriggerUnit()

    

    if (not IsIssuedOrder("smart")) then

        return

    endif

    call StopUnit(hero)

    

    call SetUnitX(hero, GetOrderPointX())

    call SetUnitY(hero, GetOrderPointY())

    call DestroyTrigger(GetTriggeringTrigger())

    set hero = null

endfunction







function ActivateTeleportOnceOnly takes unit hero returns nothing

    local integer playerId = GetUnitUserData(hero)

    call DestroyTrigger(teleTriggers[playerId])

    set teleTriggers[playerId] = CreateTrigger()

    call TriggerAddAction(teleTriggers[playerId], function TeleportOnceOnly_Actions)

    call TriggerRegisterUnitEvent(teleTriggers[playerId], hero, EVENT_UNIT_ISSUED_POINT_ORDER )

endfunction









endlibrary//===========================================================================

// Trigger: Teleport

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

function Trig_teleport_Conditions takes nothing returns boolean

    return (IsHero(GetTriggerUnit()) and Hero2Escaper(GetTriggerUnit()).canTeleport())

endfunction



function Trig_teleport_Actions takes nothing returns nothing

    call StopUnit(GetTriggerUnit())

    call SetUnitX(GetTriggerUnit(), GetOrderPointX())

    call SetUnitY(GetTriggerUnit(), GetOrderPointY())

endfunction



//===========================================================================

function InitTrig_Teleport takes nothing returns nothing

    set gg_trg_Teleport = CreateTrigger()

    call DisableTrigger(gg_trg_Teleport)

    call TriggerRegisterAnyUnitEventBJ( gg_trg_Teleport, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER)

    call TriggerAddCondition(gg_trg_Teleport, Condition(function Trig_teleport_Conditions))

    call TriggerAddAction(gg_trg_Teleport, function Trig_teleport_Actions)

endfunction



//===========================================================================

// Trigger: Autorevive

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

globals

    real udg_autoreviveDelay = 4

endglobals







function Trig_autorevive_Conditions takes nothing returns boolean

    return IsHero(GetTriggerUnit())

endfunction



function Trig_autorevive_Actions takes nothing returns nothing

    local Escaper escaper = Hero2Escaper(GetTriggerUnit())

    if (escaper.hasAutorevive()) then

        call TriggerSleepAction(udg_autoreviveDelay)

        call escaper.reviveAtStart()

        call escaper.selectHero()

    endif

endfunction





//===========================================================================

function InitTrig_Autorevive takes nothing returns nothing

    set gg_trg_Autorevive = CreateTrigger()

    call TriggerRegisterAnyUnitEventBJ(gg_trg_Autorevive, EVENT_PLAYER_UNIT_DEATH)

    call TriggerAddCondition(gg_trg_Autorevive, Condition( function Trig_autorevive_Conditions))

    call TriggerAddAction(gg_trg_Autorevive, function Trig_autorevive_Actions)

endfunction



//===========================================================================

// Trigger: Command all

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library CommandAll needs CommandsFunctions, CommandShortcuts, Disco







function ExecuteCommandAll takes Escaper escaper, string cmd returns boolean

	local string name = CmdName(cmd)

	local boolean noParam = NoParam(cmd) 

	local integer nbParam = NbParam(cmd)

	

	local integer n

	local integer i

	local integer j

	local integer k



	local boolean b



	local string str = ""

	local string str2 = ""



	local real x

	local real y

	local location point

 

	local string param



	local string param1 = CmdParam(cmd, 1)

	local string param2 = CmdParam(cmd, 2)

	local string param3 = CmdParam(cmd, 3)

	local string param4 = CmdParam(cmd, 4)

    

    

    

    

//-<color>   --> change the base color of the hero

	if (IsColorString(name)) then

		if (noParam) then

			call escaper.setBaseColor(ColorString2Id(name))

			return true

		endif

		if (nbParam == 1 and escaper.isTrueMaximaxou() and IsPlayerColorString(param1)) then

            call udg_escapers.get(ColorString2Id(param1)).setBaseColor(ColorString2Id(name))

		endif

		return true

	endif





//-vertexColor(vc) [ <red> <green> <blue> [<transparency>] ]   --> without parameter takes a random vertex color without changing transparency

	if (name == "vertexColor" or name == "vc") then

		if (noParam or nbParam == 1) then

			if (nbParam == 1) then

				if (not(IsPlayerColorString(param1) and escaper.isTrueMaximaxou())) then

					return true

				endif

				set escaper = udg_escapers.get(ColorString2Id(param1))

			endif

			call escaper.setVcRed(GetRandomPercentageBJ())

			call escaper.setVcGreen(GetRandomPercentageBJ())

			call escaper.setVcBlue(GetRandomPercentageBJ())

		else

			if (not(nbParam == 3 or nbParam == 4)) then

				return true

			endif

			if (not escaper.setVcRed(I2R(PercentageStringOrX2Integer(param1)))) then

                call Text_P(escaper.getPlayer(), udg_colorCode[RED] + "Red : not a correct percentage (" + param1 + ")")

            endif

			if (not escaper.setVcGreen(I2R(PercentageStringOrX2Integer(param2)))) then

                call Text_P(escaper.getPlayer(), udg_colorCode[GREEN] + "Green : not a correct percentage (" + param2 + ")")

            endif

			if (not escaper.setVcBlue(I2R(PercentageStringOrX2Integer(param3)))) then

                call Text_P(escaper.getPlayer(), udg_colorCode[BLUE] + "Blue : not a correct percentage (" + param3 + ")")

            endif

			if (nbParam == 4) then

                if (not escaper.setVcTransparency(I2R(PercentageStringOrX2Integer(param4)))) then

                    call Text_P(escaper.getPlayer(), udg_colorCode[GREY] + "Transparency : not a correct percentage (" + param4 + ")")

                endif

			endif

		endif

		

		call escaper.refreshVertexColor()

		return true

	endif

    

   

//-vertexColorRed(vcr) [<red>]   --> changes the red part of the vertex color only

    if (name == "vertexColorRed" or name == "vcr") then

        if (noParam) then

            call escaper.setVcRed(GetRandomPercentageBJ())

            call escaper.refreshVertexColor()

            return true

        endif

        if (not(nbParam == 1)) then

            return true

        endif

        if (not escaper.setVcRed(I2R(PercentageStringOrX2Integer(param1)))) then

            call Text_P(escaper.getPlayer(), udg_colorCode[RED] + "Red : not a correct percentage (" + param1 + ")")

            return true

        endif

        call escaper.refreshVertexColor()

        return true

    endif

    

    

//-vertexColorGreen(vcg) [<Green>]   --> changes the green part of the vertex color only

    if (name == "vertexColorGreen" or name == "vcg") then

        if (noParam) then

            call escaper.setVcGreen(GetRandomPercentageBJ())

            call escaper.refreshVertexColor()

            return true

        endif

        if (not(nbParam == 1)) then

            return true

        endif

        if (not escaper.setVcGreen(I2R(PercentageStringOrX2Integer(param1)))) then

            call Text_P(escaper.getPlayer(), udg_colorCode[GREEN] + "Green : not a correct percentage (" + param1 + ")")

            return true

        endif

        call escaper.refreshVertexColor()

        return true

    endif

    

    

//-vertexColorBlue(vcb) [<Blue>]   --> changes the blue part of the vertex color only

    if (name == "vertexColorBlue" or name == "vcb") then

        if (noParam) then

            call escaper.setVcBlue(GetRandomPercentageBJ())

            call escaper.refreshVertexColor()

            return true

        endif

        if (not(nbParam == 1)) then

            return true

        endif

        if (not escaper.setVcBlue(I2R(PercentageStringOrX2Integer(param1)))) then

            call Text_P(escaper.getPlayer(), udg_colorCode[BLUE] + "Blue : not a correct percentage (" + param1 + ")")

            return true

        endif

        call escaper.refreshVertexColor()

        return true

    endif

    

    

//-vertexColorTransparency(vct) [<transparency>]   --> changes the transparency of the hero

    if (name == "vertexColorTransparency" or name == "vct") then

        if (noParam) then

            call escaper.setVcTransparency(GetRandomPercentageBJ())

            call escaper.refreshVertexColor()

            return true

        endif

        if (not(nbParam == 1)) then

            return true

        endif

        if (not escaper.setVcTransparency(I2R(PercentageStringOrX2Integer(param1)))) then

            call Text_P(escaper.getPlayer(), udg_colorCode[GREY] + "Transparency : not a correct percentage (" + param1 + ")")

            return true

        endif

        call escaper.refreshVertexColor()

        return true

    endif





//-noVertex(nv)   --> put normal vertex color : RGB(100, 100, 100) with 0 transparency

	if (name == "noVertex" or name == "nv") then

		if (not(noParam or nbParam == 1)) then

			return true

		endif

		if (nbParam == 1) then

			if (not(escaper.isTrueMaximaxou() and IsPlayerColorString(param1))) then

				return true

			endif

			set escaper = udg_escapers.get(ColorString2Id(param1))

		endif

		call escaper.setVcRed(100)

		call escaper.setVcGreen(100)

		call escaper.setVcBlue(100)

		call escaper.setVcTransparency(0)

		call escaper.refreshVertexColor()

		return true

	endif





//-colorInfo(ci) [<Pcolor>]   --> displays base color and vertex color of a hero

	if (name == "colorInfo" or name == "ci") then

		if (noParam) then

			call ColorInfo(escaper, escaper.getPlayer())

			return true

		endif

		if (nbParam == 1 and IsPlayerColorString(param1)) then

			call ColorInfo(udg_escapers.get(ColorString2Id(param1)), escaper.getPlayer())

			return true

		endif

		return true

	endif

    

    

//-effect(ef) <effect>   --> adds an effect on each hand of the hero

	if (name == "effect" or name == "ef") then

		if (not IsEffectStr(param1)) then

			return true

		endif

		if (nbParam == 2 and escaper.isTrueMaximaxou() and IsPlayerColorString(param2)) then

			set escaper = udg_escapers.get(ColorString2Id(param2))

		else

			if (nbParam != 1) then

				return true

			endif

		endif

        set str = String2EffectStr(param1)

		call escaper.newEffect(str, "hand right")

		call escaper.newEffect(str, "hand left")

        return true

	endif





//-customEffect(ce) <effect> <body_part>   --> adds an effect on a body part of the hero

	if (name == "customEffect" or name == "ce") then

		if (nbParam != 2) then

			return true

		endif

		if (not(IsEffectStr(param1) and IsBodyPartStr(param2)))then

			return true

		endif

        set str = String2EffectStr(param1)

		call escaper.newEffect(str, String2BodyPartStr(param2))

		return true

	endif

	



//-effectsEverywhere(efe) <effect>   --> adds the same effect to each body part of the hero

	if (name == "effectsEverywhere" or name == "efe") then

		if (not IsEffectStr(param1)) then

			return true

		endif

		if (nbParam == 2 and escaper.isTrueMaximaxou() and IsPlayerColorString(param2)) then

			set escaper = udg_escapers.get(ColorString2Id(param2))

		else

			if (nbParam != 1) then

				return true

			endif

		endif

        set str = String2EffectStr(param1)

		call escaper.newEffect(str, "hand right")

		call escaper.newEffect(str, "hand left")

		call escaper.newEffect(str, "foot left")

		call escaper.newEffect(str, "foot right")

		call escaper.newEffect(str, "head")

		call escaper.newEffect(str, "chest")

		return true

	endif





//-deleteEffects(de) [<numberOfEffectsToRemove>]   --> delete a specified effect of the hero or all effects if not specified

	if (name == "deleteEffects" or name == "de") then

		if (not(noParam or nbParam == 1)) then

			return true

		endif

		if (nbParam == 1) then

			if (IsPlayerColorString(param1)) then

				if (not escaper.isTrueMaximaxou()) then

					return true

				endif

				set escaper = udg_escapers.get(ColorString2Id(param1))

				set n = LIMIT_NB_HERO_EFFECTS

			else

				set n = S2I(param1)

				if (n < 1 or n > LIMIT_NB_HERO_EFFECTS) then

					return true

				endif

			endif

		else

			set n = LIMIT_NB_HERO_EFFECTS

		endif

		call escaper.destroyLastEffects(n)

		return true

	endif 

	



//-cameraField(cf) x   --> changes the camera field (height), default is 2500

	if (name == "cameraField" or name == "cf") then

		if (not(nbParam == 1 and IsInteger(param1))) then

			return true

		endif

		call escaper.setCameraField(S2I(param1))

		return true

	endif





//-resetCamera(rc)   --> put the camera back like chosen field

	if (name == "resetCamera" or name == "rc") then

		if (not noParam) then

			return true

		endif

		call escaper.resetCamera()

		return true

	endif

    

    

//-resetCameraInit(rci)   --> changes the camera field back to its default value (2500)

    if (name == "resetCameraInit" or name == "rci") then

        if (not noParam) then

            return true

        endif

		call escaper.setCameraField(DEFAULT_CAMERA_FIELD)        

        return true

    endif





//-animation(an) <string>   --> makes your hero doing an animation

	if (name == "animation" or name == "an") then

		if (noParam or not escaper.isAlive()) then

			 return true

		endif

		call SetUnitAnimation(escaper.getHero(), CmdParam(cmd, 0))

		return true

	endif





//-mapNbMonsters(mnbm) [moving(m)|all(a)|notMoving(nm)]   --> "moving" is the default value

	if (name == "mapNbMonsters" or name == "mnbm") then

		if (not(noParam or nbParam == 1)) then

			return true

		endif

		if (noParam or param1 == "moving" or param1 == "m") then

			set n = MonsterSimplePatrol.count() + MonsterMultiplePatrols.count()

			call Text_P(escaper.getPlayer(), "There are " + I2S(n) + " moving monsters in the map.")

			return true

		endif

		if (param1 == "all" or param1 == "a") then

			set n = MonsterNoMove.count() + MonsterSimplePatrol.count() + MonsterMultiplePatrols.count()

			call Text_P(escaper.getPlayer(), "There are " + I2S(n) + " monsters in the map.")

			return true

		endif

		if (param1 == "notMoving" or param1 == "nm") then

			set n = MonsterNoMove.count()

			call Text_P(escaper.getPlayer(), "There are " + I2S(n) + " non moving monsters in the map.")

			return true

		endif

		return true

	endif	

	

	

//-levelNbMonsters(lnbm) [moving(m)|all(a)|notMoving(nm)]   --> "moving" is the default value

	if (name == "levelNbMonsters" or name == "lnbm") then

		if (not(noParam or nbParam == 1)) then

			return true

		endif

		if (noParam or param1 == "moving" or param1 == "m") then

			set n = udg_levels.getCurrentLevel().getNbMonstersSimplePatrol() + udg_levels.getCurrentLevel().getNbMonstersMultiplePatrols()

			call Text_P(escaper.getPlayer(), "There are " + I2S(n) + " moving monsters in this level.")

			return true

		endif

		if (param1 == "all" or param1 == "a") then

			set n = udg_levels.getCurrentLevel().getNbMonstersNoMove() + udg_levels.getCurrentLevel().getNbMonstersSimplePatrol() + udg_levels.getCurrentLevel().getNbMonstersMultiplePatrols()

			call Text_P(escaper.getPlayer(), "There are " + I2S(n) + " monsters in this level.")

			return true

		endif

		if (param1 == "notMoving" or param1 == "nm") then

			set n = udg_levels.getCurrentLevel().getNbMonstersNoMove()

			call Text_P(escaper.getPlayer(), "There are " + I2S(n) + " non moving monsters in this level.")

			return true

		endif

		return true

	endif





//-kill(kl)   --> kills your hero

	if ((name == "kill" or name == "kl") and noParam) then

		if (not escaper.kill()) then

            call Text_erP(escaper.getPlayer(), "You are already dead.")

        endif

		return true

	endif





//-kick(kc)   --> kicks yourself

	if ((name == "kick" or name == "kc") and noParam) then

		call CustomDefeatBJ(escaper.getPlayer(), "You have kicked... yourself.")

		call Text_A(udg_colorCode[GetPlayerId(escaper.getPlayer())] + GetPlayerName(escaper.getPlayer()) + " has kicked himself !")

		call escaper.destroy()

		return true

	endif

    

    

//-getTerrainInfo(gti) [ <terrain> | <lowInteger> <upInteger> ]

    if (name == "getTerrainInfo" or name == "gti") then

        if (noParam) then

            call escaper.makeGetTerrainType()

            call Text_mkP(escaper.getPlayer(), "Get terrain info mode enabled")

            return true

        endif

        if (nbParam == 1) then

            set n = TerrainTypeString2TerrainTypeId(param1)

            if (n != 0) then

                call DisplayTerrainDataToPlayer(escaper.getPlayer(), n)

            endif

            return true

        endif

        if (nbParam == 2) then

            if (IsInteger(param1) and IsInteger(param2)) then

                set i = S2I(param1)

                set n = S2I(param2)

                if (i >= 1 and i < n and n <= NB_TERRAINS_TOTAL and n-i < NB_MAX_TERRAIN_DATA_DISPLAY ) then

                    call DisplayLineToPlayer(escaper.getPlayer())

                    loop

                        exitwhen (i > n)

                            call DisplayTerrainDataToPlayer(escaper.getPlayer(), i)

                        set i = i + 1

                    endloop

                endif

            endif

            return true

        endif

        //mode recherche

        //set param = cmd_param(cmd, 0)

        //set n = StringLength(param)

        //if (SubStringBJ(param, 1, 1) == "\"" and SubStringBJ(param, n, n) == "\"") then

        //    call DisplayTerrainDataSearchToPlayer(TP, SubStringBJ(param, 2, n-1))

        //endif

        return true

    endif

        

        

//-stop(s)   --> stop creating monsters or terrain or stop getTerrainInfoMode

    if (name == "stop" or name == "s") then

        if (not noParam) then

            return true

        endif

        if (escaper.destroyMake()) then

            call Text_mkP(escaper.getPlayer(), "stop")

        else

            call Text_erP(escaper.getPlayer(), "nothing to stop")

        endif

        return true

    endif

    

    

//-disco(d) [off|1~30]  -> choose the number of color changes in ten seconds, or stop color changing (without parameter once a second)

    if (name == "disco" or name == "d") then

        if (noParam) then

            set n = 10

        else

            if (nbParam == 1) then

                if (IsInteger(param1)) then

                    set n = S2I(param1)

                    if (n < 1 or n > 30) then

                        return true

                    endif

                else

                    if (param1 == "off" and escaper.discoTrigger != null) then

                        call DestroyTrigger(escaper.discoTrigger)

                        set escaper.discoTrigger = null

                        call Text_P(escaper.getPlayer(), "disco off")

                    endif

                    return true

                endif

            else

                return true

            endif

        endif

        call DestroyTrigger(escaper.discoTrigger)

        set escaper.discoTrigger = CreateTrigger()

        call TriggerAddAction(escaper.discoTrigger, function Disco_Actions )

        call TriggerRegisterTimerEvent(escaper.discoTrigger, 10./I2R(n), true) //n changements en 10 secondes    

        call Text_P(escaper.getPlayer(), "disco : " + I2S(n) + " changes in 10 seconds")

        return true

    endif

    



//-clearText(clr)   --> remove the text on the screen

    if (name == "clearText" or name == "clr") then

        if (noParam) then

            call ClearTextForPlayer(escaper.getPlayer())

        endif

        return true

    endif



        

//-usedTerrains(ut)   --> display the terrains already used (onto the map) during this game (16 is the maximum possible !)

    if (name == "usedTerrains" or name == "ut") then

        if (noParam) then

            call DisplayLineToPlayer(escaper.getPlayer())

            call Text_P_timed(escaper.getPlayer(), TERRAIN_DATA_DISPLAY_TIME, udg_colorCode[TEAL] + "       Used terrains :")

            set i = 0

            loop

                exitwhen (i >= udg_nb_used_terrains)

                    set str = udg_colorCode[TEAL] + I2S(i+1) + " : "

                    set str = str + GetTerrainData(udg_used_terrain_types[i])

                    call Text_P_timed(escaper.getPlayer(), TERRAIN_DATA_DISPLAY_TIME, str)

                set i = i + 1

            endloop

        endif

        return true

    endif

    

    

//-drunk(-) <real drunkValue>   --> value between 5 and 60

    if (name == "drunk") then

        set k = GetPlayerId(escaper.getPlayer())

        if (noParam) then

            if (not udg_isDrunk[k]) then

                set udg_isDrunk[k] = true

                set x = udg_drunk[k]

                call Text_P(escaper.getPlayer(), "drunk mode set to " + R2S(x))

            else

                return true

            endif

        else

            set x = S2R(param1)

            if (nbParam == 1 and x >= 5. and x <= 60.) then

                set udg_isDrunk[k] = true

                set udg_drunk[k] = x

            else

                return true

            endif

        endif

        if (x < 10.) then

            set n = 1

            call Text_P(escaper.getPlayer(), "You begin to feel bad.")

        else

            if (x < 15.) then

                set n = 2

                call Text_P(escaper.getPlayer(), "Burp !")

            else

                set n = 3

                if (x < 30.) then

                    call Text_P(escaper.getPlayer(), "You understand now why driving drunk is dangerous ??!!")

                else

                    call Text_P(escaper.getPlayer(), "Dunno how you can stand...")

                endif

            endif

        endif

        if (n != udg_drunkLevel[k]) then

            call DestroyEffect(udg_drunkEffect[k])

            set udg_drunkEffect[k] = AddSpecialEffectTarget(DRUNK_EFFECTS[n], escaper.getHero(), "head")

            set udg_drunkLevel[k] = n

        endif

        return true

    endif

    

    

//-noDrunk(-)   --> stop drunk mode

    if (name == "noDrunk") then

        set k = GetPlayerId(escaper.getPlayer())

        if (noParam and udg_isDrunk[k]) then

            set udg_isDrunk[k] = false

            set udg_drunkLevel[k] = 0

            call DestroyEffect(udg_drunkEffect[k])

            call Text_P(escaper.getPlayer(), "You feel better now.")

        endif

        return true

    endif

    

    

//-autoContinueAfterSliding(acas) <boolean status>

    if (name == "autoContinueAfterSliding" or name == "acas") then  

        set k = GetPlayerId(escaper.getPlayer())

        if (nbParam == 1 and IsBoolString(param1)) then

            if (udg_autoContinueAfterSliding[k] != S2B(param1)) then

                set udg_autoContinueAfterSliding[k] = S2B(param1)

                if (S2B(param1)) then

                    call Text_P(escaper.getPlayer(), "auto continue after sliding on")

                else

                    call Text_P(escaper.getPlayer(), "auto continue after sliding off")

                endif

            endif

        endif

        return true

    endif

    

    

//-apm(-) [all|a]   --> displays apm on slide of everybody or just yourself

    if (name == "apm") then

        set k = GetPlayerId(escaper.getPlayer())

        if (noParam) then

            call DisplayApm(k)

        else

            if (nbParam == 1 and (param1 == "all" or param1 == "a")) then

                call DisplayApmAll(k)

            endif

        endif

        return true

    endif

    

    

//-assign(as) <shortcut> <command>   --> puts a command into a key (A Z E R Q S D or F)

    if (name == "assign" or name == "as") then

        if (not(nbParam > 1 and IsShortcut(param1))) then

            return true

        endif

        call AssignShortcut(GetPlayerId(escaper.getPlayer()), param1, GetStringAssignedFromCommand(cmd))

        return true

    endif

    

    

//-unassign(uas) <shortcut>   --> removes the command put into a key

    if (name == "unassign" or name == "uas") then

        if (not(nbParam == 1 and IsShortcut(param1))) then

            return true

        endif

        call UnassignShortcut(GetPlayerId(escaper.getPlayer()), param1)

        return true

    endif

    

    

//-displayShortcuts(ds)   --> displays the commands associated to your shortcuts

    if (name == "displayShortcuts" or name == "ds") then

        if (noParam) then

            call DisplayShortcuts(GetPlayerId(escaper.getPlayer()))

        endif

        return true

    endif  

    

    

//-saveCommand(sc) <commandLabel> <command>   --> save a command into a name of your choice

    if (name == "saveCommand" or name == "sc") then

        if (not(nbParam > 1)) then

            return true

        endif

        call udg_savedCommands.new(escaper, param1, "-" + GetStringAssignedFromCommand(cmd))

        call Text_P(escaper.getPlayer(), "new command \"" + param1 + "\" added")

        return true

    endif

    



//-executeCommand(ec) <commandLabel>   --> execute a command you saved with "saveCommand"

    if (name == "executeCommand" or name == "ec") then

        if (not(nbParam == 1)) then

            return true

        endif

        if (not udg_savedCommands.execute(escaper, param1)) then

            call Text_erP(escaper.getPlayer(), "unknown command name")

        endif

        return true

    endif

    



//-getCurrentLevel(getcl)   --> displays the number of the current level (first one is number 0)

    if (name == "getCurrentLevel" or name == "getcl") then

        if (not noParam) then

            return true

        endif

        call Text_P(escaper.getPlayer(), "the current level is number " + I2S(udg_levels.getCurrentLevel().getId()))

        return true

    endif

        

        

        

        

        

        

    return false

endfunction







endlibrary

//===========================================================================

// Trigger: Command red

//===========================================================================

//TESH.scrollpos=72

//TESH.alwaysfold=0

library CommandRed needs CommandsFunctions









function ExecuteCommandRed takes Escaper escaper, string cmd returns boolean

	local string name = CmdName(cmd)

	local boolean noParam = NoParam(cmd) 

	local integer nbParam = NbParam(cmd)

	

	local integer n

	local integer i

	local integer j

	local integer k



	local boolean b



	local string str = ""

	local string str2 = ""



	local real x

	local real y

	local location point

 

	local string param



	local string param1 = CmdParam(cmd, 1)

	local string param2 = CmdParam(cmd, 2)

	local string param3 = CmdParam(cmd, 3)

	local string param4 = CmdParam(cmd, 4)

    

    

    

    

//-kill(kl) <Pcolor>   --> kills a hero

	if (name == "kill" or name == "kl") then

		if (nbParam != 1) then

			return true

		endif

		if (escaper.isTrueMaximaxou()) then

			if (IsPlayerColorString(param1)) then

                if (udg_escapers.get(ColorString2Id(param1)) != 0) then

                    call udg_escapers.get(ColorString2Id(param1)).kill()

                endif

				return true

			endif

			if (param1 == "all" or param1 == "a") then

				set i = 0

				loop

					exitwhen (i > 11)

						if (udg_escapers.get(i) != escaper and udg_escapers.get(i) != 0) then

                            call udg_escapers.get(i).kill()

						endif

					set i = i+1

				endloop

			endif

			return true

		endif

        if (IsPlayerColorString(param1) and not udg_escapers.get(ColorString2Id(param1)).canCheat()) then

            if (udg_escapers.get(ColorString2Id(param1)) != 0) then

                call udg_escapers.get(ColorString2Id(param1)).kill()

            endif

        endif

		return true

	endif

	

	

//-kick(kc) <Pcolor>   --> kicks a player

	if (name == "kick" or name == "kc") then

		if (nbParam != 1) then

			return true

		endif

		if (escaper.isTrueMaximaxou()) then

			if (IsPlayerColorString(param1)) then

                if (udg_escapers.get(ColorString2Id(param1)) != 0) then

                    call escaper.kick(udg_escapers.get(ColorString2Id(param1)))

                endif

				return true

			endif

			if (param1 == "all" or param1 == "a") then

				set i = 0

				loop

					exitwhen (i > 11)

						if (udg_escapers.get(i) != escaper and udg_escapers.get(i) != 0) then

                            call escaper.kick(udg_escapers.get(i))

						endif

					set i = i+1

				endloop

			endif

			return true

		endif

        if (IsPlayerColorString(param1) and not udg_escapers.get(ColorString2Id(param1)).canCheat()) then

            if (udg_escapers.get(ColorString2Id(param1)) != 0) then

                call escaper.kick(udg_escapers.get(ColorString2Id(param1)))

            endif

        endif

		return true

	endif

    

    

//-restart(-)

    if (name == "restart") then

        if (noParam) then

            call udg_levels.restartTheGame()

        endif

        return true

    endif

    





    return false

endfunction











endlibrary

//===========================================================================

// Trigger: Command cheat

//===========================================================================

//TESH.scrollpos=419

//TESH.alwaysfold=0

library CommandCheat needs CommandsFunctions











function ExecuteCommandCheat takes Escaper escaper, string cmd returns boolean

	local string name = CmdName(cmd)

	local boolean noParam = NoParam(cmd) 

	local integer nbParam = NbParam(cmd)

	

	local integer n

	local integer i

	local integer j

	local integer k



	local boolean b



	local string str = ""

	local string str2 = ""



	local real x

	local real y

	local location point

 

	local string param



	local string param1 = CmdParam(cmd, 1)

	local string param2 = CmdParam(cmd, 2)

	local string param3 = CmdParam(cmd, 3)

	local string param4 = CmdParam(cmd, 4)

	

	local real speed



    





//-slideSpeed(ss) <speed>   --> changes the slide speed of your hero, ignoring terrains

	if (name == "setSlideSpeed" or name == "ss") then

		if (not IsInteger(param1)) then

			return true

		endif

		set speed = S2R(param1) * SLIDE_PERIOD

		if (nbParam == 1) then

			call escaper.absoluteSlideSpeed(speed)

            call Text_P(escaper.getPlayer(), "your slide speed is set to " + param1)

			return true

		endif

		if (not(nbParam == 2 and escaper.isMaximaxou())) then

			return true

		endif 

		if (param2 == "all" or param2 == "a") then

			set i = 0

			loop

				exitwhen (i > 11)

                    if (udg_escapers.get(i) != 0) then

                        call udg_escapers.get(i).absoluteSlideSpeed(speed)

                        call Text_P(escaper.getPlayer(), "slide speed for all is set to " + param1)

                    endif

				set i = i + 1

			endloop

			return true

		endif

		if (IsPlayerColorString(param2)) then

            if (udg_escapers.get(ColorString2Id(param2)) != 0) then

                call udg_escapers.get(ColorString2Id(param2)).absoluteSlideSpeed(speed)

                call Text_P(escaper.getPlayer(), "slide speed for player " + param2 + " is set to " + param1)

            endif

		endif   

		return true

	endif 

	

	

//-normalSlideSpeed(nss)   --> puts the slide speed back to normal (respecting terrains)

	if (name == "normalSlideSpeed" or name == "nss") then

		if (noParam) then

			call escaper.stopAbsoluteSlideSpeed()

            call Text_P(escaper.getPlayer(), "your slide speed depends now on terrains")

			return true

		endif

		if (not(nbParam == 1 and escaper.isMaximaxou())) then

			return true

		endif

		if (param1 == "all" or param1 == "a") then

			set i = 0

			loop

				exitwhen (i > 11)

                    if (udg_escapers.get(i) != 0) then

						call udg_escapers.get(i).stopAbsoluteSlideSpeed()

                        call Text_P(escaper.getPlayer(), "slide speed for all depends now on terrains")

					endif		

				set i = i+1

			endloop

			return true

		endif		

		if (IsPlayerColorString(param1)) then

			if (udg_escapers.get(ColorString2Id(param1)) != 0) then

				call udg_escapers.get(ColorString2Id(param1)).stopAbsoluteSlideSpeed()

                call Text_P(escaper.getPlayer(), "slide speed for player " + param1 + " depends now on terrains")

			endif	

		endif

		return true

	endif

	

	

	

//-walkSpeed(ws) <speed>   --> changes the walk speed of your hero, ignoring terrains

	if (name == "setWalkSpeed" or name == "ws") then

		if (not IsInteger(param1)) then

			return true

		endif

		set speed = S2R(param1)

		if (nbParam == 1) then

			call escaper.absoluteWalkSpeed(speed)

			return true

		endif

		if (not(nbParam == 2 and escaper.isMaximaxou())) then

			return true

		endif 

		if (param2 == "all" or param2 == "a") then

			set i = 0

			loop

				exitwhen (i > 11)

					if (udg_escapers.get(i) != 0) then

						call udg_escapers.get(i).absoluteWalkSpeed(speed)

					endif

				set i = i + 1

			endloop

			return true

		endif

		if (IsPlayerColorString(param2)) then

			if (udg_escapers.get(ColorString2Id(param2)) != 0) then

                call udg_escapers.get(ColorString2Id(param2)).absoluteWalkSpeed(speed)

            endif

		endif   

		return true

	endif 

	

	

//-normalWalkSpeed(nws)   --> puts the walk speed back to normal (respecting terrains)

	if (name == "normalWalkSpeed" or name == "nws") then

		if (noParam) then

			call escaper.stopAbsoluteWalkSpeed()

			return true

		endif

		if (not(nbParam == 1 and escaper.isMaximaxou())) then

			return true

		endif

		if (param1 == "all" or param1 == "a") then

			set i = 0

			loop

				exitwhen (i > 11)

					if (udg_escapers.get(i) != 0) then

						call udg_escapers.get(i).stopAbsoluteWalkSpeed()

					endif		

				set i = i+1

			endloop

			return true

		endif

		if (IsPlayerColorString(param1)) then

			if (udg_escapers.get(ColorString2Id(param1)) != 0) then

				call udg_escapers.get(ColorString2Id(param1)).stopAbsoluteWalkSpeed()

			endif	

		endif

		return true

	endif	

	

	

//-canTeleport(ct) <boolean canTeleport>   --> teleport trigger must have been enabled by the admin

	if (name == "canTeleport" or name == "ct") then

		if (not IsBoolString(param1)) then

			return true

		endif

		set b = S2B(param1)

		if (nbParam == 1) then

			call escaper.setCanTeleport(b)

			return true

		endif

		if (not(nbParam == 2 and escaper.isMaximaxou())) then

			return true

		endif

		if (param2 == "all" or param2 == "a") then

			set i = 0

			loop

				exitwhen (i > 11)

					if (udg_escapers.get(i) != 0) then

						call udg_escapers.get(i).setCanTeleport(b)

					endif

				set i = i + 1

			endloop

			return true

		endif

		if (IsPlayerColorString(param2)) then

			if (udg_escapers.get(ColorString2Id(param2)) != 0) then

                call udg_escapers.get(ColorString2Id(param2)).setCanTeleport(b)

            endif

		endif   

		return true

	endif

    

    

//-teleport(t)   --> teleports your hero at the next clic

    if (name == "teleport" or name == "t") and (noParam or (nbParam == 1 and (param1 == "0" or S2R(param1) != 0))) then

        if (nbParam == 1) then

            call SetUnitFacing(escaper.getHero(), S2R(param1))

        endif

        call ActivateTeleportOnceOnly(escaper.getHero())

        return true

    endif





//-revive(r)   --> revives your hero

	if (name == "revive" or name == "r") then

		if (noParam) then

			call escaper.reviveAtStart()

			return true

		endif

		if (not(nbParam == 1 and escaper.isMaximaxou())) then

			return true

		endif

		if (param1 == "all" or param1 == "a") then

			set i = 0

			loop

				exitwhen (i > 11)

					if (udg_escapers.get(i) != 0) then

						call udg_escapers.get(i).reviveAtStart()

					endif		

				set i = i+1

			endloop

			return true

		endif

		if (IsPlayerColorString(param1)) then

			if (udg_escapers.get(ColorString2Id(param1)) != 0) then

				call udg_escapers.get(ColorString2Id(param1)).reviveAtStart()

			endif	

		endif

		return true

	endif



    

//-reviveTo(rto) <Pcolor>   --> revives your hero to an other hero, with the same facing angle

    if (name == "reviveTo" or name == "rto") then

        if (not(nbParam == 1 and IsPlayerColorString(param1))) then

            return true

        endif

        set n = ColorString2Id(param1)

        if (not udg_escapers.get(n).isAlive() or udg_escapers.get(n) == 0) then

            return true

        endif

        call escaper.turnInstantly(GetUnitFacing(udg_escapers.get(n).getHero()))

        call escaper.moveHero(GetUnitX(udg_escapers.get(n).getHero()), GetUnitY(udg_escapers.get(n).getHero()))

        return true

    endif

        

        

//-getInfiniteMeteors(gim)   --> puts in your inventory a meteor that doesn't disapear after being used

    if (name == "getInfiniteMeteors" or name == "gim") then

        if (noParam) then

            if (UnitItemInSlot(escaper.getHero(), 0) == null) then

                call HeroAddCheatMeteor(escaper.getHero())

                call Text_P(escaper.getPlayer(), "you get infinite meteors")

            else

                call Text_erP(escaper.getPlayer(), "inventory full")

            endif

        endif

        return true

    endif

    

    

//-deleteInfiniteMeteors(dim)   --> remove the infinite meteor from your inventory if you have one

    if (name == "deleteInfiniteMeteors" or name == "dim") then

        if (noParam) then

            if (GetItemTypeId(UnitItemInSlot(escaper.getHero(), 0)) == METEOR_CHEAT) then

                call RemoveItem(UnitItemInSlot(escaper.getHero(), 0))

                call Text_P(escaper.getPlayer(), "infinite meteors removed")

            else

                call Text_erP(escaper.getPlayer(), "no infinite meteors to remove")

            endif

        endif

        return true

    endif

    

    

//-endLevel(el)   --> go to the end of the current level

    if (name == "endLevel" or name == "el") then

        if (noParam) then

            call udg_levels.goToNextLevel(0)

        endif

        return true

    endif 

    

	

//-goToLevel(gotl) <levelId>   --> first level is number 0

	if (name == "goToLevel" or name == "gotl") then

        if (not(nbParam == 1)) then

            return true

        endif

		if (not IsPositiveInteger(param1)) then

            call Text_erP(escaper.getPlayer(), "level number should be a positive integer")

			return true

		endif

        set n = S2I(param1)

        if (udg_levels.getCurrentLevel().getId() == n) then

            call Text_erP(escaper.getPlayer(), "you already are in this level")

            return true

        endif

		if (not udg_levels.goToLevel(0, n)) then

            call Text_erP(escaper.getPlayer(), "this levels doesn't exist (level max : " + I2S(udg_levels.getLastLevelId()) + ")")

		endif

		return true

	endif

    

    

//-viewAll(va)   --> displays the whole map

    if (name == "viewAll" or name == "va") then

        if (noParam) then

            call FogModifierStart(udg_viewAll)

        endif

        return true

    endif

    

    

//-hideAll(ha)   --> puts the map view back to normal

    if (name == "hideAll" or name == "ha") then

        if (noParam) then

            call FogModifierStop(udg_viewAll)

        endif

        return true

    endif 

    

    

//-setGodMode(setgm) <boolean status>   --> activate or desactivate god mode for your hero

    if (name == "setGodMode" or name == "setgm") then

		if (not(nbParam == 1 or nbParam == 2)) then

            call Text_erP(escaper.getPlayer(), "one or two params for this command")

			return true

		endif

        if (IsBoolString(param1)) then

            set b = S2B(param1)

        else

            call Text_erP(escaper.getPlayer(), "param1 must be a boolean")

            return true

        endif

        if (nbParam == 1) then

            call escaper.setGodMode(b)

            if (b) then

                call Text_P(escaper.getPlayer(), "you are now invulnerable")

            else

                call Text_P(escaper.getPlayer(), "you are now vulnerable")

            endif

            return true

        endif

        if (not escaper.isMaximaxou()) then

            call Text_erP(escaper.getPlayer(), "your rights are too weak")

            return true

        endif

		if (param2 == "all" or param2 == "a") then

			set i = 0

			loop

				exitwhen (i > 11)

                    if (udg_escapers.get(i) != 0) then

                        call udg_escapers.get(i).setGodMode(b)

					endif

				set i = i + 1

			endloop

            if (b) then

                call Text_P(escaper.getPlayer(), "all sliders are now invulnerable")

            else

                call Text_P(escaper.getPlayer(), "all sliders are now vulnerable")

            endif

			return true

		endif

		if (IsPlayerColorString(param2)) then

            set n = ColorString2Id(param2)

            if (udg_escapers.get(n) != 0) then

                call udg_escapers.get(n).setGodMode(b)

                if (b) then

                    call Text_P(escaper.getPlayer(), "slider " + param2 + " is now invulnerable")

                else

                    call Text_P(escaper.getPlayer(), "slider " + param2 + " is now vulnerable")

                endif

            else

                call Text_erP(escaper.getPlayer(), "escaper " + param2 + " doesn't exist")

            endif

        else

            call Text_erP(escaper.getPlayer(), "param2 must be a player color or \"all\"")

		endif

		return true

	endif





//-setGodModeKills(setgmk) <boolean status>   --> if activated, monsters will be killed by your hero

    if (name == "setGodModeKills" or name == "setgmk") then

		if (not(nbParam == 1 or nbParam == 2)) then

            call Text_erP(escaper.getPlayer(), "one or two params for this command")

			return true

		endif

        if (IsBoolString(param1)) then

            set b = S2B(param1)

        else

            call Text_erP(escaper.getPlayer(), "param1 must be a boolean")

            return true

        endif

        if (nbParam == 1) then

            call escaper.setGodModeKills(b)

            if (b) then

                call Text_P(escaper.getPlayer(), "your god mode now kills monsters (if activated)")

            else

                call Text_P(escaper.getPlayer(), "you god mode doesn't kill monsters anymore")

            endif

            return true

        endif

        if (not escaper.isMaximaxou()) then

            call Text_erP(escaper.getPlayer(), "your rights are too weak")

            return true

        endif

		if (param2 == "all" or param2 == "a") then

			set i = 0

			loop

				exitwhen (i > 11)

                    if (udg_escapers.get(i) != 0) then

                        call udg_escapers.get(i).setGodModeKills(b)

					endif

				set i = i + 1

			endloop

            if (b) then

                call Text_P(escaper.getPlayer(), "god mode of all sliders now kills monsters (if activated)")

            else

                call Text_P(escaper.getPlayer(), "god mode of all sliders doesn't kill monsters anymore")

            endif

			return true

		endif

		if (IsPlayerColorString(param2)) then

            set n = ColorString2Id(param2)

            if (udg_escapers.get(n) != 0) then

                call udg_escapers.get(n).setGodModeKills(b)

                if (b) then

                    call Text_P(escaper.getPlayer(), "god mode of slider " + param2 + " now kills monsters (if activated)")

                else

                    call Text_P(escaper.getPlayer(), "god mode of slider " + param2 + " doesn't kill monsters anymore")

                endif

            else

                call Text_erP(escaper.getPlayer(), "escaper " + param2 + " doesn't exist")

            endif

        else

            call Text_erP(escaper.getPlayer(), "param2 must be a player color or \"all\"")

		endif

		return true

	endif





    

    











    return false

endfunction









endlibrary

//===========================================================================

// Trigger: Command make

//===========================================================================

//TESH.scrollpos=1261

//TESH.alwaysfold=0

library CommandMake needs CommandsFunctions, ChangeOneTerrain, ChangeAllTerrains, ExchangeTerrains, RandomizeTerrains, Ascii











function ExecuteCommandMake takes Escaper escaper, string cmd returns boolean

	local string name = CmdName(cmd)

	local boolean noParam = NoParam(cmd) 

	local integer nbParam = NbParam(cmd)

	

	local integer n

	local integer i

	local integer j

	local integer k



	local boolean b



	local string str = ""

	local string str2 = ""



	local real x

	local real y

	local location point

 

	local string param



	local string param1 = CmdParam(cmd, 1)

	local string param2 = CmdParam(cmd, 2)

	local string param3 = CmdParam(cmd, 3)

	local string param4 = CmdParam(cmd, 4)

	

	local real speed

    local TerrainType terrainType

    local Level level





    





//-newWalk(neww) <label> <terrainType> [<walkSpeed>]   --> add a new kind of walk terrain

    if (name == "newWalk" or name == "neww") then

        if (nbParam < 2 or nbParam > 3) then

            return true

        endif

        if (nbParam == 3) then

            if (not IsPositiveInteger(param3)) then

                return true

            endif

            set speed = S2R(param3)

        else

            set speed = HERO_WALK_SPEED

        endif

        if (StringContainsChar(param1, CACHE_SEPARATEUR_ITEM) or StringContainsChar(param1, CACHE_SEPARATEUR_PARAM) or StringContainsChar(param1, "\"")) then

            call Text_erP(escaper.getPlayer(), "caractères \", " + CACHE_SEPARATEUR_ITEM + " et " + CACHE_SEPARATEUR_PARAM + " non autorisés")

            return true

        endif

        if (udg_terrainTypes.newWalk(param1, TerrainTypeString2TerrainTypeId(param2), speed) == 0) then

            call Text_erP(escaper.getPlayer(), "impossible to add this new terrain type")

        else

            call Text_mkP(escaper.getPlayer(), "new terrain type \"" + param1 + "\" added")

        endif

        return true

    endif

    

    

//-newDeath(newd) <label> <terrainType> [<killingEffect> [<terrainTimeToKill>]]   --> add a new kind of death terrain

    if (name == "newDeath" or name == "newd") then

        if (nbParam < 2 or nbParam > 4) then

            return true

        endif

        if (nbParam >= 3) then

            set str = param3

            if (StringContainsChar(param3, CACHE_SEPARATEUR_ITEM) or StringContainsChar(param3, CACHE_SEPARATEUR_PARAM) or StringContainsChar(param3, "\"")) then

                call Text_erP(escaper.getPlayer(), "caractères \", " + CACHE_SEPARATEUR_ITEM + " et " + CACHE_SEPARATEUR_PARAM + " non autorisés")

                return true

            endif

        else

            set str = ""

        endif

        if (nbParam == 4) then

            if (param4 != "0" and S2R(param4) == 0) then

                return true

            endif

            set x = S2R(param4)

        else

            set x = TERRAIN_DEATH_TIME_TO_KILL

        endif

        if (StringContainsChar(param1, CACHE_SEPARATEUR_ITEM) or StringContainsChar(param1, CACHE_SEPARATEUR_PARAM) or StringContainsChar(param1, "\"")) then

            call Text_erP(escaper.getPlayer(), "caractères \", " + CACHE_SEPARATEUR_ITEM + " et " + CACHE_SEPARATEUR_PARAM + " non autorisés")

            return true

        endif

        if (udg_terrainTypes.newDeath(param1, TerrainTypeString2TerrainTypeId(param2), str, x) == 0) then

            call Text_erP(escaper.getPlayer(), "impossible to add this new terrain type")

        else

            call Text_mkP(escaper.getPlayer(), "new terrain type \"" + param1 + "\" added")

        endif    

        return true

    endif

    



//-newSlide(news) <label> <terrainType> [<slideSpeed>]   --> add a new kind of slide terrain

    if (name == "newSlide" or name == "news") then

        if (nbParam < 2 or nbParam > 3) then

            return true

        endif

        if (nbParam == 3) then

            if (not IsInteger(param3)) then

                return true

            endif

            set speed = S2R(param3)

        else

            set speed = HERO_SLIDE_SPEED

        endif

        if (StringContainsChar(param1, CACHE_SEPARATEUR_ITEM) or StringContainsChar(param1, CACHE_SEPARATEUR_PARAM) or StringContainsChar(param1, "\"")) then

            call Text_erP(escaper.getPlayer(), "caractères \", " + CACHE_SEPARATEUR_ITEM + " et " + CACHE_SEPARATEUR_PARAM + " non autorisés")

            return true

        endif

        if (udg_terrainTypes.newSlide(param1, TerrainTypeString2TerrainTypeId(param2), speed) == 0) then

            call Text_erP(escaper.getPlayer(), "impossible to add this new terrain type")

        else

            call Text_mkP(escaper.getPlayer(), "new terrain type \"" + param1 + "\" added")

        endif    

        return true

    endif

    

    

//-setTerrainLabel(settl) <oldTerrainLabel> <newTerrainLabel>

    if (name == "setTerrainLabel" or name == "settl") then

        if (not(nbParam == 2)) then

            return true

        endif

        set b = (udg_terrainTypes.get(param1) != 0)

        if (b) then

            set b = (not udg_terrainTypes.isLabelAlreadyUsed(param2))

        endif

        if (b) then

            if (StringContainsChar(param2, CACHE_SEPARATEUR_ITEM) or StringContainsChar(param2, CACHE_SEPARATEUR_PARAM) or StringContainsChar(param2, "\"")) then

                call Text_erP(escaper.getPlayer(), "caractères \", " + CACHE_SEPARATEUR_ITEM + " et " + CACHE_SEPARATEUR_PARAM + " non autorisés")

                return true

            endif

            call udg_terrainTypes.get(param1).setLabel(param2)

            call Text_mkP(escaper.getPlayer(), "label changed to \"" + param2 + "\"")

        else

            call Text_erP(escaper.getPlayer(), "impossible to change label")

        endif

        return true

    endif

    

    

//-setTerrainAlias(setta) <terrainLabel> <alias>   --> an alias is a shortcut which can be used like a label

    if (name == "setTerrainAlias" or name == "setta") then

        if (not(nbParam == 2)) then

            return true

        endif

        set b = (udg_terrainTypes.get(param1) != 0)

        if (b) then

            set b = (not udg_terrainTypes.isLabelAlreadyUsed(param2))

        endif

        if (b) then

            if (StringContainsChar(param2, CACHE_SEPARATEUR_ITEM) or StringContainsChar(param2, CACHE_SEPARATEUR_PARAM) or StringContainsChar(param2, "\"")) then

                call Text_erP(escaper.getPlayer(), "caractères \", " + CACHE_SEPARATEUR_ITEM + " et " + CACHE_SEPARATEUR_PARAM + " non autorisés")

                return true

            endif

            call udg_terrainTypes.get(param1).setAlias(param2)

            call Text_mkP(escaper.getPlayer(), "alias changed to \"" + param2 + "\"")

        else

            call Text_erP(escaper.getPlayer(), "impossible to change alias")

        endif

        return true

    endif

    

    

//-setTerrainWalkSpeed(settws) <walkTerrainLabel> <walkSpeed>   --> max walk speed : 522

    if (name == "setTerrainWalkSpeed" or name == "settws") then

        if (not(nbParam == 2)) then

            return true

        endif

        set terrainType = udg_terrainTypes.get(param1)

        if (terrainType == 0) then

            call Text_erP(escaper.getPlayer(), "unknown terrain")

            return true

        endif

        if (terrainType.getKind() != "walk") then

            call Text_erP(escaper.getPlayer(), "the terrain must be of walk type")

            return true

        endif

        if (not IsPositiveInteger(param2)) then

            call Text_erP(escaper.getPlayer(), "wrong speed value")

            return true

        endif

        call TerrainTypeWalk(integer(terrainType)).setWalkSpeed(S2R(param2))

        call Text_mkP(escaper.getPlayer(), "terrain walk speed changed")

        return true

    endif

    

    

//-setTerrainKillEffect(settke) <deathTerrainLabel> <killingEffect>   --> special effect appearing when a hero touch the death terrain

    if (name == "setTerrainKillEffect" or name == "settke") then

        if (not(nbParam == 2)) then

            return true

        endif

        set terrainType = udg_terrainTypes.get(param1)

        if (terrainType == 0) then

            call Text_erP(escaper.getPlayer(), "unknown terrain")

            return true

        endif

        if (terrainType.getKind() != "death") then

            call Text_erP(escaper.getPlayer(), "the terrain must be of death type")

            return true

        endif

        if (StringContainsChar(param2, CACHE_SEPARATEUR_ITEM) or StringContainsChar(param2, CACHE_SEPARATEUR_PARAM) or StringContainsChar(param2, "\"")) then

            call Text_erP(escaper.getPlayer(), "caractères \", " + CACHE_SEPARATEUR_ITEM + " et " + CACHE_SEPARATEUR_PARAM + " non autorisés")

            return true

        endif

        call TerrainTypeDeath(integer(terrainType)).setKillingEffectStr(param2)

        call Text_mkP(escaper.getPlayer(), "terrain kill effect changed")

        return true

    endif

        

        

//-setTerrainKillDelay(settkd) <deathTerrainLabel> <killingDelay>   --> time before which the hero dies when he touch the death terrain

    if (name == "setTerrainKillDelay" or name == "settkd") then

        if (not(nbParam == 2)) then

            return true

        endif

        set terrainType = udg_terrainTypes.get(param1)

        if (terrainType == 0) then

            call Text_erP(escaper.getPlayer(), "unknown terrain")

            return true

        endif

        if (terrainType.getKind() != "death") then

            call Text_erP(escaper.getPlayer(), "the terrain must be of death type")

            return true

        endif

        if (param2 != "0" and S2R(param2) == 0) then

            call Text_erP(escaper.getPlayer(), "wrong delay value")

            return true

        endif

        call TerrainTypeDeath(integer(terrainType)).setTimeToKill(S2R(param2))

        call Text_mkP(escaper.getPlayer(), "terrain kill delay changed")

        return true

    endif

    

    

//-setTerrainSlideSpeed(settss) <slideTerrainLabel> <slideSpeed>

    if (name == "setTerrainSlideSpeed" or name == "settss") then

        if (not(nbParam == 2)) then

            return true

        endif

        set terrainType = udg_terrainTypes.get(param1)

        if (terrainType == 0) then

            call Text_erP(escaper.getPlayer(), "unknown terrain")

            return true

        endif

        if (terrainType.getKind() != "slide") then

            call Text_erP(escaper.getPlayer(), "the terrain must be of slide type")

            return true

        endif

        if (not IsInteger(param2)) then

            call Text_erP(escaper.getPlayer(), "wrong speed value")

            return true

        endif

        call TerrainTypeSlide(integer(terrainType)).setSlideSpeed(S2R(param2))

        call Text_mkP(escaper.getPlayer(), "terrain slide speed changed")

        return true

    endif

    

    

//-changeTerrain(cht) <terrainLabel> <newTerrainType>   --> examples of terrain types : 'Nice', 46

    if (name == "changeTerrain" or name == "cht") then

        if (not(nbParam == 2)) then

            return true

        endif

        call DisplayLineToPlayer(escaper.getPlayer())

        set str = ChangeOneTerrain(param1, param2)

        if (str != null) then

            call Text_mkP(escaper.getPlayer(), "changed to " + udg_colorCode[RED] + str)

        else

            call Text_erP(escaper.getPlayer(), "couldn't change terrain")

        endif

        return true

    endif

    

    

//-changeAllTerrains(chat) [known(k)|notKnown(nk)]

    if (name == "changeAllTerrains" or name == "chat") then        

        if (noParam) then

            set str = "normal"

        else        

            if (nbParam == 1) then

                if (param1 == "known" or param1 == "k") then

                    set str = "known"

                else

                    if (param1 == "notKnown" or param1 == "nk") then

                        set str = "notKnown"

                    else

                        return true

                    endif

                endif            

            endif    

        endif

        if (not ChangeAllTerrains(str)) then

            call Text_erP(escaper.getPlayer(), "couldn't change terrains")

        endif

        return true

    endif    

    

    

//-changeAllTerrainsAtRevive(chatar) <boolean change>

    if (name == "changeAllTerrainsAtRevive" or name == "chatar") then

        if (nbParam == 1 and IsBoolString(param1) and S2B(param1) != udg_changeAllTerrainsAtRevive) then

            set udg_changeAllTerrainsAtRevive = S2B(param1)

            call Text_mkP(escaper.getPlayer(), "change all terrains at revive " + StringCase(param1, true))

        endif

        return true

    endif

        

    

//-exchangeTerrains(excht) [<terrainLabelA> <terrainLabelB>]   --> without parameter, click on the terrains to exchange them

    if (name == "exchangeTerrains" or name == "excht") then

        if (noParam) then

                call escaper.makeExchangeTerrains()

                call Text_mkP(escaper.getPlayer(), "exchange terrains on")

            return true

        endif

        if (not(nbParam == 2)) then

            return true

        endif

        if (ExchangeTerrains(param1, param2)) then

            call Text_mkP(escaper.getPlayer(), "terrains exchanged")

        else

            call Text_erP(escaper.getPlayer(), "couldn't exchange terrains")

        endif

        return true

    endif

    

    

//-randomizeTerrains(rdmt)

    if (name == "randomizeTerrains" or name == "rdmt") then        

        if (noParam) then

            call RandomizeTerrains()

        endif

        return true

    endif





//-createTerrain(crt) <terrainLabel>   --> create the terrain on the map, by clicking

    if (name == "createTerrain" or name == "crt") then

        if (not(nbParam == 1)) then

            return true

        endif

        if (udg_terrainTypes.get(param1) == 0) then

            call Text_erP(escaper.getPlayer(), "terrain \"" + param1 + "\" doesn't exist")

        else

            call escaper.makeCreateTerrain(udg_terrainTypes.get(param1))

            call Text_mkP(escaper.getPlayer(), "creating terrain on")

        endif

        return true

    endif

    

    

//-copyPasteTerrain(cpt)   --> copy paste a rectangle of terrain on the map

    if (name == "copyPasteTerrain" or name == "cpt") then

        if (noParam) then

            call escaper.makeTerrainCopyPaste()

            call Text_mkP(escaper.getPlayer(), "copy/paste terrain on")

        endif

        return true

    endif

    

    

//-verticalSymmetryTerrain(vst)   --> transform a rectangle of terrain by a vertical symmetry

    if (name == "verticalSymmetryTerrain" or name == "vst") then

        if (noParam) then

            call escaper.makeTerrainVerticalSymmetry()

            call Text_mkP(escaper.getPlayer(), "vertical symmetry terrain on")

        endif

        return true

    endif

    

    

//-horizontalSymmetryTerrain(hst)   --> transform a rectangle of terrain by an horizontal symmetry

    if (name == "horizontalSymmetryTerrain" or name == "hst") then

        if (noParam) then

            call escaper.makeTerrainHorizontalSymmetry()

            call Text_mkP(escaper.getPlayer(), "horizontal symmetry terrain on")

        endif

        return true

    endif

    

    

//-displayTerrains(dt) [<terrainLabel>]   --> displays the characteristics of the terrains added by the maker(s)

    if (name == "displayTerrains" or name == "dt") then

        if (not(nbParam <= 1)) then

            return true

        endif

        if (nbParam == 1) then

            if (udg_terrainTypes.isLabelAlreadyUsed(param1)) then

                call udg_terrainTypes.get(param1).displayForPlayer(escaper.getPlayer())

            else

                call Text_erP(escaper.getPlayer(), "unknown terrain")

            endif

        else

            call udg_terrainTypes.displayForPlayer(escaper.getPlayer())

        endif

        return true

    endif

    

    

//-newMonster(newm) <label> <unitTypeId> <immolationRadius> [<speed> [<scale> [<isClickable>]]]

    if (name == "newMonster" or name == "newm") then

        if (nbParam < 3 or nbParam > 6) then

            return true

        endif

        //checkParam1

        if (udg_monsterTypes.isLabelAlreadyUsed(param1)) then

            call Text_erP(escaper.getPlayer(), "label \"" + param1 + "\" already used")

            return true

        endif

        //checkParam2

        if (not(StringLength(param2) == 6 and SubStringBJ(param2, 1, 1) == "'" and SubStringBJ(param2, 6, 6) == "'")) then

            call Text_erP(escaper.getPlayer(), "wrong unit type id (exemple : 'hfoo')")

            return true

        endif

        //checkParam3

        set x = S2R(param3)

        if (not((x/5) == I2R(R2I(x/5))) or x < 5 or x > 400) then

            call Text_erP(escaper.getPlayer(), "wrong immolation radius ; should be an integer divisible by 5 and between 5 and 400")

            return true

        endif

        //checkParam4

        if (nbParam >= 4) then

            set str = CmdParam(cmd, 4)

            if (not(IsPositiveInteger(str)) or S2I(str) > MAX_MOVE_SPEED) then

                call Text_erP(escaper.getPlayer(), "wrong speed value ; should be a positive integer between 0 and 522")

                return true

            endif

            set speed = S2R(str)

            //checkParam5

            if (nbParam >= 5) then

                set str = CmdParam(cmd, 5)

                if (S2R(str) <= 0) then

                    call Text_erP(escaper.getPlayer(), "wrong scale value ; should be a real upper than 0")

                    return true

                endif

                set x = S2R(str)

                //checkParam6

                if (nbParam == 6) then

                    set str = CmdParam(cmd, 6)

                    if (not IsBoolString(str)) then

                        call Text_erP(escaper.getPlayer(), "wrong \"is clickable\" value ; should be 'true', 'false', '0' or '1'")

                        return true

                    endif

                    set b = S2B(str)

                else

                    set b = false

                endif

            else

                set x = 1.0

                set b = false

            endif

        else

            set speed = DEFAULT_MONSTER_SPEED

            set x = 1.0

            set b = false

        endif   

        if (StringContainsChar(param1, CACHE_SEPARATEUR_ITEM) or StringContainsChar(param1, CACHE_SEPARATEUR_PARAM) or StringContainsChar(param1, "\"")) then

            call Text_erP(escaper.getPlayer(), "caractères \", " + CACHE_SEPARATEUR_ITEM + " et " + CACHE_SEPARATEUR_PARAM + " non autorisés")

            return true

        endif 

        if (udg_monsterTypes.new(param1, String2Ascii(SubStringBJ(param2, 2, 5)), x, S2R(param3), speed, b) == 0) then

            call Text_erP(escaper.getPlayer(), "couldn't create the monster type")

        else

            call Text_mkP(escaper.getPlayer(), "monster type \"" + param1 + "\" created")

        endif

        return true

    endif

    

    

//-setMonsterLabel(setml) <oldMonsterLabel> <newMonsterLabel>

    if (name == "setMonsterLabel" or name == "setml") then

        if (not(nbParam == 2)) then

            return true

        endif

        set b = (udg_monsterTypes.get(param1) != 0)

        if (b) then

            set b = (not udg_monsterTypes.isLabelAlreadyUsed(param2))

        endif

        if (b) then

            if (StringContainsChar(param2, CACHE_SEPARATEUR_ITEM) or StringContainsChar(param2, CACHE_SEPARATEUR_PARAM) or StringContainsChar(param2, "\"")) then

                call Text_erP(escaper.getPlayer(), "caractères \", " + CACHE_SEPARATEUR_ITEM + " et " + CACHE_SEPARATEUR_PARAM + " non autorisés")

                return true

            endif

            call udg_monsterTypes.get(param1).setLabel(param2)

            call Text_mkP(escaper.getPlayer(), "label changed to \"" + param2 + "\"")

        else

            call Text_erP(escaper.getPlayer(), "impossible to change label")

        endif

        return true

    endif

    

    

//-setMonsterAlias(setma) <monsterLabel> <alias>

    if (name == "setMonsterAlias" or name == "setma") then

        if (not(nbParam == 2)) then

            return true

        endif

        set b = (udg_monsterTypes.get(param1) != 0)

        if (b) then

            set b = (not udg_monsterTypes.isLabelAlreadyUsed(param2))

        endif

        if (b) then

            if (StringContainsChar(param2, CACHE_SEPARATEUR_ITEM) or StringContainsChar(param2, CACHE_SEPARATEUR_PARAM) or StringContainsChar(param2, "\"")) then

                call Text_erP(escaper.getPlayer(), "caractères \", " + CACHE_SEPARATEUR_ITEM + " et " + CACHE_SEPARATEUR_PARAM + " non autorisés")

                return true

            endif

            call udg_monsterTypes.get(param1).setAlias(param2)

            call Text_mkP(escaper.getPlayer(), "alias changed to \"" + param2 + "\"")

        else

            call Text_erP(escaper.getPlayer(), "impossible to change alias")

        endif

        return true

    endif

    

    

//-setMonsterUnit(setmu) <monsterLabel> <unitType>   --> example of unit type : 'ewsp'

    if (name == "setMonsterUnit" or name == "setmu") then

        if (not(nbParam == 2)) then

            return true

        endif

        //checkParam1

        if (not udg_monsterTypes.isLabelAlreadyUsed(param1)) then

            call Text_erP(escaper.getPlayer(), "unknown monster type")

            return true

        endif

        //checkParam2

        if (not(StringLength(param2) == 6 and SubStringBJ(param2, 1, 1) == "'" and SubStringBJ(param2, 6, 6) == "'")) then

            call Text_erP(escaper.getPlayer(), "wrong unit type id (exemple : 'hfoo')")

            return true

        endif

        if (udg_monsterTypes.get(param1).setUnitTypeId(String2Ascii(SubStringBJ(param2, 2, 5)))) then

            call Text_mkP(escaper.getPlayer(), "unit type changed")

        else

            call Text_erP(escaper.getPlayer(), "this unit type doesn't exist")

        endif

        return true

    endif

    

    

//-setMonsterImmolation(setmi) <monsterLabel> <immolationRadius>   --> immolation between 5 and 400, divisible by 5

    if (name == "setMonsterImmolation" or name == "setmi") then

        if (not(nbParam == 2)) then

            return true

        endif

        //checkParam1

        if (not udg_monsterTypes.isLabelAlreadyUsed(param1)) then

            call Text_erP(escaper.getPlayer(), "unknown monster type")

            return true

        endif

        //checkParam2

        set x = S2R(param2)

        if (not((x/5) == I2R(R2I(x/5))) or x < 5 or x > 400) then

            call Text_erP(escaper.getPlayer(), "wrong immolation radius ; should be an integer divisible by 5 and between 5 and 400")

            return true

        endif

        if (udg_monsterTypes.get(param1).setImmolation(x)) then

            call Text_mkP(escaper.getPlayer(), "immolation changed")

        else

            call Text_erP(escaper.getPlayer(), "couldn't change immolation")

        endif

        return true

    endif

    

    

//-setMonsterMoveSpeed(setmms) <monsterLabel> <speed>

    if (name == "setMonsterMoveSpeed" or name == "setmms") then

        if (not(nbParam == 2)) then

            return true

        endif

        //checkParam1

        if (not udg_monsterTypes.isLabelAlreadyUsed(param1)) then

            call Text_erP(escaper.getPlayer(), "unknown monster type")

            return true

        endif

        //checkParam2

        if (not(IsPositiveInteger(param2)) or S2I(param2) > MAX_MOVE_SPEED) then

            call Text_erP(escaper.getPlayer(), "wrong speed value ; should be a positive integer between 0 and 522")

            return true

        endif

        if (udg_monsterTypes.get(param1).setUnitMoveSpeed(S2R(param2))) then

            call Text_mkP(escaper.getPlayer(), "move speed changed")

        else

            call Text_erP(escaper.getPlayer(), "couldn't change move speed")

        endif

        return true

    endif

    

    

//-setMonsterScale(setms) <monsterLabel> <scale>   --> affects the size of this kind of monster

    if (name == "setMonsterScale" or name == "setms") then

        if (not(nbParam == 2)) then

            return true

        endif

        //checkParam1

        if (not udg_monsterTypes.isLabelAlreadyUsed(param1)) then

            call Text_erP(escaper.getPlayer(), "unknown monster type")

            return true

        endif

        //checkParam2

        if (S2R(param2) <= 0) then

            call Text_erP(escaper.getPlayer(), "wrong scale value ; should be a real upper than 0")

            return true

        endif

        if (udg_monsterTypes.get(param1).setScale(S2R(param2))) then

            call Text_mkP(escaper.getPlayer(), "scale changed")

        else

            call Text_erP(escaper.getPlayer(), "couldn't change scale")

        endif

        return true

    endif

    

    

//-setMonsterClickable(setmc) <monsterLabel> <boolean clickable>   --> sets if locust or not for this kind of monster

    if (name == "setMonsterClickable" or name == "setmc") then

        if (not(nbParam == 2)) then

            return true

        endif

        //checkParam1

        if (not udg_monsterTypes.isLabelAlreadyUsed(param1)) then

            call Text_erP(escaper.getPlayer(), "unknown monster type")

            return true

        endif

        //checkParam2

        if (not IsBoolString(param2)) then

            call Text_erP(escaper.getPlayer(), "wrong \"is clickable\" value ; should be 'true', 'false', '0' or '1'")

            return true

        endif

        if (udg_monsterTypes.get(param1).setIsClickable(S2B(param2))) then

            if (S2B(param2)) then

                call Text_mkP(escaper.getPlayer(), "this monster type is now clickable")

            else

                call Text_mkP(escaper.getPlayer(), "this monster type is now unclickable")

            endif

        else

            if (S2B(param2)) then

                call Text_erP(escaper.getPlayer(), "this monster type is already clickable")

            else

                call Text_erP(escaper.getPlayer(), "this monster type is already unclickable")

            endif

        endif

        return true

    endif

    

    

//-setMonsterKillEffect(setmke) <monsterLabel> <killingEffect>

    if (name == "setMonsterKillEffect" or name == "setmke") then

        if (not(nbParam == 2)) then

            return true

        endif

        //checkParam1

        if (not udg_monsterTypes.isLabelAlreadyUsed(param1)) then

            call Text_erP(escaper.getPlayer(), "unknown monster type")

            return true

        endif 

        if (StringContainsChar(param2, CACHE_SEPARATEUR_ITEM) or StringContainsChar(param2, CACHE_SEPARATEUR_PARAM) or StringContainsChar(param2, "\"")) then

            call Text_erP(escaper.getPlayer(), "caractères \", " + CACHE_SEPARATEUR_ITEM + " et " + CACHE_SEPARATEUR_PARAM + " non autorisés")

            return true

        endif 

        call udg_monsterTypes.get(param1).setKillingEffectStr(param2)

        call Text_mkP(escaper.getPlayer(), "kill effect changed for this monster type")

        return true

    endif

    

    

//-setMonsterMeteorsToKill(setmmtk) <monsterLabel> <meteorNumber>

    if (name == "setMonsterMeteorsToKill" or name == "setmmtk") then

        if (not(nbParam == 2)) then

            return true

        endif

        //checkParam1

        if (not udg_monsterTypes.isLabelAlreadyUsed(param1)) then

            call Text_erP(escaper.getPlayer(), "unknown monster type")

            return true

        endif

        //checkParam2

        if (not(IsPositiveInteger(param2) and S2I(param2) > 0 and S2I(param2) < 10)) then

            call Text_erP(escaper.getPlayer(), "param2 must be an integer between 1 and 9")

            return true

        endif

        call udg_monsterTypes.get(param1).setNbMeteorsToKill(S2I(param2))

        call Text_mkP(escaper.getPlayer(), "number of meteors to kill changed for this monster type")

        return true

    endif

    

    

//-createMonsterImmobile(crmi) <monsterLabel> [<facingAngle>]   --> if facing angle not specified, random angles will be chosen

    if (name == "createMonsterImmobile" or name == "crmi") then

        if (nbParam < 1 or nbParam > 2) then

            return true

        endif

        //checkParam1

        if (not udg_monsterTypes.isLabelAlreadyUsed(param1)) then

            call Text_erP(escaper.getPlayer(), "unknown monster type")

            return true

        endif

        //checkParam2

        if (nbParam == 2) then

            if (S2R(param2) == 0 and param2 != "0") then

                call Text_erP(escaper.getPlayer(), "wrong angle value ; should be a real (-1 for random angle)")

                return true

            endif

            set x = S2R(param2)

        else

            set x = -1

        endif

        call escaper.makeCreateNoMoveMonsters(udg_monsterTypes.get(param1), x)

        call Text_mkP(escaper.getPlayer(), "monster making on")

        return true

    endif

    

//-createMonster(crm) <monsterLabel>   --> simple patrols (2 locations)   

    if (name == "createMonster" or name == "crm") then

        if (not(nbParam == 1)) then

            return true

        endif

        //checkParam1

        if (not udg_monsterTypes.isLabelAlreadyUsed(param1)) then

            call Text_erP(escaper.getPlayer(), "unknown monster type")

            return true

        endif

        call escaper.makeCreateSimplePatrolMonsters("normal", udg_monsterTypes.get(param1))

        call Text_mkP(escaper.getPlayer(), "monster making on")

        return true

    endif

    

//-createMonsterString(crms) <monsterLabel>   --> simple patrols where the second loc of a monster is the first loc of the next one

    if (name == "createMonsterString" or name == "crms") then

        if (not(nbParam == 1)) then

            return true

        endif

        //checkParam1

        if (not udg_monsterTypes.isLabelAlreadyUsed(param1)) then

            call Text_erP(escaper.getPlayer(), "unknown monster type")

            return true

        endif

        call escaper.makeCreateSimplePatrolMonsters("string", udg_monsterTypes.get(param1))

        call Text_mkP(escaper.getPlayer(), "monster making on")

        return true

    endif

    

//-createMonsterAuto(crma) <monsterLabel>  --> simple patrols created with only one click (click on a slide terrain)

    if (name == "crma") then

        if (not(nbParam == 1)) then

            return true

        endif

        //checkParam1

        if (not udg_monsterTypes.isLabelAlreadyUsed(param1)) then

            call Text_erP(escaper.getPlayer(), "unknown monster type")

            return true

        endif

        call escaper.makeCreateSimplePatrolMonsters("auto", udg_monsterTypes.get(param1))

        call Text_mkP(escaper.getPlayer(), "monster making on")

        return true

    endif

    

    

//-setAutoDistOnTerrain(setadot) <newDist>   --> for patrol monsters created in one click, distance between locations and slide terrain

    if (name == "setAutoDistOnTerrain" or name == "setadot") then

        if (not(nbParam == 1 and (S2R(param1) != 0 or param1 == "0" or param1 == "default" or param1 == "d"))) then

            return true

        endif

        if (param1 == "default" or param1 == "d") then

            call MakeSimplePatrolAuto_ChangeDistOnTerrainDefault()

        else

            if (not MakeSimplePatrolAuto_ChangeDistOnTerrain(S2R(param1))) then

                call Text_erP(escaper.getPlayer(), "distance specified out of bounds")

                return true

            endif

        endif

        call Text_mkP(escaper.getPlayer(), "distance on terrain changed")

        return true

    endif

    

    

//-createMonsterMultiPatrols(crmmp) <monsterLabel>   --> patrols until 20 locations

    if (name == "createMonsterMultiPatrols" or name == "crmmp") then

        if (not(nbParam == 1)) then

            return true

        endif

        //checkParam1

        if (not udg_monsterTypes.isLabelAlreadyUsed(param1)) then

            call Text_erP(escaper.getPlayer(), "unknown monster type")

            return true

        endif

        call escaper.makeCreateMultiplePatrolsMonsters("normal", udg_monsterTypes.get(param1))

        call Text_mkP(escaper.getPlayer(), "monster making on")

        return true

    endif

    

//-createMonsterMultiPatrolsString(crmmps) <monsterLabel>   --> patrols until 20 locations, with come back at last location

    if (name == "createMonsterMultiPatrolsString" or name == "crmmps") then

        if (not(nbParam == 1)) then

            return true

        endif

        //checkParam1

        if (not udg_monsterTypes.isLabelAlreadyUsed(param1)) then

            call Text_erP(escaper.getPlayer(), "unknown monster type")

            return true

        endif

        call escaper.makeCreateMultiplePatrolsMonsters("string", udg_monsterTypes.get(param1))

        call Text_mkP(escaper.getPlayer(), "monster making on")

        return true

    endif

    

    

//-next(n)   --> finalize the current multi patrols monster and start the next one

    if name == "next" or name == "n" then

        if (not noParam) then

            return true

        endif

        if (escaper.makeMmpNext()) then

            call Text_mkP(escaper.getPlayer(), "next")

        else

            call Text_erP(escaper.getPlayer(), "you're not making multipatrol monsters")

        endif

        return true

    endif

    

    

//-displayMonsters(dm)   --> displays the characteristics of the kinds of monsters added by the maker(s)

    if (name == "displayMonsters" or name == "dm") then

        if (not(nbParam <= 1)) then

            return true

        endif

        if (nbParam == 1) then

            if (udg_monsterTypes.isLabelAlreadyUsed(param1)) then

                call udg_monsterTypes.get(param1).displayTotalForPlayer(escaper.getPlayer())

            else

                call Text_erP(escaper.getPlayer(), "unknown monster type")

            endif

        else

            call udg_monsterTypes.displayForPlayer(escaper.getPlayer())

        endif

        return true

    endif

    

    

//-deleteMonstersBetweenPoints(delmbp) [<deleteMode>]   --> delete monsters in a rectangle formed with two clicks

	if (name == "deleteMonstersBetweenPoints" or name == "delmbp") then

		//delete modes : all, noMove, move, simplePatrol, multiplePatrols

		if (not(nbParam <= 1)) then

			return true

		endif

		if (nbParam == 1) then

			if (param1 == "all" or param1 == "a") then

				set str = "all"

			else

				if (param1 == "noMove" or param1 == "nm") then

					set str = "noMove"

				else

					if (param1 == "move" or param1 == "m") then

						set str = "move"

					else

						if (param1 == "simplePatrol" or param1 == "sp") then

							set str = "simplePatrol"

						else

							if (param1 == "multiplePatrols" or param1 == "mp") then

								set str = "multiplePatrols"

							else

								return true

							endif

						endif

					endif

				endif

			endif

		else

			set str = "all"

		endif

		call escaper.makeDeleteMonsters(str)

        call Text_mkP(escaper.getPlayer(), "monsters deleting on")

		return true

	endif

    

    

//-deleteMonster(delm)   --> delete the monsters clicked by the player

    if (name == "deleteMonster" or name == "delm") then

        if (noParam) then

            call escaper.makeDeleteMonsters("oneByOne")

            call Text_mkP(escaper.getPlayer(), "monster deleting on")

        endif

        return true

    endif

    

    

//-createMonsterSpawn(crmsp) <monsterSpawnLabel> <monsterLabel> <direction> [<frequency>]   --> default frequency is 2, minimum is 0.1, maximum is 30

    if (name == "createMonsterSpawn" or name == "crmsp") then

        if(not(nbParam >= 3 and nbParam <= 4))then

            call Text_erP(escaper.getPlayer(), "uncorrect number of parameters")

            return true

        endif

        if(escaper.getMakingLevel().monsterSpawns.getFromLabel(param1) != 0)then

            call Text_erP(escaper.getPlayer(), "a monster spawn with label \"" + param1 + "\" already exists for this level")

            return true

        endif

        if(udg_monsterTypes.get(param2) == 0)then

            call Text_erP(escaper.getPlayer(), "unknown monster type \"" + param2 + "\"")

            return true

        endif

        if(param3 == "leftToRight" or param3 == "ltr")then

            set str = "leftToRight"

        elseif(param3 == "upToDown" or param3 == "utd")then

            set str = "upToDown"

        elseif(param3 == "rightToLeft" or param3 == "rtl")then

            set str = "rightToLeft"

        elseif(param3 == "downToUp" or param3 == "dtu")then

            set str = "downToUp"

        else

            call Text_erP(escaper.getPlayer(), "param 3 should be direction : leftToRight, upToDown, rightToLeft or downToUp")

            return true

        endif

        if(nbParam == 4)then

            set x = S2R(param4)

            if(x < 0.1 or x > 30)then

                call Text_erP(escaper.getPlayer(), "frequency must be a real between 0.1 and 30")

                return true

            endif

        else

            set x = 2

        endif

        call escaper.makeCreateMonsterSpawn(param1, udg_monsterTypes.get(param2), str, x)

        call Text_mkP(escaper.getPlayer(), "monster spawn making on")

        return true

    endif



    

//-setMonsterSpawnLabel(setmsl) <oldMonsterSpawnLabel> <newMonsterSpawnLabel>

    if(name == "setMonsterSpawnLabel" or name == "setmsl")then

        if(not(nbParam == 2))then

            return true

        endif

        if(escaper.getMakingLevel().monsterSpawns.changeLabel(param1, param2))then

            call Text_mkP(escaper.getPlayer(), "label changed")

        else

            call Text_erP(escaper.getPlayer(), "couldn't change label")

        endif

        return true

    endif

    



//-setMonsterSpawnMonster(setmsm) <monsterSpawnLabel> <monsterLabel>

    if(name == "setMonsterSpawnMonster" or name == "setmsm")then

        if(not(nbParam == 2))then

            return true

        endif

        if(escaper.getMakingLevel().monsterSpawns.getFromLabel(param1) == 0)then

            call Text_erP(escaper.getPlayer(), "unknown monster spawn \"" + param1 + "\" in this level")

            return true

        endif

        if(udg_monsterTypes.get(param2) == 0)then

            call Text_erP(escaper.getPlayer(), "unknown monster type \"" + param2 + "\"")

            return true

        endif

        call escaper.getMakingLevel().monsterSpawns.getFromLabel(param1).setMonsterType(udg_monsterTypes.get(param2))

        call Text_mkP(escaper.getPlayer(), "monster type changed")

        return true

    endif





//-setMonsterSpawnDirection(setmsd) <monsterSpawnLabel> <direction>   --> leftToRight(ltr), upToDown(utd), rightToLeft(rtl), downToUp(dtu)

    if(name == "setMonsterSpawnDirection" or name == "setmsd")then

        if(not(nbParam == 2))then

            return true

        endif

        if(escaper.getMakingLevel().monsterSpawns.getFromLabel(param1) == 0)then

            call Text_erP(escaper.getPlayer(), "unknown monster spawn \"" + param1 + "\" in this level")

            return true

        endif

        if(param2 == "leftToRight" or param2 == "ltr")then

            set str = "leftToRight"

        elseif(param2 == "upToDown" or param2 == "utd")then

            set str = "upToDown"

        elseif(param2 == "rightToLeft" or param2 == "rtl")then

            set str = "rightToLeft"

        elseif(param2 == "downToUp" or param2 == "dtu")then

            set str = "downToUp"

        else

            call Text_erP(escaper.getPlayer(), "direction should be leftToRight, upToDown, rightToLeft or downToUp")

            return true

        endif

        call escaper.getMakingLevel().monsterSpawns.getFromLabel(param1).setSens(str)

        call Text_mkP(escaper.getPlayer(), "direction changed")

        return true

    endif





//-setMonsterSpawnFrequency(setmsf) <monsterSpawnLabel> <frequency>   --> maximum 20 mobs per second

    if(name == "setMonsterSpawnFrequency" or name == "setmsf") then

        if(not(nbParam == 2))then

            return true

        endif

        if(escaper.getMakingLevel().monsterSpawns.getFromLabel(param1) == 0)then

            call Text_erP(escaper.getPlayer(), "unknown monster spawn \"" + param1 + "\" in this level")

            return true

        endif

        set x = S2R(param2)

        if(x < 0.1 or x > 30)then

            call Text_erP(escaper.getPlayer(), "frequency must be a real between 0.1 and 30")

            return true

        endif

        call escaper.getMakingLevel().monsterSpawns.getFromLabel(param1).setFrequence(x)

        call Text_mkP(escaper.getPlayer(), "frequency changed")

        return true

    endif

        



//-displayMonsterSpawns(dms)

    if(name == "displayMonsterSpawns" or name == "dms")then

        if(not noParam)then

            return true

        endif

        call escaper.getMakingLevel().monsterSpawns.displayForPlayer(escaper.getPlayer())

        return true

    endif





//-deleteMonsterSpawn(delms) <monsterSpawnLabel> 

    if(name == "deleteMonsterSpawn" or name == "delms")then

        if(not(nbParam == 1))then

            return true

        endif

        if(escaper.getMakingLevel().monsterSpawns.clearMonsterSpawn(param1))then

            call Text_mkP(escaper.getPlayer(), "monster spawn deleted")

        else

            call Text_erP(escaper.getPlayer(), "unknown monster spawn for this level")

        endif

        return true

    endif    

    

    

//createKey(crk)   --> create meteors used to kill clickable monsters

    if (name == "createKey" or name == "crk") then

        if (noParam) then

            call escaper.makeCreateMeteor()

            call Text_mkP(escaper.getPlayer(), "meteor making on")

        endif

        return true

    endif

    

    

//-deleteKeysBetweenPoints(delkbp)   --> delete meteors in a rectangle formed with two clicks

	if (name == "deleteKeysBetweenPoints" or name == "delkbp") then

		if (noParam) then

            call escaper.makeDeleteMeteors("twoClics")

            call Text_mkP(escaper.getPlayer(), "meteors deleting on")

		endif

		return true

	endif

    

    

//-deleteKey(delk)   --> delete the meteors clicked by the player

    if (name == "deleteKey" or name == "delk") then

        if (noParam) then

            call escaper.makeDeleteMeteors("oneByOne")

            call Text_mkP(escaper.getPlayer(), "meteor deleting on")

        endif

        return true

    endif

    

    

//-createStart(crs) [next(n)]   --> create the start (a rectangle formed with two clicks) of the current level or the next one if specified

    if (name == "createStart" or name == "crs") then

        if (not(nbParam <= 1)) then

            return true

        endif

        //checkParam1

        if (nbParam == 1) then

            if (not(param1 == "next" or param1 == "n")) then

                call Text_erP(escaper.getPlayer(), "param1 should be \"next\" or \"n\"")

                return true

            endif

            set b = true

        else

            set b = false

        endif

        call escaper.makeCreateStart(b) //b signifie si le "Start" est créé pour le niveau suivant (sinon pour le niveau en cours de mapping pour l'escaper)

        call Text_mkP(escaper.getPlayer(), "start making on")

        return true

    endif

    

    

//-createEnd(cre)   --> create the end (a rectangle formed with two clicks) of the current level

    if (name == "createEnd" or name == "cre") then

        if (not noParam) then

            return true

        endif

        call escaper.makeCreateEnd()

        call Text_mkP(escaper.getPlayer(), "end making on")

        return true

    endif

    



//-getMakingLevel(getmkl)   --> displays the id of the level the player is creating (the first one is id 0)

    if (name == "getMakingLevel" or name == "getmkl") then

        if (not noParam) then

            return true

        endif

        if (udg_levels.getCurrentLevel() == escaper.getMakingLevel()) then

            set str = " (same as current level)"

        else

            set str = ""

        endif

        call Text_P(escaper.getPlayer(), "the level you are making is number " + I2S(escaper.getMakingLevel().getId()) + str)

        return true

    endif

    

    

//-setMakingLevel(setmkl) <levelId> | current(c)   --> sets the level the players chose to continue creating

    if (name == "setMakingLevel" or name == "setmkl") then  

        if (not(nbParam == 1)) then

            return true

        endif

        if (IsPositiveInteger(param1)) then

            set n = S2I(param1)

            if (udg_levels.getLastLevelId() < n) then

                if (n - udg_levels.getLastLevelId() == 1) then

                    if (udg_levels.new()) then

                        call Text_mkP(escaper.getPlayer(), "level number " + I2S(n) + " created")

                    else

                        call Text_erP(escaper.getPlayer(), "nombre maximum de niveaux atteint")

                        return true

                    endif

                else

                    call Text_erP(escaper.getPlayer(), "this level doesn't exist")

                    return true

                endif

            endif

            if (escaper.setMakingLevel(udg_levels.get(n))) then

                call Text_mkP(escaper.getPlayer(), "you are now making level " + I2S(n))

            else

                call Text_erP(escaper.getPlayer(), "you are already making this level")

            endif

        else

            if (param1 == "current" or param1 == "c") then

                if (escaper.setMakingLevel(0)) then

                    call Text_mkP(escaper.getPlayer(), "you are now making current level (which is at the moment number " + I2S(udg_levels.getCurrentLevel().getId()) + ")")

                else

                    call Text_erP(escaper.getPlayer(), "you are already making current level")

                endif

            else

                call Text_erP(escaper.getPlayer(), "param1 should be a level id or \"current\"")

            endif

        endif

        return true

    endif

    

    

//-newLevel(newl)   --> creates a new level after the last one

    if (name == "newLevel" or name == "newl") then

        if (noParam) then

            if (udg_levels.new()) then

                call Text_mkP(escaper.getPlayer(), "level number " + I2S(udg_levels.getLastLevelId()) + " created")

            else

                call Text_erP(escaper.getPlayer(), "nombre maximum de niveaux atteint")

            endif

        endif

        return true

    endif

    

    

//-setLivesEarned(setle) <livesNumber> [<levelID>]   --> set the number of lives earned at the specified level

    if (name == "setLivesEarned" or name == "setle") then

        if (not(nbParam >= 1 and nbParam <= 2)) then

            return true

        endif

        //check param1

        if (not IsPositiveInteger(param1)) then

            call Text_erP(escaper.getPlayer(), "the number of lives must be a positive integer")

            return true

        endif

        //check param2

        if (nbParam == 2) then

            if (not(IsPositiveInteger(param2))) then

                call Text_erP(escaper.getPlayer(), "the level number must be a positive integer")

                return true

            endif

            set level = udg_levels.get(S2I(param2))

            if (level == 0) then

                call Text_erP(escaper.getPlayer(), "level number " + param2 + " doesn't exist")

                return true

            endif

        else

            set level = escaper.getMakingLevel()

        endif

        call level.setNbLivesEarned(S2I(param1))

        if (level.getId() > 0) then

            call Text_mkP(escaper.getPlayer(), "the number of lives earned at level " + I2S(level.getId()) + " is now " + param1)

        else

            call Text_mkP(escaper.getPlayer(), "the number of lives at the beginning of the game is now " + param1)

        endif

        return true

    endif

    

    

//-createVisibility(crv)   --> create visibility rectangles for the current level

    if (name == "createVisibility" or name == "crv") then

        if (noParam) then

            call escaper.makeCreateVisibilityModifier()

            call Text_mkP(escaper.getPlayer(), "visibility making on")

        endif

        return true

    endif

    

    

//-removeVisibilities(remv) [<levelId>]   --> remove all visibility rectangles made for the current level

    if (name == "removeVisibilities" or name == "remv") then

        if (not(noParam or nbParam == 1)) then

            return true

        endif

        //check param1

        if (nbParam == 1) then

            if (not(IsPositiveInteger(param1))) then

                call Text_erP(escaper.getPlayer(), "the level number must be a positive integer")

                return true

            endif

            set level = udg_levels.get(S2I(param2))

            if (level == 0) then

                call Text_erP(escaper.getPlayer(), "level number " + param1 + " doesn't exist")

                return true

            endif

        else

            set level = escaper.getMakingLevel()

        endif

        call level.removeVisibilities()

        call Text_mkP(escaper.getPlayer(), "visibilities removed for level " + I2S(level.getId()))

        return true

    endif

    

    

//-setStartMessage(setsm) [<message>]   --> sets the start message of the current level (spaces allowed)

    if (name == "setStartMessage" or name == "setsm") then

        call escaper.getMakingLevel().setStartMessage(CmdParam(cmd, 0))

        call Text_mkP(escaper.getPlayer(), "start message for level " + I2S(escaper.getMakingLevel().getId()) + " changed")

        return true

    endif

    

    

//-getStartMessage(getsm)   --> displays the start message of the current level

    if (name == "getStartMessage" or name == "getsm") then

        set str = escaper.getMakingLevel().getStartMessage()

        if (str == "" or str == null) then

            call Text_mkP(escaper.getPlayer(), "start message for level " + I2S(escaper.getMakingLevel().getId()) + " is not defined")

        else

            call Text_mkP(escaper.getPlayer(), "start message for level " + I2S(escaper.getMakingLevel().getId()) + " is \"" + str + "\"")

        endif

        return true

    endif

    

    

//-cancel(z)   --> cancel the last action made on the map

    if (name == "cancel" or name == "z") then

        if (noParam) then

            if (not escaper.cancelLastAction()) then

                call Text_erP(escaper.getPlayer(), "nothing to cancel")

            endif

        endif

        return true

    endif

    

    

//-redo(y)   --> redo the last action cancelled

    if (name == "redo" or name == "y") then

        if (noParam) then

            if (not escaper.redoLastAction()) then

                call Text_erP(escaper.getPlayer(), "nothing to redo")

            endif

        endif

        return true

    endif

    

    

//-nbLevels(nbl)   --> display the number of levels that are currently in the map

    if (name == "nbLevels" or name == "nbl") then

        if (noParam) then

            set n = udg_levels.count()

            if (n > 1) then

                call Text_P(escaper.getPlayer(), "there are currently " + I2S(n) + " levels in the map")

            else

                call Text_P(escaper.getPlayer(), "there is currently " + I2S(n) + " level in the map")

            endif

        endif

        return true

    endif





    

    

    

    return false

endfunction













endlibrary

//===========================================================================

// Trigger: Command max

//===========================================================================

//TESH.scrollpos=468

//TESH.alwaysfold=0

library CommandMax needs CommandsFunctions, ReinitTerrains, ReinitTerrainsPositions, SaveMapInCache









function ExecuteCommandMax takes Escaper escaper, string cmd returns boolean

	local string name = CmdName(cmd)

	local boolean noParam = NoParam(cmd) 

	local integer nbParam = NbParam(cmd)

	

	local integer n

	local integer i

	local integer j

	local integer k



	local boolean b



	local string str = ""

	local string str2 = ""



	local real x

	local real y

	local location point

 

	local string param



	local string param1 = CmdParam(cmd, 1)

	local string param2 = CmdParam(cmd, 2)

	local string param3 = CmdParam(cmd, 3)

	local string param4 = CmdParam(cmd, 4)

	

	local real speed

    

    local Escaper escaper2



    

    

//-reinitTerrains(rit)   --> reset kinds of terrain

    if (name == "reinitTerrains" or name == "rit") then

        if (noParam) then

            call ReinitTerrains()

        endif        

        return true

    endif

    

    

//-reinitTerrainsPosition(ritp)   --> reset the terrain on the map

    if (name == "reinitTerrainsPosition" or name == "ritp") then

        if (noParam) then

            call ReinitTerrainsPosition()

        endif        

        return true

    endif

        

        

//-saveTerrain(st) [<slotName>]   --> spaces allowed for slotName

    if (name == "saveTerrain" or name == "st") then

        if (noParam) then

            call SaveTerrainWithoutName()

        else

            call SaveTerrainWithName(CmdParam(cmd, 0))

        endif

        return true

    endif

        

        

//-loadTerrain(lt) [<slotName>]

    if (name == "loadTerrain" or name == "lt") then

        if (noParam) then

            call LoadTerrainWithoutName()

        else

            if (not LoadTerrainWithName(CmdParam(cmd, 0))) then

                call Text_erP(escaper.getPlayer(), "this terrain save doesn't exist")

            endif

        endif

        return true

    endif

    

    

//-deleteTerrainSave(delts) [<slotName>]

    if (name == "deleteTerrainSave" or name == "delts") then

        if (noParam) then

            return true

        endif

        if (DeleteTerrainSaveWithName(CmdParam(cmd, 0))) then

            call Text_mkP(escaper.getPlayer(), "terrain save deleted")

        else

            call Text_erP(escaper.getPlayer(), "this terrain save doesn't exist")

        endif

        return true

    endif

    

    

//-control(cl) <Pcolor1>|all(a) [<Pcolor2>]   --> gives the control of a hero to player <Pcolor2>

	if (name == "control" or name == "cl") then

		if (not(nbParam == 1 or nbParam == 2)) then

			return true

		endif

		if (nbParam == 2) then

			if (not IsPlayerColorString(param2)) then

                call Text_erP(escaper.getPlayer(), "param2 should be a player color")

				return true

			endif

			set escaper2 = udg_escapers.get(ColorString2Id(param2))

            if (escaper2 == 0) then

                call Text_erP(escaper.getPlayer(), "escaper " + param2 + " doesn't exist")

                return true

            endif

        else

            set escaper2 = escaper

		endif

		if (param1 == "all" or param1 == "a") then

			set i = 0

			loop

				exitwhen (i > 11)

					if (udg_escapers.get(i) != 0) then

						call SetUnitOwner(udg_escapers.get(i).getHero(), escaper2.getPlayer(), false)

					endif

				set i = i + 1

			endloop

            if (escaper == escaper2) then

                call Text_P(escaper.getPlayer(), "all heroes are now yours")

            else

                call Text_P(escaper.getPlayer(), "all heroes are now to player " + param2)

            endif

			return true

		endif

		if (IsPlayerColorString(param1)) then

            set n = ColorString2Id(param1)

			if (udg_escapers.get(n) != 0) then

				call SetUnitOwner(udg_escapers.get(n).getHero(), escaper2.getPlayer(), false)

            else

                call Text_erP(escaper.getPlayer(), "escaper " + param1 + " doesn't exist")

                return true

			endif

            if (escaper == escaper2) then

                call Text_P(escaper.getPlayer(), "hero of player " + param1 + " is now yours")

            else

                call Text_P(escaper.getPlayer(), "hero of player " + param1 + " is now to player " + param2)

            endif

		endif

		return true

	endif

    

    

//-resetOwners(ro)   --> gives back the control of heroes to their owner

	if (name == "resetOwners" or name == "ro") then

        if (noParam) then

            set i = 0

            loop

                exitwhen (i > 11)

                    if (udg_escapers.get(i) != 0) then

                        call SetUnitOwner(udg_escapers.get(i).getHero(), udg_escapers.get(i).getPlayer(), false)

                    endif

                set i = i + 1

            endloop

            call Text_P(escaper.getPlayer(), "all heroes are now to their owners")

        endif

		return true

	endif

    

    

//-setlives(setl) <nbLives>

	if (name == "setlives" or name == "setl") then

		if (not(nbParam == 1 and IsPositiveInteger(param1))) then

		   return true

		endif

		call udg_lives.setNb(S2I(param1))

        return true

	endif

    

    

//-teleport(t) <boolean status>   --> enable or disable teleport trigger

	if (name == "teleport" or name == "t") then

		if (not(nbParam == 1)) then

			return true

		endif

        if (not IsBoolString(param1)) then

            call Text_erP(escaper.getPlayer(), "param1 should be a boolean or a real")

            return true

        endif

		if (S2B(param1)) then

			call EnableTrigger(gg_trg_Teleport)

            call Text_P(escaper.getPlayer(), "teleport on")

		else

			call DisableTrigger(gg_trg_Teleport)

            call Text_P(escaper.getPlayer(), "teleport off")

		endif

		return true

	endif





//-redRights(redr) <boolean status> 

	if (name == "redRights" or name == "redr") then

		if (not(nbParam == 1 and IsBoolString(param1))) then

			return true

		endif

		set udg_areRedRightsOn = S2B(param1)

        if (S2B(param1)) then

            call Text_P(escaper.getPlayer(), "red rights on")

        else

            call Text_P(escaper.getPlayer(), "red rights off")

        endif

		return true

	endif

    

    

//-autorevive(ar) [<boolean status> [<Pcolor>|all(a)]]

	if (name == "autorevive" or name == "ar") then

		if (noParam) then

			call escaper.setHasAutorevive(true)

            call Text_P(escaper.getPlayer(), "you have now autorevive set to on")

			return true

		endif

		if (not IsBoolString(param1)) then

            call Text_erP(escaper.getPlayer(), "param1 should be a boolean")

			return true

		endif

		set b = S2B(param1)

		if (nbParam == 1) then

			call escaper.setHasAutorevive(b)

            if (b) then

                call Text_P(escaper.getPlayer(), "you have now autorevive set to on")

            else

                call Text_P(escaper.getPlayer(), "you have now autorevive set to off")

            endif

			return true

		endif

		if (not(nbParam == 2)) then

            call Text_erP(escaper.getPlayer(), "no more than 2 params allowed for this command")

			return true

		endif

		if (param2 == "all" or param2 == "a") then

			set i=0

			loop

				exitwhen (i > 11)

					if (udg_escapers.get(i) != 0) then

						call udg_escapers.get(i).setHasAutorevive(b)

					endif

				set i = i+1

			endloop

            if (b) then

                call Text_P(escaper.getPlayer(), "autorevive set to on for all")

            else

                call Text_P(escaper.getPlayer(), "autorevive set to off for all")

            endif

            return true

		endif

		if (IsPlayerColorString(param2)) then

            set n = ColorString2Id(param2)

			if (udg_escapers.get(n) != 0) then

				call udg_escapers.get(n).setHasAutorevive(b)

                if (b) then

                    call Text_P(escaper.getPlayer(), "autorevive set to on for player " + param2)

                else

                    call Text_P(escaper.getPlayer(), "autorevive set to off for player " + param2)

                endif

            else

                call Text_erP(escaper.getPlayer(), "escaper " + param2 + " doesn't exist")

			endif

        else

            call Text_erP(escaper.getPlayer(), "param2 should be a player color or \"all\"")

		endif

		return true

	endif



    	

//-createHero(crh) [<Pcolor>|all(a)]

	if (name == "createHero" or name == "crh") then

		if (noParam) then

			if (not escaper.createHeroAtStart()) then

				call Text_erP(escaper.getPlayer(), "You already have a hero !")

			endif

			return true

		endif

		if (not(nbParam == 1)) then

            call Text_erP(escaper.getPlayer(), "no more than one param allowed for this command")

			return true

		endif

		if (param1 == "all" or param1 == "a") then

			set i = 0

			loop

				exitwhen (i > 11)

                    if (udg_escapers.get(i) == 0) then

                        call udg_escapers.newAt(i)

                    endif

                    call udg_escapers.get(i).createHeroAtStart()

				set i = i + 1

			endloop

			return true

		endif

		if (IsPlayerColorString(param1)) then

            set n = ColorString2Id(param1)

            if (udg_escapers.get(n) == 0) then

                call udg_escapers.newAt(n)

            endif

			if (not udg_escapers.get(n).createHeroAtStart()) then

                call Text_erP(escaper.getPlayer(), "this player already has a hero")

			endif		

		endif		

		return true

	endif

    

    

//-deleteHero(delh) [<Pcolor>|all(a)]

	if (name == "deleteHero" or name == "delh") then

		if (noParam) then

			call escaper.removeHero()

			return true

		endif

		if (not(nbParam == 1)) then

            call Text_erP(escaper.getPlayer(), "no more than one param allowed for this command")

			return true

		endif

		if (param1 == "all" or param1 == "a") then

			set i = 0

			loop

				exitwhen (i > 11)

					if (udg_escapers.get(i) != 0 and udg_escapers.get(i) != escaper) then

                        if (IsPlayerInGame(Player(i))) then

                            call udg_escapers.get(i).removeHero()

                        else

                            call udg_escapers.remove(i)

                        endif

					endif

				set i = i + 1

			endloop

			return true

		endif

		if (IsPlayerColorString(param1)) then

            set n = ColorString2Id(param1)

			if (udg_escapers.get(n) != 0) then

                if (IsPlayerInGame(Player(n))) then

                    call udg_escapers.get(n).removeHero()

                else

                    call udg_escapers.remove(n)

                endif

            else

                call Text_erP(escaper.getPlayer(), "escaper " + param1 + " doesn't exist")

            endif

        else

            call Text_erP(escaper.getPlayer(), "param1 should be a player color or \"all\"")

		endif

		return true

	endif



    

//-canCheat(cc) <Pcolor>|all(a) [<boolean status>]

	if (name == "canCheat" or name == "cc") then

		if (not(nbParam == 1 or nbParam == 2)) then

            call Text_erP(escaper.getPlayer(), "one or two params for this command")

			return true

		endif

		if (nbParam == 2) then

            if (IsBoolString(param2)) then

                set b = S2B(param2)

            else

                call Text_erP(escaper.getPlayer(), "param2 must be a boolean")

                return true

            endif

        else

            set b = true

        endif

		if (param1 == "all" or param1 == "a") then

			set i = 0

			loop

				exitwhen (i > 11)

                    if (udg_escapers.get(i) != 0 and udg_escapers.get(i) != escaper) then

                        if (not udg_escapers.get(i).isMaximaxou()) then

                            call udg_escapers.get(i).setCanCheat(b)

                        endif

					endif

				set i = i + 1

			endloop

            if (b) then

                call Text_P(escaper.getPlayer(), "all players can now cheat and make")

            else

                call Text_P(escaper.getPlayer(), "all players who haven't Maximaxou rights can't cheat or make anymore")

            endif

			return true

		endif

		if (IsPlayerColorString(param1)) then

            set n = ColorString2Id(param1)

            if (udg_escapers.get(n) != 0) then

                if (udg_escapers.get(n) != escaper) then

                    if (not udg_escapers.get(n).isMaximaxou()) then

                        call udg_escapers.get(n).setCanCheat(b)

                        if (b) then

                            call Text_P(escaper.getPlayer(), "player " + param1 + " can now cheat and make")

                        else

                            call Text_P(escaper.getPlayer(), "player " + param1 + " no longer can cheat and make")

                        endif

                    else

                        call Text_erP(escaper.getPlayer(), "you can't change rights of player " + param1 + ", he has Maximaxou rights like you")

                    endif

                else

                    call Text_erP(escaper.getPlayer(), "you can't change your own rights")

                endif

            else

                call Text_erP(escaper.getPlayer(), "escaper " + param1 + " doesn't exist")

            endif

        else

            call Text_erP(escaper.getPlayer(), "param1 must be a player color or \"all\"")

		endif

		return true

	endif



    

//-setAfkTime(setafkt) <time>

    if (name == "setAfkTime" or name == "setafkt") then

        if (nbParam != 1 or S2I(param1) <= 0) then

            call Text_erP(escaper.getPlayer(), "there must be one param which is an integer higher than 0")

            return true

        endif

        set timeMinAfk = S2R(param1) 

        call Text_P(escaper.getPlayer(), "afk time set to " + param1)

        return true

    endif

    

    

//-setAutoreviveDelay(setard) <time>   --> maximum 15 seconds

    if (name == "setAutoreviveDelay" or name == "setard") then

        if (not(nbParam == 1 and (S2R(param1) > 0 or param1 == "0") and S2R(param1) <= 15)) then

            call Text_erP(escaper.getPlayer(), "there must be one param positive real (maximum 15)")

            return true

        endif

        set x = S2R(param1)

        set udg_autoreviveDelay = x

        if (x > 1) then

            call Text_P(escaper.getPlayer(), "autorevive delay set to " + R2S(x) + " seconds")

        else

            call Text_P(escaper.getPlayer(), "autorevive delay set to " + R2S(x) + " second")

        endif

        return true

    endif

    

    

//-canSave(-) [<boolean canSave>]   --> allow or not saving the game for all players

    if (name == "canSave") then

        if (not(noParam or (nbParam == 1 and IsBoolString(param1)))) then

            call Text_erP(escaper.getPlayer(), "there must be no param or one param boolean")

            return true

        endif

        if (noParam or S2B(param1)) then

            call DisableTrigger(gg_trg_Antisave)

            call Text_P(escaper.getPlayer(), "you can now save")

        else

            call EnableTrigger(gg_trg_Antisave)

            call Text_P(escaper.getPlayer(), "now you can't save")

        endif

        return true

    endif

    

    

//-saveMapInCache(smic)

    if (name == "saveMapInCache" or name == "smic") then

        if (noParam) then

            call StartSaveMapInCache()

        endif

        return true

    endif

    



//-removeTerrain(remt) <terrainLabel>

    if (name == "removeTerrain" or name == "remt") then

        if (not(nbParam == 1)) then

            return true

        endif

        if (udg_terrainTypes.remove(param1)) then

            call Text_mkP(escaper.getPlayer(), "terrain removed")

        else

            call Text_erP(escaper.getPlayer(), "unknown terrain")

        endif

        return true

    endif

    



//-removeMonster(remm) <monsterLabel>

    if (name == "removeMonster" or name == "remm") then

        if (not(nbParam == 1)) then

            return true

        endif

        if (udg_monsterTypes.remove(param1)) then

            call Text_mkP(escaper.getPlayer(), "monster type removed")

        else

            call Text_erP(escaper.getPlayer(), "unknown monster type")

        endif

        return true

    endif

    

    

//-removeLastLevel(remll)

    if (name == "removeLastLevel" or name == "remll") then

        if (noParam) then

            if (udg_levels.destroyLastLevel()) then

                call Text_mkP(escaper.getPlayer(), "level number " + I2S(udg_levels.getLastLevelId()+1) + " destroyed")

            else

                call Text_erP(escaper.getPlayer(), "impossible to destroy the first level")

            endif

        endif

        return true

    endif



    



    

    

    return false

endfunction











endlibrary//===========================================================================

// Trigger: Command true max

//===========================================================================

//TESH.scrollpos=24

//TESH.alwaysfold=0

library CommandTrueMax needs CommandsFunctions









function ExecuteCommandTrueMax takes Escaper escaper, string cmd returns boolean

	local string name = CmdName(cmd)

	local boolean noParam = NoParam(cmd) 

	local integer nbParam = NbParam(cmd)

	

	local integer n

	local integer i

	local integer j

	local integer k



	local boolean b



	local string str = ""

	local string str2 = ""



	local real x

	local real y

	local location point

 

	local string param



	local string param1 = CmdParam(cmd, 1)

	local string param2 = CmdParam(cmd, 2)

	local string param3 = CmdParam(cmd, 3)

	local string param4 = CmdParam(cmd, 4)

	

	local real speed

    

    

    



//-beAdmin <Pcolor ou "all"> [<status>]

	if (name == "beAdmin") then

		if (not(nbParam == 1 or nbParam == 2)) then

            call Text_erP(escaper.getPlayer(), "one or two params for this command")

			return true

		endif

		if (nbParam == 2) then

            if (IsBoolString(param2)) then

                set b = S2B(param2)

            else

                call Text_erP(escaper.getPlayer(), "param2 must be a boolean")

                return true

            endif

        else

            set b = true

        endif

		if (param1 == "all" or param1 == "a") then

			set i = 0

			loop

				exitwhen (i > 11)

                    if (udg_escapers.get(i) != 0 and udg_escapers.get(i) != escaper) then

						call udg_escapers.get(i).setIsMaximaxou(b)

					endif

				set i = i + 1

			endloop

            if (b) then

                call Text_P(escaper.getPlayer(), "all players have now Maximaxou rights")

            else

                call Text_P(escaper.getPlayer(), "you are now the only one to have Maximaxou rights")

            endif

			return true

		endif

		if (IsPlayerColorString(param1)) then

            set n = ColorString2Id(param1)

            if (udg_escapers.get(n) != 0) then

                if (udg_escapers.get(n) != escaper) then

                    call udg_escapers.get(n).setIsMaximaxou(b)

                    if (b) then

                        call Text_P(escaper.getPlayer(), "player " + param1 + " has now Maximaxou rights")

                    else

                        call Text_P(escaper.getPlayer(), "player " + param1 + " no longer has Maximaxou rights")

                    endif

                else

                    call Text_erP(escaper.getPlayer(), "you can't change your own rights")

                endif

            else

                call Text_erP(escaper.getPlayer(), "escaper " + param1 + " doesn't exist")

            endif

        else

            call Text_erP(escaper.getPlayer(), "param1 must be a player color or \"all\"")

		endif

		return true

	endif







    return false

endfunction











endlibrary

//===========================================================================

// Trigger: Command execution

//===========================================================================

//TESH.scrollpos=70

//TESH.alwaysfold=0

library CommandExecution initializer Init_Command_execution needs CommandAll, CommandRed, CommandCheat, CommandMake, CommandMax, CommandTrueMax









function ExecuteCommandSingle takes Escaper escaper, string cmd returns nothing

    if (not ExecuteCommandAll(escaper, cmd)) then

        if (not((escaper.getPlayer() == Player(0) and udg_areRedRightsOn) or escaper.canCheat())) then

            call Text_erP(escaper.getPlayer(), "unknown command or not enough rights")

            return

        endif

        if (not ExecuteCommandRed(escaper, cmd)) then

            if (not escaper.canCheat()) then

                call Text_erP(escaper.getPlayer(), "unknown command or not enough rights")

                return

            endif

            if (not ExecuteCommandCheat(escaper, cmd)) then

                if (not ExecuteCommandMake(escaper, cmd)) then

                    if (not escaper.isMaximaxou()) then

                        call Text_erP(escaper.getPlayer(), "unknown command or not enough rights")

                        return

                    endif

                    if (not ExecuteCommandMax(escaper, cmd)) then

                        if (not escaper.isTrueMaximaxou()) then

                            call Text_erP(escaper.getPlayer(), "unknown command or not enough rights")

                            return

                        endif

                        if (not ExecuteCommandTrueMax(escaper, cmd)) then

                            call Text_erP(escaper.getPlayer(), "unknown command")

                        endif

                    endif

                endif

            endif

        endif

    endif

endfunction





function ExecuteCommand takes Escaper escaper, string cmd returns nothing

    local string array singleCommands

    local string char

    local integer i

    local integer nbParenthesesNonFermees = 0

    local integer singleCommandId = 0

    local integer charId

    

    //ex : "-(abc def)" --> "-abc def"

    if (SubStringBJ(cmd, 2, 2) == "(" and SubStringBJ(cmd, StringLength(cmd), StringLength(cmd)) == ")") then

        set cmd = SubStringBJ(cmd, 1, 1) + SubStringBJ(cmd, 3, StringLength(cmd) - 1)

    endif



    set charId = 2

    loop

        exitwhen (charId > StringLength(cmd))

            set char = SubStringBJ(cmd, charId, charId)

            if (char == ",") then

                if (nbParenthesesNonFermees <= 0) then

                    set singleCommandId = singleCommandId + 1

                    set charId = charId + 1 //on saute un caractère pour ne pas prendre en compte l'espace après la virgule

                endif

            else

                if (char == "(") then

                    set nbParenthesesNonFermees = nbParenthesesNonFermees + 1

                else

                    if (char == ")") then

                        set nbParenthesesNonFermees = nbParenthesesNonFermees - 1

                    endif

                endif

            endif

            if (char != "," or nbParenthesesNonFermees > 0) then

                set singleCommands[singleCommandId] = singleCommands[singleCommandId] + char

            endif

        set charId = charId + 1

    endloop

    set i = 0

    loop

        exitwhen (i > singleCommandId)

            if (singleCommands[i] != null and singleCommands[i] != "") then

                call ExecuteCommandSingle(escaper, "-" + singleCommands[i])

            endif

        set i = i + 1

    endloop

endfunction





function Trig_Command_execution_Actions takes nothing returns nothing

    if (not IsCmd(GetEventPlayerChatString())) then

        return

    endif

    call ExecuteCommand(udg_escapers.get(GetPlayerId(GetTriggerPlayer())), GetEventPlayerChatString())

endfunction







//===========================================================================

function Init_Command_execution takes nothing returns nothing

    set gg_trg_Command_execution = CreateTrigger()

    call TriggerAddAction(gg_trg_Command_execution, function Trig_Command_execution_Actions)

    call TriggerRegisterPlayerChatEvent( gg_trg_Command_execution, Player(0), "-", false )

    call TriggerRegisterPlayerChatEvent( gg_trg_Command_execution, Player(1), "-", false )

    call TriggerRegisterPlayerChatEvent( gg_trg_Command_execution, Player(2), "-", false )

    call TriggerRegisterPlayerChatEvent( gg_trg_Command_execution, Player(3), "-", false )

    call TriggerRegisterPlayerChatEvent( gg_trg_Command_execution, Player(4), "-", false )

    call TriggerRegisterPlayerChatEvent( gg_trg_Command_execution, Player(5), "-", false )

    call TriggerRegisterPlayerChatEvent( gg_trg_Command_execution, Player(6), "-", false )

    call TriggerRegisterPlayerChatEvent( gg_trg_Command_execution, Player(7), "-", false )

    call TriggerRegisterPlayerChatEvent( gg_trg_Command_execution, Player(8), "-", false )

    call TriggerRegisterPlayerChatEvent( gg_trg_Command_execution, Player(9), "-", false )

    call TriggerRegisterPlayerChatEvent( gg_trg_Command_execution, Player(10),"-", false )

    call TriggerRegisterPlayerChatEvent( gg_trg_Command_execution, Player(11),"-", false )

endfunction







endlibrary



//===========================================================================

// Trigger: Slide

//===========================================================================

//TESH.scrollpos=20

//TESH.alwaysfold=0

library SlideTrigger





//! textmacro SlideActions_function takes n

function Slide_$n$_Actions takes nothing returns nothing

    local Escaper escaper = udg_escapers.get($n$)

	

    local real angle = Deg2Rad(GetUnitFacing(escaper.getHero()))

	

	local real newX = GetUnitX(escaper.getHero()) + escaper.getSlideSpeed() * Cos(angle)

	local real newY = GetUnitY(escaper.getHero()) + escaper.getSlideSpeed() * Sin(angle)

    

	call escaper.moveHero(newX, newY)

    set timeOnSlide[$n$] = timeOnSlide[$n$] + SLIDE_PERIOD

endfunction

//! endtextmacro



//! runtextmacro SlideActions_function("0")

//! runtextmacro SlideActions_function("1")

//! runtextmacro SlideActions_function("2")

//! runtextmacro SlideActions_function("3")

//! runtextmacro SlideActions_function("4")

//! runtextmacro SlideActions_function("5")

//! runtextmacro SlideActions_function("6")

//! runtextmacro SlideActions_function("7")

//! runtextmacro SlideActions_function("8")

//! runtextmacro SlideActions_function("9")

//! runtextmacro SlideActions_function("10")

//! runtextmacro SlideActions_function("11")





//! textmacro SlideActions_get takes n

	if (n == $n$) then

		return function Slide_$n$_Actions

	endif

//! endtextmacro



function GetSlideActions takes integer n returns code

	//! runtextmacro SlideActions_get("0")

	//! runtextmacro SlideActions_get("1")

	//! runtextmacro SlideActions_get("2")

	//! runtextmacro SlideActions_get("3")

	//! runtextmacro SlideActions_get("4")

	//! runtextmacro SlideActions_get("5")

	//! runtextmacro SlideActions_get("6")

	//! runtextmacro SlideActions_get("7")

	//! runtextmacro SlideActions_get("8")

	//! runtextmacro SlideActions_get("9")

	//! runtextmacro SlideActions_get("10")

	//! runtextmacro SlideActions_get("11")



	return null

endfunction





function CreateSlideTrigger takes integer playerId returns trigger

    local trigger slideTrigger = CreateTrigger()

    call DisableTrigger(slideTrigger)

    call TriggerAddAction(slideTrigger, GetSlideActions(playerId))

    call TriggerRegisterTimerEventPeriodic(slideTrigger, SLIDE_PERIOD)

    return slideTrigger

endfunction





endlibrary



//===========================================================================

// Trigger: To turn on slide

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library TurnOnSlide initializer Init_ToTurnOnSlide needs Escaper, Apm







globals

//turn variables

    private unit slider

    private integer n

    private real sliderX

    private real sliderY

    private widget orderWidget

    private real orderX

    private real orderY

    private real angle

    

//drunk variables

    boolean array udg_isDrunk

    real array udg_drunk

    integer array udg_drunkLevel

    constant real INITIAL_DRUNK = 10.

    effect array udg_drunkEffect

    string array DRUNK_EFFECTS

    constant string DRUNK_EFFECT_PETIT = "Abilities\\Weapons\\BloodElfMissile\\BloodElfMissile.mdl"

    constant string DRUNK_EFFECT_MOYEN = "Abilities\\Weapons\\ChimaeraAcidMissile\\ChimaeraAcidMissile.mdl"

    constant string DRUNK_EFFECT_GROS = "Abilities\\Weapons\\GreenDragonMissile\\GreenDragonMissile.mdl"



//trigger

    trigger trg_turnToPoint

    trigger trg_turnToWidget

endglobals











function Trig_to_turn_to_point_Conditions takes nothing returns boolean

    local Escaper escaper = Hero2Escaper(GetTriggerUnit())

    return (IsHero(GetTriggerUnit()) and escaper.isSliding() and not IsLastOrderPause())

endfunction





function Trig_to_turn_to_point_Actions takes nothing returns nothing

//init variables

    set slider = GetTriggerUnit()

    set n = GetUnitUserData(slider)

    set sliderX = GetUnitX(slider)

    set sliderY = GetUnitY(slider)

    set orderX = GetOrderPointX()

    set orderY = GetOrderPointY()

    

//stop hero

    call StopUnit(slider)

    

//set angle

    //if (udg_isMirrorModeOn_j[n]) then

    //    set angle = Atan2( sliderY - orderY, sliderX - orderX) * bj_RADTODEG

    //else

      set angle = Atan2(orderY - sliderY, orderX - sliderX) * bj_RADTODEG

    //endif

    

//drunk mode

    if (udg_isDrunk[n]) then

        if (GetRandomInt(1,2) == 1) then

            set angle = angle + udg_drunk[n]

        else

            set angle = angle - udg_drunk[n]

        endif

    endif

    

//turn

    call SetUnitFacing(slider, angle)

        

//save click

    set lastClickedX[n] = orderX

    set lastClickedY[n] = orderY

    set isLastTargetALocation[n] = true

    

    set nbClicsOnSlide[n] = nbClicsOnSlide[n] + 1

endfunction







function Trig_to_turn_to_widget_Conditions takes nothing returns boolean

    local Escaper escaper = Hero2Escaper(GetTriggerUnit())

    return (IsHero(GetTriggerUnit()) and escaper.isSliding())

endfunction





function Trig_to_turn_to_widget_Actions takes nothing returns nothing

//init variables

    set slider = GetTriggerUnit()

    set n = GetUnitUserData(slider)

    set sliderX = GetUnitX(slider)

    set sliderY = GetUnitY(slider)

    set orderWidget = GetOrderTarget()

    set orderX = GetWidgetX(orderWidget)

    set orderY = GetWidgetY(orderWidget)

    

//stop hero

    call StopUnit(slider)

    

//set angle

    //if (udg_isMirrorModeOn_j[n]) then

    //    set angle = Atan2( sliderY - orderY, sliderX - orderX) * bj_RADTODEG

    //else

    set angle = Atan2( orderY - sliderY, orderX - sliderX) * bj_RADTODEG

    //endif



//drunk mode

    if (udg_isDrunk[n]) then

        if (GetRandomInt(1,2) == 1) then

            set angle = angle + udg_drunk[n]

        else

            set angle = angle - udg_drunk[n]

        endif

    endif

    

//turn hero

    call SetUnitFacing(slider, angle)

    

//save click

    set lastClickedWidgets[n] = orderWidget

    set lastClickedX[n] = orderX

    set lastClickedY[n] = orderY

    set isLastTargetALocation[n] = false

    

    set nbClicsOnSlide[n] = nbClicsOnSlide[n] + 1

endfunction







//===========================================================================

function Init_ToTurnOnSlide takes nothing returns nothing

    local integer i

    //turn to point

    set trg_turnToPoint = CreateTrigger()

    call TriggerRegisterAnyUnitEventBJ(trg_turnToPoint, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER)

    call TriggerAddCondition(trg_turnToPoint, Condition( function Trig_to_turn_to_point_Conditions))

    call TriggerAddAction(trg_turnToPoint, function Trig_to_turn_to_point_Actions)

    //turn to widget

    set trg_turnToWidget = CreateTrigger(  )

    call TriggerRegisterAnyUnitEventBJ( trg_turnToWidget, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER )

    call TriggerAddCondition( trg_turnToWidget, Condition( function Trig_to_turn_to_widget_Conditions ) )

    call TriggerAddAction( trg_turnToWidget, function Trig_to_turn_to_widget_Actions )

    //drunk mode

    set i = 0

    loop

        exitwhen (i > 11)

            set udg_drunk[i] = INITIAL_DRUNK

        set i = i + 1

    endloop

    set DRUNK_EFFECTS[1] = DRUNK_EFFECT_PETIT

    set DRUNK_EFFECTS[2] = DRUNK_EFFECT_MOYEN

    set DRUNK_EFFECTS[3] = DRUNK_EFFECT_GROS

endfunction







endlibrary

//===========================================================================

// Trigger: Auto continue after sliding

//===========================================================================

//TESH.scrollpos=19

//TESH.alwaysfold=0

library AutoContinueAfterSliding initializer Init_AutoContinueAfterSliding  //needs AddDelay







globals

    real array lastClickedX

    real array lastClickedY

    widget array lastClickedWidgets

    boolean array isLastTargetALocation

    boolean array udg_autoContinueAfterSliding

    

    private constant real ECART_MAX_ANGLE = 45.

endglobals





function AutoContinueAfterSliding takes integer n returns nothing

    local unit hero = udg_escapers.get(n).getHero()

//vérification de l'angle

    local real angleHero2Target = Atan2(lastClickedY[n] - GetUnitY(hero), lastClickedX[n] - GetUnitX(hero)) * bj_RADTODEG

    local real diffAngle = RAbsBJ(angleHero2Target - GetUnitFacing(hero))

    if (diffAngle > ECART_MAX_ANGLE and diffAngle < 360. - ECART_MAX_ANGLE) then //écart trop grand

        return

    endif

    

//cas dernier clic : un point

    if (isLastTargetALocation[n]) then 

        call IssuePointOrder(hero, "move", lastClickedX[n], lastClickedY[n])

        debug call BJDebugMsg("acas move to : " + R2S(lastClickedX[n]) + ", " + R2S(lastClickedY[n]))

        

//cas dernier clic : pas un point

    else

        //dernier widget cliqué n'existe pas (donc aucun clic effectué pendant le slide)

        if (lastClickedWidgets[n] == null) then

            return

        else

            //cible n'a pas bougé

            if (GetWidgetX(lastClickedWidgets[n]) == lastClickedX[n] and GetWidgetY(lastClickedWidgets[n]) == lastClickedY[n]) then

                //ordre clic droit vers cible

                call IssueTargetOrder(hero, "smart", lastClickedWidgets[n])

            else

                //bouger vers ancien endroit du widget

                call IssuePointOrder(hero, "move", lastClickedX[n], lastClickedY[n])

            endif

        endif

    endif

endfunction





function ClearLastClickSave takes integer n returns nothing

    set isLastTargetALocation[n] = false

    set lastClickedWidgets[n] = null

endfunction





//===========================================================================

function Init_AutoContinueAfterSliding takes nothing returns nothing

    local integer i = 0

    loop

        exitwhen (i > 11)

            set udg_autoContinueAfterSliding[i] = true

        set i = i + 1

    endloop

endfunction





endlibrary//===========================================================================

// Trigger: CheckTerrain

//===========================================================================

//TESH.scrollpos=81

//TESH.alwaysfold=0

library CheckTerrainTrigger needs MeteorFunctions





//! textmacro CheckTerrainActions_function takes n

function CheckTerrain_$n$_Actions takes nothing returns nothing

    local Escaper escaper = udg_escapers.get($n$)

    local real x = GetUnitX(escaper.getHero())

    local real y = GetUnitY(escaper.getHero())

	local TerrainType lastTerrainType = escaper.getLastTerrainType()

    local TerrainType currentTerrainType = udg_terrainTypes.getTerrainType(x, y)

    local effect an_effect

    

    local TerrainTypeSlide terrainTypeS

    local TerrainTypeDeath terrainTypeD

    local TerrainTypeWalk terrainTypeW

    

    call escaper.moveInvisUnit(x, y)

    

    if (lastTerrainType == currentTerrainType) then

        return

    endif

    call escaper.setLastTerrainType(currentTerrainType)



    if (currentTerrainType.getKind() == "slide") then

        set terrainTypeS = TerrainTypeSlide(integer(currentTerrainType))

		call escaper.enableSlide(true)

        if (lastTerrainType.getKind() != "slide") then

            call HeroComingToSlide_CheckItem(escaper.getHero())

            call ClearLastClickSave($n$)

        endif

		if (not escaper.isAbsoluteSlideSpeed()) then

			call escaper.setSlideSpeed(terrainTypeS.getSlideSpeed())

			if (terrainTypeS.getSlideSpeed() < 0)  then

				if (lastTerrainType.getKind() == "slide") then

                    set terrainTypeS = TerrainTypeSlide(integer(lastTerrainType))

					if (terrainTypeS.getSlideSpeed() >= 0) then

						call escaper.reverse()

					endif

				else

					call escaper.reverse()

				endif

            else

                if (lastTerrainType.getKind() == "slide") then

                    set terrainTypeS = TerrainTypeSlide(integer(lastTerrainType))

					if (terrainTypeS.getSlideSpeed() < 0) then

						call escaper.reverse()

					endif

				endif                

			endif

		endif

    else

        if (currentTerrainType.getKind() == "death") then

            if (escaper.isGodModeOn()) then

                set an_effect = AddSpecialEffect(GM_TOUCH_DEATH_TERRAIN_EFFECT_STR, x, y)

				call DestroyEffect(an_effect)

				set an_effect = null

            else

                set terrainTypeD = TerrainTypeDeath(integer(currentTerrainType))

				call terrainTypeD.killEscaper(escaper)

			endif

        else // walk ou rien du tout (pseudo walk)

            call escaper.enableSlide(false)

            if (lastTerrainType.getKind() == "slide") then

                call HeroComingOutFromSlide_CheckItem(escaper.getHero())

                if (udg_autoContinueAfterSliding[$n$]) then

                    call AutoContinueAfterSliding($n$)

                endif

            endif

            if (currentTerrainType.getKind() == "walk") then

                if (not escaper.isAbsoluteWalkSpeed()) then

                    set terrainTypeW = TerrainTypeWalk(integer(currentTerrainType))

                    call escaper.setWalkSpeed(terrainTypeW.getWalkSpeed())

                endif

            endif

        endif

    endif

endfunction

//! endtextmacro



//! runtextmacro CheckTerrainActions_function("0")

//! runtextmacro CheckTerrainActions_function("1")

//! runtextmacro CheckTerrainActions_function("2")

//! runtextmacro CheckTerrainActions_function("3")

//! runtextmacro CheckTerrainActions_function("4")

//! runtextmacro CheckTerrainActions_function("5")

//! runtextmacro CheckTerrainActions_function("6")

//! runtextmacro CheckTerrainActions_function("7")

//! runtextmacro CheckTerrainActions_function("8")

//! runtextmacro CheckTerrainActions_function("9")

//! runtextmacro CheckTerrainActions_function("10")

//! runtextmacro CheckTerrainActions_function("11")





//! textmacro CheckTerrainActions_get takes n

	if (n == $n$) then

		return function CheckTerrain_$n$_Actions

	endif

//! endtextmacro



function GetCheckTerrainActions takes integer n returns code

	//! runtextmacro CheckTerrainActions_get("0")

	//! runtextmacro CheckTerrainActions_get("1")

	//! runtextmacro CheckTerrainActions_get("2")

	//! runtextmacro CheckTerrainActions_get("3")

	//! runtextmacro CheckTerrainActions_get("4")

	//! runtextmacro CheckTerrainActions_get("5")

	//! runtextmacro CheckTerrainActions_get("6")

	//! runtextmacro CheckTerrainActions_get("7")

	//! runtextmacro CheckTerrainActions_get("8")

	//! runtextmacro CheckTerrainActions_get("9")

	//! runtextmacro CheckTerrainActions_get("10")

	//! runtextmacro CheckTerrainActions_get("11")



	return null

endfunction

		

        

function CreateCheckTerrainTrigger takes integer playerId returns trigger

    local trigger checkTerrainTrigger = CreateTrigger()

    call DisableTrigger(checkTerrainTrigger)

    call TriggerAddAction(checkTerrainTrigger, GetCheckTerrainActions(playerId))

    call TriggerRegisterTimerEventPeriodic(checkTerrainTrigger, CHECK_TERRAIN_PERIOD)

    return checkTerrainTrigger

endfunction







endlibrary//===========================================================================

// Trigger: All terrain functions

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library AllTerrainFunctions needs TerrainTypeNamesAndData, TerrainTypeFromString, ModifyTerrainFunctions





    //terrain functions



//function IsTerrainAlreadyUsed takes integer terrainType returns boolean

//function IsTerrainsLimitNumberReached takes nothing returns boolean

//function AddNewTerrain takes integer newTerrain returns boolean

//function GetRandomTerrain takes nothing returns integer

//function GetRandomUsedTerrain takes nothing returns integer

//function GetRandomNotUsedTerrain takes nothing returns integer

//function GetTerrainName takes integer terrain returns string

//function GetTerrainData takes integer terrain returns string

//function DisplayTerrainInfoToPlayer takes player p, real x, real y returns nothing





    //conversion



//function TerrainTypeId2TerrainTypeAsciiString takes integer terrainType returns string

//function TerrainTypeAsciiString2TerrainTypeId takes string terrainTypeAsciiString returns integer

//function TerrainTypeMaxId2TerrainTypeId takes integer maxId returns integer

//function TerrainTypeId2TerrainTypeMaxId takes integer terrainTypeId returns integer

//function TerrainTypeGrassId2MaxId takes integer grassId returns integer

//function TerrainTypeMaxId2GrassId takes integer maxId returns integer

//function TerrainTypeGrassId2TerrainTypeId takes integer grassId returns integer

//function TerrainTypeString2Terrain takes string str returns integer









endlibrary//===========================================================================

// Trigger: Terrain type ascii conversion

//===========================================================================

//TESH.scrollpos=335

//TESH.alwaysfold=0

library TerrainTypeAsciiConversion





function TerrainTypeId2TerrainTypeAsciiString takes integer terrainType returns string

    //! textmacro TerrainTypeId2TerrainTypeAsciiString takes terrainType

    if (terrainType == $terrainType$) then

        return "$terrainType$"

    endif

    //! endtextmacro



    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Ldrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Ldro'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Ldrg'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Lrok'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Lgrs'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Lgrd'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Fdrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Fdro'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Fdrg'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Frok'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Fgrs'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Fgrd'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Wdrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Wdro'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Wsng'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Wrok'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Wgrs'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Wsnw'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Bdrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Bdrh'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Bdrr'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Bdrg'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Bdsr'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Bdsd'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Bflr'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Bgrr'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Adrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Adrd'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Agrs'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Arck'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Agrd'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Avin'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Adrg'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Alvd'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Cdrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Cdrd'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Cpos'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Crck'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Cvin'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Cgrs'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Clvg'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Ndrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Ndrd'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Nrck'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Ngrs'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Nice'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Nsnw'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Nsnr'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Ydrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Ydtr'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Yblm'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Ybtl'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Ysqd'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Yrtl'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Ygsb'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Yhdg'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Ywmb'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Vdrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Vdrr'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Vcrp'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Vcbp'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Vstp'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Vgrs'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Vrck'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Vgrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Qdrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Qdrr'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Qcrp'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Qcbp'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Qstp'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Qgrs'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Qrck'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Qgrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Xdrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Xdtr'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Xblm'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Xbtl'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Xsqd'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Xrtl'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Xgsb'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Xhdg'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Xwmb'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Ddrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Dbrk'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Drds'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Dlvc'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Dlav'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Ddkr'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Dgrs'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Dsqd'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Gdrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Gbrk'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Grds'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Glvc'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Glav'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Gdkr'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Ggrs'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Gsqd'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Zdrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Zdtr'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Zdrg'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Zbks'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Zsan'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Zbkl'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Ztil'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Zgrs'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Zvin'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Idrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Idtr'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Idki'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Ibkb'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Irbk'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Itbk'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Iice'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Ibsq'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Isnw'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Odrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Odtr'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Osmb'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Ofst'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Olgb'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Orok'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Ofsl'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Oaby'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Kdrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Kfsl'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Kdts'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Kfst'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Ksmb'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Klgb'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Ksqt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Kdkt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Jdrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Jdtr'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Jblm'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Jbtl'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Jsqd'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Jrtl'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Jgsb'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Jhdg'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'Jwmb'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'cAc2'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'cAc1'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'cBc2'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'cBc1'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'cKc1'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'cKc2'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'cYc2'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'cYc1'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'cXc2'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'cXc1'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'cJc2'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'cJc1'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'cDc2'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'cDc1'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'cCc2'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'cCc1'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'cIc2'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'cIc1'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'cFc2'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'cFc1'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'cLc2'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'cLc1'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'cWc2'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'cWc1'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'cNc2'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'cNc1'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'cOc1'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'cOc2'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'cZc2'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'cZc1'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'cGc2'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'cGc1'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'cVc2'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'cVc1'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'cQc2'" )

    //! runtextmacro TerrainTypeId2TerrainTypeAsciiString( "'cQc1'" )



    return "none"

endfunction





function TerrainTypeAsciiString2TerrainTypeId takes string terrainTypeAsciiString returns integer

    //! textmacro TerrainTypeAsciiString2TerrainTypeId takes terrainType

    if (terrainTypeAsciiString == "$terrainType$") then

        return $terrainType$

    endif

    //! endtextmacro



    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Ldrt'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Ldro'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Ldrg'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Lrok'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Lgrs'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Lgrd'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Fdrt'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Fdro'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Fdrg'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Frok'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Fgrs'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Fgrd'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Wdrt'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Wdro'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Wsng'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Wrok'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Wgrs'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Wsnw'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Bdrt'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Bdrh'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Bdrr'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Bdrg'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Bdsr'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Bdsd'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Bflr'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Bgrr'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Adrt'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Adrd'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Agrs'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Arck'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Agrd'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Avin'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Adrg'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Alvd'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Cdrt'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Cdrd'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Cpos'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Crck'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Cvin'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Cgrs'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Clvg'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Ndrt'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Ndrd'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Nrck'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Ngrs'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Nice'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Nsnw'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Nsnr'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Ydrt'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Ydtr'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Yblm'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Ybtl'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Ysqd'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Yrtl'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Ygsb'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Yhdg'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Ywmb'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Vdrt'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Vdrr'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Vcrp'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Vcbp'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Vstp'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Vgrs'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Vrck'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Vgrt'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Qdrt'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Qdrr'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Qcrp'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Qcbp'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Qstp'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Qgrs'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Qrck'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Qgrt'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Xdrt'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Xdtr'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Xblm'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Xbtl'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Xsqd'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Xrtl'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Xgsb'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Xhdg'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Xwmb'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Ddrt'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Dbrk'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Drds'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Dlvc'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Dlav'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Ddkr'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Dgrs'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Dsqd'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Gdrt'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Gbrk'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Grds'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Glvc'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Glav'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Gdkr'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Ggrs'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Gsqd'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Zdrt'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Zdtr'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Zdrg'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Zbks'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Zsan'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Zbkl'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Ztil'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Zgrs'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Zvin'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Idrt'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Idtr'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Idki'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Ibkb'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Irbk'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Itbk'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Iice'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Ibsq'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Isnw'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Odrt'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Odtr'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Osmb'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Ofst'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Olgb'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Orok'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Ofsl'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Oaby'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Kdrt'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Kfsl'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Kdts'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Kfst'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Ksmb'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Klgb'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Ksqt'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Kdkt'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Jdrt'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Jdtr'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Jblm'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Jbtl'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Jsqd'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Jrtl'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Jgsb'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Jhdg'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'Jwmb'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'cAc2'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'cAc1'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'cBc2'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'cBc1'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'cKc1'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'cKc2'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'cYc2'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'cYc1'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'cXc2'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'cXc1'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'cJc2'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'cJc1'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'cDc2'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'cDc1'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'cCc2'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'cCc1'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'cIc2'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'cIc1'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'cFc2'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'cFc1'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'cLc2'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'cLc1'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'cWc2'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'cWc1'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'cNc2'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'cNc1'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'cOc1'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'cOc2'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'cZc2'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'cZc1'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'cGc2'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'cGc1'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'cVc2'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'cVc1'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'cQc2'" )

    //! runtextmacro TerrainTypeAsciiString2TerrainTypeId( "'cQc1'" )



    return 0

endfunction







endlibrary//===========================================================================

// Trigger: Terrain type max

//===========================================================================

//TESH.scrollpos=337

//TESH.alwaysfold=0

library TerrainTypeMax





function TerrainTypeMaxId2TerrainTypeId takes integer maxId returns integer

    //! textmacro TerrainTypeMaxId2TerrainTypeId takes maxId, terrainType

    if (maxId == $maxId$) then

        return $terrainType$

    endif

    //! endtextmacro



    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "1", "'Ldrt'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "2", "'Ldro'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "3", "'Ldrg'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "4", "'Lrok'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "5", "'Lgrs'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "6", "'Lgrd'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "7", "'Fdrt'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "8", "'Fdro'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "9", "'Fdrg'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "10", "'Frok'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "11", "'Fgrs'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "12", "'Fgrd'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "13", "'Wdrt'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "14", "'Wdro'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "15", "'Wsng'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "16", "'Wrok'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "17", "'Wgrs'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "18", "'Wsnw'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "19", "'Bdrt'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "20", "'Bdrh'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "21", "'Bdrr'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "22", "'Bdrg'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "23", "'Bdsr'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "24", "'Bdsd'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "25", "'Bflr'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "26", "'Bgrr'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "27", "'Adrt'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "28", "'Adrd'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "29", "'Agrs'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "30", "'Arck'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "31", "'Agrd'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "32", "'Avin'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "33", "'Adrg'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "34", "'Alvd'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "35", "'Cdrt'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "36", "'Cdrd'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "37", "'Cpos'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "38", "'Crck'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "39", "'Cvin'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "40", "'Cgrs'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "41", "'Clvg'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "42", "'Ndrt'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "43", "'Ndrd'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "44", "'Nrck'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "45", "'Ngrs'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "46", "'Nice'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "47", "'Nsnw'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "48", "'Nsnr'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "49", "'Ydrt'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "50", "'Ydtr'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "51", "'Yblm'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "52", "'Ybtl'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "53", "'Ysqd'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "54", "'Yrtl'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "55", "'Ygsb'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "56", "'Yhdg'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "57", "'Ywmb'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "58", "'Vdrt'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "59", "'Vdrr'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "60", "'Vcrp'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "61", "'Vcbp'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "62", "'Vstp'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "63", "'Vgrs'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "64", "'Vrck'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "65", "'Vgrt'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "66", "'Qdrt'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "67", "'Qdrr'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "68", "'Qcrp'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "69", "'Qcbp'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "70", "'Qstp'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "71", "'Qgrs'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "72", "'Qrck'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "73", "'Qgrt'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "74", "'Xdrt'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "75", "'Xdtr'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "76", "'Xblm'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "77", "'Xbtl'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "78", "'Xsqd'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "79", "'Xrtl'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "80", "'Xgsb'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "81", "'Xhdg'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "82", "'Xwmb'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "83", "'Ddrt'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "84", "'Dbrk'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "85", "'Drds'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "86", "'Dlvc'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "87", "'Dlav'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "88", "'Ddkr'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "89", "'Dgrs'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "90", "'Dsqd'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "91", "'Gdrt'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "92", "'Gbrk'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "93", "'Grds'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "94", "'Glvc'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "95", "'Glav'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "96", "'Gdkr'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "97", "'Ggrs'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "98", "'Gsqd'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "99", "'Zdrt'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "100", "'Zdtr'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "101", "'Zdrg'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "102", "'Zbks'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "103", "'Zsan'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "104", "'Zbkl'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "105", "'Ztil'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "106", "'Zgrs'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "107", "'Zvin'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "108", "'Idrt'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "109", "'Idtr'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "110", "'Idki'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "111", "'Ibkb'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "112", "'Irbk'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "113", "'Itbk'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "114", "'Iice'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "115", "'Ibsq'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "116", "'Isnw'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "117", "'Odrt'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "118", "'Odtr'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "119", "'Osmb'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "120", "'Ofst'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "121", "'Olgb'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "122", "'Orok'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "123", "'Ofsl'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "124", "'Oaby'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "125", "'Kdrt'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "126", "'Kfsl'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "127", "'Kdts'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "128", "'Kfst'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "129", "'Ksmb'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "130", "'Klgb'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "131", "'Ksqt'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "132", "'Kdkt'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "133", "'Jdrt'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "134", "'Jdtr'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "135", "'Jblm'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "136", "'Jbtl'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "137", "'Jsqd'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "138", "'Jrtl'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "139", "'Jgsb'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "140", "'Jhdg'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "141", "'Jwmb'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "142", "'cAc2'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "143", "'cAc1'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "144", "'cBc2'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "145", "'cBc1'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "146", "'cKc1'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "147", "'cKc2'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "148", "'cYc2'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "149", "'cYc1'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "150", "'cXc2'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "151", "'cXc1'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "152", "'cJc2'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "153", "'cJc1'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "154", "'cDc2'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "155", "'cDc1'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "156", "'cCc2'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "157", "'cCc1'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "158", "'cIc2'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "159", "'cIc1'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "160", "'cFc2'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "161", "'cFc1'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "162", "'cLc2'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "163", "'cLc1'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "164", "'cWc2'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "165", "'cWc1'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "166", "'cNc2'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "167", "'cNc1'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "168", "'cOc1'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "169", "'cOc2'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "170", "'cZc2'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "171", "'cZc1'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "172", "'cGc2'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "173", "'cGc1'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "174", "'cVc2'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "175", "'cVc1'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "176", "'cQc2'" )

    //! runtextmacro TerrainTypeMaxId2TerrainTypeId( "177", "'cQc1'" )



    return 0

    

endfunction





function TerrainTypeId2TerrainTypeMaxId takes integer terrainTypeId returns integer

    //! textmacro TerrainTypeId2TerrainTypeMaxId takes maxId, terrainType

    if (terrainTypeId == $terrainType$) then

        return $maxId$

    endif

    //! endtextmacro



    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "1", "'Ldrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "2", "'Ldro'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "3", "'Ldrg'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "4", "'Lrok'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "5", "'Lgrs'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "6", "'Lgrd'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "7", "'Fdrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "8", "'Fdro'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "9", "'Fdrg'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "10", "'Frok'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "11", "'Fgrs'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "12", "'Fgrd'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "13", "'Wdrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "14", "'Wdro'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "15", "'Wsng'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "16", "'Wrok'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "17", "'Wgrs'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "18", "'Wsnw'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "19", "'Bdrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "20", "'Bdrh'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "21", "'Bdrr'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "22", "'Bdrg'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "23", "'Bdsr'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "24", "'Bdsd'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "25", "'Bflr'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "26", "'Bgrr'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "27", "'Adrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "28", "'Adrd'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "29", "'Agrs'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "30", "'Arck'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "31", "'Agrd'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "32", "'Avin'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "33", "'Adrg'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "34", "'Alvd'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "35", "'Cdrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "36", "'Cdrd'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "37", "'Cpos'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "38", "'Crck'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "39", "'Cvin'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "40", "'Cgrs'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "41", "'Clvg'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "42", "'Ndrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "43", "'Ndrd'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "44", "'Nrck'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "45", "'Ngrs'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "46", "'Nice'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "47", "'Nsnw'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "48", "'Nsnr'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "49", "'Ydrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "50", "'Ydtr'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "51", "'Yblm'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "52", "'Ybtl'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "53", "'Ysqd'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "54", "'Yrtl'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "55", "'Ygsb'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "56", "'Yhdg'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "57", "'Ywmb'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "58", "'Vdrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "59", "'Vdrr'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "60", "'Vcrp'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "61", "'Vcbp'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "62", "'Vstp'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "63", "'Vgrs'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "64", "'Vrck'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "65", "'Vgrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "66", "'Qdrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "67", "'Qdrr'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "68", "'Qcrp'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "69", "'Qcbp'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "70", "'Qstp'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "71", "'Qgrs'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "72", "'Qrck'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "73", "'Qgrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "74", "'Xdrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "75", "'Xdtr'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "76", "'Xblm'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "77", "'Xbtl'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "78", "'Xsqd'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "79", "'Xrtl'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "80", "'Xgsb'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "81", "'Xhdg'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "82", "'Xwmb'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "83", "'Ddrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "84", "'Dbrk'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "85", "'Drds'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "86", "'Dlvc'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "87", "'Dlav'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "88", "'Ddkr'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "89", "'Dgrs'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "90", "'Dsqd'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "91", "'Gdrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "92", "'Gbrk'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "93", "'Grds'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "94", "'Glvc'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "95", "'Glav'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "96", "'Gdkr'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "97", "'Ggrs'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "98", "'Gsqd'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "99", "'Zdrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "100", "'Zdtr'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "101", "'Zdrg'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "102", "'Zbks'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "103", "'Zsan'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "104", "'Zbkl'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "105", "'Ztil'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "106", "'Zgrs'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "107", "'Zvin'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "108", "'Idrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "109", "'Idtr'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "110", "'Idki'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "111", "'Ibkb'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "112", "'Irbk'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "113", "'Itbk'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "114", "'Iice'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "115", "'Ibsq'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "116", "'Isnw'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "117", "'Odrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "118", "'Odtr'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "119", "'Osmb'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "120", "'Ofst'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "121", "'Olgb'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "122", "'Orok'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "123", "'Ofsl'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "124", "'Oaby'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "125", "'Kdrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "126", "'Kfsl'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "127", "'Kdts'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "128", "'Kfst'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "129", "'Ksmb'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "130", "'Klgb'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "131", "'Ksqt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "132", "'Kdkt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "133", "'Jdrt'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "134", "'Jdtr'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "135", "'Jblm'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "136", "'Jbtl'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "137", "'Jsqd'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "138", "'Jrtl'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "139", "'Jgsb'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "140", "'Jhdg'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "141", "'Jwmb'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "142", "'cAc2'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "143", "'cAc1'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "144", "'cBc2'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "145", "'cBc1'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "146", "'cKc1'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "147", "'cKc2'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "148", "'cYc2'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "149", "'cYc1'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "150", "'cXc2'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "151", "'cXc1'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "152", "'cJc2'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "153", "'cJc1'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "154", "'cDc2'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "155", "'cDc1'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "156", "'cCc2'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "157", "'cCc1'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "158", "'cIc2'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "159", "'cIc1'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "160", "'cFc2'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "161", "'cFc1'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "162", "'cLc2'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "163", "'cLc1'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "164", "'cWc2'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "165", "'cWc1'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "166", "'cNc2'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "167", "'cNc1'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "168", "'cOc1'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "169", "'cOc2'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "170", "'cZc2'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "171", "'cZc1'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "172", "'cGc2'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "173", "'cGc1'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "174", "'cVc2'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "175", "'cVc1'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "176", "'cQc2'" )

    //! runtextmacro TerrainTypeId2TerrainTypeMaxId( "177", "'cQc1'" )



    return 0

endfunction







endlibrary//===========================================================================

// Trigger: Terrain type grass

//===========================================================================

//TESH.scrollpos=21

//TESH.alwaysfold=0

library TerrainTypeGrass needs TerrainTypeMax





function TerrainTypeGrassId2MaxId takes integer grassId returns integer

	//! textmacro TerrainTypeGrassId2MaxId takes grassId, maxId

	if (grassId == $grassId$) then

		return $maxId$

	endif

	//! endtextmacro

	

	//! runtextmacro TerrainTypeGrassId2MaxId( "1", "5" )

	//! runtextmacro TerrainTypeGrassId2MaxId( "2", "11" )

	//! runtextmacro TerrainTypeGrassId2MaxId( "3", "12" )

	//! runtextmacro TerrainTypeGrassId2MaxId( "4", "17" )

	//! runtextmacro TerrainTypeGrassId2MaxId( "5", "26" )

	//! runtextmacro TerrainTypeGrassId2MaxId( "6", "29" )

	//! runtextmacro TerrainTypeGrassId2MaxId( "7", "40" )

	//! runtextmacro TerrainTypeGrassId2MaxId( "8", "45" )

	//! runtextmacro TerrainTypeGrassId2MaxId( "9", "55" )

	//! runtextmacro TerrainTypeGrassId2MaxId( "10", "63" )

	//! runtextmacro TerrainTypeGrassId2MaxId( "11", "65" )

	//! runtextmacro TerrainTypeGrassId2MaxId( "12", "71" )

	//! runtextmacro TerrainTypeGrassId2MaxId( "13", "73" )

	//! runtextmacro TerrainTypeGrassId2MaxId( "14", "80" )

	//! runtextmacro TerrainTypeGrassId2MaxId( "15", "106" )

	//! runtextmacro TerrainTypeGrassId2MaxId( "16", "107" )

	//! runtextmacro TerrainTypeGrassId2MaxId( "17", "139" )



    return 0

endfunction





function TerrainTypeMaxId2GrassId takes integer maxId returns integer

	//! textmacro TerrainTypeMaxId2GrassId takes grassId, maxId

	if (maxId == $maxId$) then

		return $grassId$

	endif

	//! endtextmacro

	

	//! runtextmacro TerrainTypeMaxId2GrassId( "1", "5" )

	//! runtextmacro TerrainTypeMaxId2GrassId( "2", "11" )

	//! runtextmacro TerrainTypeMaxId2GrassId( "3", "12" )

	//! runtextmacro TerrainTypeMaxId2GrassId( "4", "17" )

	//! runtextmacro TerrainTypeMaxId2GrassId( "5", "26" )

	//! runtextmacro TerrainTypeMaxId2GrassId( "6", "29" )

	//! runtextmacro TerrainTypeMaxId2GrassId( "7", "40" )

	//! runtextmacro TerrainTypeMaxId2GrassId( "8", "45" )

	//! runtextmacro TerrainTypeMaxId2GrassId( "9", "55" )

	//! runtextmacro TerrainTypeMaxId2GrassId( "10", "63" )

	//! runtextmacro TerrainTypeMaxId2GrassId( "11", "65" )

	//! runtextmacro TerrainTypeMaxId2GrassId( "12", "71" )

	//! runtextmacro TerrainTypeMaxId2GrassId( "13", "73" )

	//! runtextmacro TerrainTypeMaxId2GrassId( "14", "80" )

	//! runtextmacro TerrainTypeMaxId2GrassId( "15", "106" )

	//! runtextmacro TerrainTypeMaxId2GrassId( "16", "107" )

	//! runtextmacro TerrainTypeMaxId2GrassId( "17", "139" )



    return 0

endfunction





function TerrainTypeGrassId2TerrainTypeId takes integer grassId returns integer

    return TerrainTypeMaxId2TerrainTypeId(TerrainTypeGrassId2MaxId(grassId))

endfunction







endlibrary//===========================================================================

// Trigger: Terrain type names and data

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library TerrainTypeNamesAndData initializer Init_TerrainTypeNamesAndData needs TerrainTypeAsciiConversion, TerrainTypeMax, TerrainTypeGrass





globals

    string array TERRAIN_TYPE_NAMES

    string array TERRAIN_TYPE_DATA

    integer NB_TERRAINS_TOTAL = 177

endglobals









function Init_TerrainTypeNamesAndData takes nothing returns nothing

    local integer maxId

    local integer terrain

    local integer grassId

    local string S



    set TERRAIN_TYPE_NAMES[  1] = "Eté de Lordaeron - Terre"

    set TERRAIN_TYPE_NAMES[  2] = "Eté de Lordaeron - Terre rocailleuse"

    set TERRAIN_TYPE_NAMES[  3] = "Eté de Lordaeron - Terre herbeuse"

    set TERRAIN_TYPE_NAMES[  4] = "Eté de Lordaeron - Rochers"

    set TERRAIN_TYPE_NAMES[  5] = "Eté de Lordaeron - Herbe"

    set TERRAIN_TYPE_NAMES[  6] = "Eté de Lordaeron - Herbe sombre"

    set TERRAIN_TYPE_NAMES[  7] = "Automne de Lordaeron - Terre"

    set TERRAIN_TYPE_NAMES[  8] = "Automne de Lordaeron - Terre rocailleuse"

    set TERRAIN_TYPE_NAMES[  9] = "Automne de Lordaeron - Terre herbeuse"

    set TERRAIN_TYPE_NAMES[ 10] = "Automne de Lordaeron - Rochers"

    set TERRAIN_TYPE_NAMES[ 11] = "Automne de Lordaeron - Herbe"

    set TERRAIN_TYPE_NAMES[ 12] = "Automne de Lordaeron - Herbe sombre"

    set TERRAIN_TYPE_NAMES[ 13] = "Hiver de Lordaeron - Terre"

    set TERRAIN_TYPE_NAMES[ 14] = "Hiver de Lordaeron - Terre rocailleuse"

    set TERRAIN_TYPE_NAMES[ 15] = "Hiver de Lordaeron - Terre herbeuse"

    set TERRAIN_TYPE_NAMES[ 16] = "Hiver de Lordaeron - Rochers"

    set TERRAIN_TYPE_NAMES[ 17] = "Hiver de Lordaeron - Herbe"

    set TERRAIN_TYPE_NAMES[ 18] = "Hiver de Lordaeron - Herbe sombre"

    set TERRAIN_TYPE_NAMES[ 19] = "Barrens - Terre"

    set TERRAIN_TYPE_NAMES[ 20] = "Barrens - Terre rocailleuse"

    set TERRAIN_TYPE_NAMES[ 21] = "Barrens - Cailloux"

    set TERRAIN_TYPE_NAMES[ 22] = "Barrens - Terre herbeuse"

    set TERRAIN_TYPE_NAMES[ 23] = "Barrens - Désert"

    set TERRAIN_TYPE_NAMES[ 24] = "Barrens - Désert sombre"

    set TERRAIN_TYPE_NAMES[ 25] = "Barrens - Rochers"

    set TERRAIN_TYPE_NAMES[ 26] = "Barrens - Herbe"

    set TERRAIN_TYPE_NAMES[ 27] = "Ashenvale - Terre"

    set TERRAIN_TYPE_NAMES[ 28] = "Ashenvale - Terre rocailleuse"

    set TERRAIN_TYPE_NAMES[ 29] = "Ashenvale - Herbe"

    set TERRAIN_TYPE_NAMES[ 30] = "Ashenvale - Rochers"

    set TERRAIN_TYPE_NAMES[ 31] = "Ashenvale - Touffes d'herbe"

    set TERRAIN_TYPE_NAMES[ 32] = "Ashenvale - Vignes"

    set TERRAIN_TYPE_NAMES[ 33] = "Ashenvale - Terre herbeuse"

    set TERRAIN_TYPE_NAMES[ 34] = "Ashenvale - Feuilles"

    set TERRAIN_TYPE_NAMES[ 35] = "Felwood - Terre"

    set TERRAIN_TYPE_NAMES[ 36] = "Felwood - Terre rocailleuse"

    set TERRAIN_TYPE_NAMES[ 37] = "Felwood - Poison"

    set TERRAIN_TYPE_NAMES[ 38] = "Felwood - Rochers"

    set TERRAIN_TYPE_NAMES[ 39] = "Felwood - Vignes"

    set TERRAIN_TYPE_NAMES[ 40] = "Felwood - Herbe"

    set TERRAIN_TYPE_NAMES[ 41] = "Felwood - Feuilles"

    set TERRAIN_TYPE_NAMES[ 42] = "Northrend - Terre"

    set TERRAIN_TYPE_NAMES[ 43] = "Northrend - Terre sombre"

    set TERRAIN_TYPE_NAMES[ 44] = "Northrend - Rochers"

    set TERRAIN_TYPE_NAMES[ 45] = "Northrend - Herbe"

    set TERRAIN_TYPE_NAMES[ 46] = "Northrend - Glace"

    set TERRAIN_TYPE_NAMES[ 47] = "Northrend - Neige"

    set TERRAIN_TYPE_NAMES[ 48] = "Northrend - Neige rocailleuse"

    set TERRAIN_TYPE_NAMES[ 49] = "Ville - Terre"

    set TERRAIN_TYPE_NAMES[ 50] = "Ville - Terre rocailleuse"

    set TERRAIN_TYPE_NAMES[ 51] = "Ville - Marbre noir"

    set TERRAIN_TYPE_NAMES[ 52] = "Ville - Briques"

    set TERRAIN_TYPE_NAMES[ 53] = "Ville - Dalles carrées"

    set TERRAIN_TYPE_NAMES[ 54] = "Ville - Dalles rondes"

    set TERRAIN_TYPE_NAMES[ 55] = "Ville - Herbe"

    set TERRAIN_TYPE_NAMES[ 56] = "Ville - Jardin"

    set TERRAIN_TYPE_NAMES[ 57] = "Ville - Marbre blanc"

    set TERRAIN_TYPE_NAMES[ 58] = "Village - Terre"

    set TERRAIN_TYPE_NAMES[ 59] = "Village - Terre rocailleuse"

    set TERRAIN_TYPE_NAMES[ 60] = "Village - Champs"

    set TERRAIN_TYPE_NAMES[ 61] = "Village - Chemin caillouteux"

    set TERRAIN_TYPE_NAMES[ 62] = "Village - Chemin pavé"

    set TERRAIN_TYPE_NAMES[ 63] = "Village - Herbe courte"

    set TERRAIN_TYPE_NAMES[ 64] = "Village - Rochers"

    set TERRAIN_TYPE_NAMES[ 65] = "Village - Herbe épaisse"

    set TERRAIN_TYPE_NAMES[ 66] = "Village automne - Terre"

    set TERRAIN_TYPE_NAMES[ 67] = "Village automne - Terre rocailleuse"

    set TERRAIN_TYPE_NAMES[ 68] = "Village automne - Champs"

    set TERRAIN_TYPE_NAMES[ 69] = "Village automne - Chemin caillouteux"

    set TERRAIN_TYPE_NAMES[ 70] = "Village automne - Chemin pavé"

    set TERRAIN_TYPE_NAMES[ 71] = "Village automne - Herbe courte"

    set TERRAIN_TYPE_NAMES[ 72] = "Village automne - Rochers"

    set TERRAIN_TYPE_NAMES[ 73] = "Village automne - Herbe épaisse"

    set TERRAIN_TYPE_NAMES[ 74] = "Dalaran - Terre"

    set TERRAIN_TYPE_NAMES[ 75] = "Dalaran - Terre rocailleuse"

    set TERRAIN_TYPE_NAMES[ 76] = "Dalaran - Marbre noir"

    set TERRAIN_TYPE_NAMES[ 77] = "Dalaran - Briques"

    set TERRAIN_TYPE_NAMES[ 78] = "Dalaran - Dalles carrées"

    set TERRAIN_TYPE_NAMES[ 79] = "Dalaran - Dalles rondes"

    set TERRAIN_TYPE_NAMES[ 80] = "Dalaran - Herbe"

    set TERRAIN_TYPE_NAMES[ 81] = "Dalaran - Jardin"

    set TERRAIN_TYPE_NAMES[ 82] = "Dalaran - Marbre blanc"

    set TERRAIN_TYPE_NAMES[ 83] = "Donjon - Terre"

    set TERRAIN_TYPE_NAMES[ 84] = "Donjon - Briques"

    set TERRAIN_TYPE_NAMES[ 85] = "Donjon - Pierres rouges"

    set TERRAIN_TYPE_NAMES[ 86] = "Donjon - Fissures de lave"

    set TERRAIN_TYPE_NAMES[ 87] = "Donjon - Lave"

    set TERRAIN_TYPE_NAMES[ 88] = "Donjon - Rochers noirs"

    set TERRAIN_TYPE_NAMES[ 89] = "Donjon - Pierres grises"

    set TERRAIN_TYPE_NAMES[ 90] = "Donjon - Dalles carrées"

    set TERRAIN_TYPE_NAMES[ 91] = "Souterrain - Terre"

    set TERRAIN_TYPE_NAMES[ 92] = "Souterrain - Briques"

    set TERRAIN_TYPE_NAMES[ 93] = "Souterrain - Pierres rouges"

    set TERRAIN_TYPE_NAMES[ 94] = "Souterrain - Fissures de lave"

    set TERRAIN_TYPE_NAMES[ 95] = "Souterrain - Lave"

    set TERRAIN_TYPE_NAMES[ 96] = "Souterrain - Rochers noirs"

    set TERRAIN_TYPE_NAMES[ 97] = "Souterrain - Pierres grises"

    set TERRAIN_TYPE_NAMES[ 98] = "Souterrain - Dalles carrées"

    set TERRAIN_TYPE_NAMES[ 99] = "Ruines englouties - Terre"

    set TERRAIN_TYPE_NAMES[100] = "Ruines englouties - Terre rocailleuse"

    set TERRAIN_TYPE_NAMES[101] = "Ruines englouties - Terre herbeuse"

    set TERRAIN_TYPE_NAMES[102] = "Ruines englouties - Petites briques"

    set TERRAIN_TYPE_NAMES[103] = "Ruines englouties - Sable"

    set TERRAIN_TYPE_NAMES[104] = "Ruines englouties - Grandes briques"

    set TERRAIN_TYPE_NAMES[105] = "Ruines englouties - Dalles rondes"

    set TERRAIN_TYPE_NAMES[106] = "Ruines englouties - Herbe"

    set TERRAIN_TYPE_NAMES[107] = "Ruines englouties - Herbe sombre"

    set TERRAIN_TYPE_NAMES[108] = "Glacier d'Icecrown - Terre"

    set TERRAIN_TYPE_NAMES[109] = "Glacier d'Icecrown - Terre rocailleuse"

    set TERRAIN_TYPE_NAMES[110] = "Glacier d'Icecrown - Glace sombre"

    set TERRAIN_TYPE_NAMES[111] = "Glacier d'Icecrown - Briques noires"

    set TERRAIN_TYPE_NAMES[112] = "Glacier d'Icecrown - Briques runiques"

    set TERRAIN_TYPE_NAMES[113] = "Glacier d'Icecrown - Briques empilées"

    set TERRAIN_TYPE_NAMES[114] = "Glacier d'Icecrown - Glace"

    set TERRAIN_TYPE_NAMES[115] = "Glacier d'Icecrown - Carrés noirs"

    set TERRAIN_TYPE_NAMES[116] = "Glacier d'Icecrown - Neige"

    set TERRAIN_TYPE_NAMES[117] = "Outland - Terre"

    set TERRAIN_TYPE_NAMES[118] = "Outland - Terre claire"

    set TERRAIN_TYPE_NAMES[119] = "Outland - rocailleuse"

    set TERRAIN_TYPE_NAMES[120] = "Outland - Terre craquelée"

    set TERRAIN_TYPE_NAMES[121] = "Outland - Pierres plates"

    set TERRAIN_TYPE_NAMES[122] = "Outland - Rochers"

    set TERRAIN_TYPE_NAMES[123] = "Outland - Pierres plates claires"

    set TERRAIN_TYPE_NAMES[124] = "Outland - Abysse"

    set TERRAIN_TYPE_NAMES[125] = "Citadelle noire - Terre"

    set TERRAIN_TYPE_NAMES[126] = "Citadelle noire - Terre claire"

    set TERRAIN_TYPE_NAMES[127] = "Citadelle noire - Terre rocailleuse"

    set TERRAIN_TYPE_NAMES[128] = "Citadelle noire - Pierres plates"

    set TERRAIN_TYPE_NAMES[129] = "Citadelle noire - Petites briques"

    set TERRAIN_TYPE_NAMES[130] = "Citadelle noire - Grandes briques"

    set TERRAIN_TYPE_NAMES[131] = "Citadelle noire - Dalles carrées"

    set TERRAIN_TYPE_NAMES[132] = "Citadelle noire - Dalles sombres"

    set TERRAIN_TYPE_NAMES[133] = "Ruines de Dalaran - Terre"

    set TERRAIN_TYPE_NAMES[134] = "Ruines de Dalaran - Terre rocailleuse"

    set TERRAIN_TYPE_NAMES[135] = "Ruines de Dalaran - Marbre noir"

    set TERRAIN_TYPE_NAMES[136] = "Ruines de Dalaran - Dalles en brique"

    set TERRAIN_TYPE_NAMES[137] = "Ruines de Dalaran - Dalles carrées"

    set TERRAIN_TYPE_NAMES[138] = "Ruines de Dalaran - Dalles rondes"

    set TERRAIN_TYPE_NAMES[139] = "Ruines de Dalaran - Herbe"

    set TERRAIN_TYPE_NAMES[140] = "Ruines de Dalaran - Jardin"

    set TERRAIN_TYPE_NAMES[141] = "Ruines de Dalaran - Marbre blanc"

    set TERRAIN_TYPE_NAMES[142] = "Ashenvale - Falaise"

    set TERRAIN_TYPE_NAMES[143] = "Ashenvale - Falaise herbeuse"

    set TERRAIN_TYPE_NAMES[144] = "Barrens - Falaise désertique"

    set TERRAIN_TYPE_NAMES[145] = "Barrens - Falaise herbeuse"

    set TERRAIN_TYPE_NAMES[146] = "Catacombes - Falaise"

    set TERRAIN_TYPE_NAMES[147] = "Catacombes - Falaise de tuiles noires"

    set TERRAIN_TYPE_NAMES[148] = "Cité - Falaise"

    set TERRAIN_TYPE_NAMES[149] = "Cité - Falaise de tuiles carrées"

    set TERRAIN_TYPE_NAMES[150] = "Dalaran - Falaise"

    set TERRAIN_TYPE_NAMES[151] = "Dalaran - Falaise de tuiles carrées"

    set TERRAIN_TYPE_NAMES[152] = "Ruines de Dalaran - Falaise"

    set TERRAIN_TYPE_NAMES[153] = "Ruines de Dalaran - Falaise de tuiles carrées"

    set TERRAIN_TYPE_NAMES[154] = "Donjon - Falaise"

    set TERRAIN_TYPE_NAMES[155] = "Donjon - Falaise de tuiles carrées"

    set TERRAIN_TYPE_NAMES[156] = "Felwood - Falaise"

    set TERRAIN_TYPE_NAMES[157] = "Felwood - Falaise herbeuse"

    set TERRAIN_TYPE_NAMES[158] = "Glacier d'Icecrown - Falaise de briques runiques"

    set TERRAIN_TYPE_NAMES[159] = "Glacier d'Icecrown - Falaise enneigée"

    set TERRAIN_TYPE_NAMES[160] = "Automne de Lordaeron - Falaise"

    set TERRAIN_TYPE_NAMES[161] = "Automne de Lordaeron - Falaise herbeuse"

    set TERRAIN_TYPE_NAMES[162] = "Eté de Lordaeron - Falaise"

    set TERRAIN_TYPE_NAMES[163] = "Eté de Lordaeron - Falaise herbeuse"

    set TERRAIN_TYPE_NAMES[164] = "Hiver de Lordaeron - Falaise herbeuse"

    set TERRAIN_TYPE_NAMES[165] = "Hiver de Lordaeron - Falaise enneigée"

    set TERRAIN_TYPE_NAMES[166] = "Northrend - Falaise"

    set TERRAIN_TYPE_NAMES[167] = "Northrend - Falaise enneigée"

    set TERRAIN_TYPE_NAMES[168] = "Terres dévastées - Falaise abyssale"

    set TERRAIN_TYPE_NAMES[169] = "Terres dévastées - Falaise ardue"

    set TERRAIN_TYPE_NAMES[170] = "Ruines englouties - Falaise"

    set TERRAIN_TYPE_NAMES[171] = "Ruines englouties - Falaise de tuiles larges"

    set TERRAIN_TYPE_NAMES[172] = "Souterrain - Falaise"

    set TERRAIN_TYPE_NAMES[173] = "Souterrain - Falaise de tuiles carrées"

    set TERRAIN_TYPE_NAMES[174] = "Village - Falaise"

    set TERRAIN_TYPE_NAMES[175] = "Village - Falaise d'herbe épaisse"

    set TERRAIN_TYPE_NAMES[176] = "Village en automne - Falaise"

    set TERRAIN_TYPE_NAMES[177] = "Village en automne - Falaise d'herbe épaisse"

    

    

    set maxId = 1

    loop

        exitwhen (maxId > NB_TERRAINS_TOTAL)

            set terrain = TerrainTypeMaxId2TerrainTypeId(maxId)

            set S = TERRAIN_TYPE_NAMES[maxId] + " :    " + I2S(maxId) + "    " + TerrainTypeId2TerrainTypeAsciiString(terrain)

            set grassId = TerrainTypeMaxId2GrassId(maxId)

            if (grassId != 0) then

                set S = S + "    g" + I2S(grassId)

            endif

            set TERRAIN_TYPE_DATA[maxId] = S

        set maxId = maxId + 1

    endloop

endfunction









endlibrary

//===========================================================================

// Trigger: Terrain functions

//===========================================================================

//TESH.scrollpos=73

//TESH.alwaysfold=0

library TerrainFunctions needs TerrainTypeAsciiConversion, TerrainTypeMax, TerrainTypeGrass, TerrainTypeFunctions







function IsTerrainAlreadyUsed takes integer terrainType returns boolean

    local integer i = 0

    loop

        exitwhen (udg_used_terrain_types[i] == 0)

            if (udg_used_terrain_types[i] == terrainType) then

                return true

            endif

        set i = i + 1

    endloop

    return false

endfunction





function IsTerrainsLimitNumberReached takes nothing returns boolean

    return (udg_nb_used_terrains == NB_MAX_OF_TERRAINS)

endfunction





function AddNewTerrain takes integer newTerrain returns boolean

    if (IsTerrainsLimitNumberReached() or IsTerrainAlreadyUsed(newTerrain)) then

        return false

    endif

    set udg_used_terrain_types[udg_nb_used_terrains] = newTerrain

    set udg_nb_used_terrains = udg_nb_used_terrains + 1

    return true

endfunction



function CanUseTerrain takes integer terrainType returns boolean

    if (IsTerrainAlreadyUsed(terrainType)) then

        return true

    endif

    return AddNewTerrain(terrainType)

endfunction





function GetRandomTerrain takes nothing returns integer

    return TerrainTypeMaxId2TerrainTypeId(GetRandomInt(1, NB_TERRAINS_TOTAL))

endfunction





function GetRandomUsedTerrain takes nothing returns integer

    return udg_used_terrain_types[GetRandomInt(0, udg_nb_used_terrains-1)]

endfunction





function GetRandomNotUsedTerrain takes nothing returns integer

    local integer terrainType

    loop

        set terrainType = GetRandomTerrain()

        exitwhen (not IsTerrainAlreadyUsed(terrainType))

    endloop

    return terrainType  

endfunction





function GetTerrainName takes integer terrain returns string

    if (terrain > NB_TERRAINS_TOTAL) then

        return TERRAIN_TYPE_NAMES[TerrainTypeId2TerrainTypeMaxId(terrain)]

    endif

    if (terrain <= 0) then

        return null

    endif

    return TERRAIN_TYPE_NAMES[terrain]        

endfunction





function GetTerrainData takes integer terrain returns string

    //GetTerrainData('Nice') == "46 : Northrend - Glace    'Nice'"

    local string str

    local integer maxId

    local TerrainType terrainType

    

    if (terrain > NB_TERRAINS_TOTAL) then

        set maxId = TerrainTypeId2TerrainTypeMaxId(terrain)

    else

        if (terrain > 0) then

            set maxId = terrain

            set terrain = TerrainTypeMaxId2TerrainTypeId(maxId)

        else

            return null

        endif

    endif

    set str = udg_colorCode[RED] + TERRAIN_TYPE_DATA[maxId]

    

    set terrainType = TerrainTypeId2TerrainType(terrain)

    if (terrainType != 0) then

        if (terrainType.getKind() == "slide") then

            set str = str + COLOR_TERRAIN_SLIDE

        else 

            if (terrainType.getKind() == "walk") then

                set str = str + COLOR_TERRAIN_WALK

            else

                set str = str + COLOR_TERRAIN_DEATH

            endif

        endif

        set str = str + "        " + terrainType.label

        if (terrainType.alias != null) then

            set str = str + "  " + terrainType.alias

        endif

    endif

    

    return str

endfunction





function DisplayTerrainDataToPlayer takes player p, integer terrain returns nothing

    call DisplayTimedTextToPlayer(p, 0., 0., TERRAIN_DATA_DISPLAY_TIME, GetTerrainData(terrain))

endfunction











endlibrary



//===========================================================================

// Trigger: Terrain type from string

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library TerrainTypeFromString needs TerrainFunctions







function TerrainTypeString2TerrainTypeId takes string str returns integer

    if (IsPositiveInteger(str)) then

        return TerrainTypeMaxId2TerrainTypeId(S2I(str))

    endif

    if (SubStringBJ(str, 1, 1) == "g" and IsPositiveInteger(SubStringBJ(str, 2, StringLength(str)))) then

        return TerrainTypeGrassId2TerrainTypeId(S2I(SubStringBJ(str, 2, StringLength(str))))

    endif

    if (StringLength(str) == 6 and SubStringBJ(str, 1, 1) == "'" and SubStringBJ(str, 6, 6) == "'") then

        return TerrainTypeAsciiString2TerrainTypeId(str)

    endif

    if (str == "x") then

        return GetRandomTerrain()

    endif

    if (str == "xnk") then

        return GetRandomNotUsedTerrain()         

    endif

    if (str == "xak") then

        return GetRandomUsedTerrain()

    endif

    return 0

endfunction









endlibrary

//===========================================================================

// Trigger: Modify terrain functions

//===========================================================================

//TESH.scrollpos=12

//TESH.alwaysfold=0

library ModifyTerrainFunctions needs TerrainFunctions









function GetNbCaseBetween takes real minX, real minY, real maxX, real maxY returns integer

    return (R2I((maxX - minX)/LARGEUR_CASE) * R2I((maxY - minY)/LARGEUR_CASE))

endfunction





function ChangeTerrainType takes real x, real y, integer terrainTypeId returns nothing

    call SetTerrainType(x, y, terrainTypeId, -1, 1, 0)   

endfunction





function ChangeTerrainBetween takes integer terrainType, real x1, real y1, real x2, real y2 returns boolean

    local real minX = RMinBJ(x1, x2)

    local real minY = RMinBJ(y1, y2)

    local real maxX = RMaxBJ(x1, x2)

    local real maxY = RMaxBJ(y1, y2)



    local real r

    local real x

    local real y



    //call Text.A( "nbCases == " + I2S( GetNbCaseBetween( minX, minY, maxX, maxY ) ) )

    //call Text.A( "changing terrain to : " + TerrainTypeId2TerrainTypeAsciiString( terrainType ) )

    

    if (GetNbCaseBetween(minX, minY, maxX, maxY) > NB_MAX_TILES_MODIFIED) then

        return false

    endif

    if (not CanUseTerrain(terrainType)) then

        return false

    endif

    

    set x = minX

    set y = minY



    loop

        exitwhen (y > maxY)

            loop

                exitwhen (x > maxX)

                    call ChangeTerrainType(x, y, terrainType)  

                set x = x + LARGEUR_CASE

            endloop

            set x = minX

        set y = y + LARGEUR_CASE

    endloop 

    

    //call Text.A( "terrain changed to : " + TerrainTypeId2TerrainTypeAsciiString( GetTerrainType( minX, minY ) ) )

    

    return true

endfunction











endlibrary//===========================================================================

// Trigger: Terrain modifying trig

//===========================================================================

//TESH.scrollpos=11

//TESH.alwaysfold=0

library TerrainModifyingTrig initializer Init_TerrainModifyingTrig







globals

    real y

    private boolean array wasCheckTerrainTriggerOn

    boolean terrainModifyWorking = false

    //constant integer TERRAIN_MODIFYING_NB_LINES_TO_DO = 5

    //maintenant on fait ligne par ligne (--> 1)

endglobals







function Init_TerrainModifyingTrig takes nothing returns nothing

    set gg_trg_Terrain_modifying_trig = CreateTrigger()

    call DisableTrigger(gg_trg_Terrain_modifying_trig)

    call TriggerRegisterTimerEvent(gg_trg_Terrain_modifying_trig, LOW_PERIOD_FOR_WORK, true)

endfunction





function StopEnabledCheckTerrainTriggers takes nothing returns nothing

    local Escaper escaper

    local integer i = 0

    loop

        exitwhen (i > 11)

            set escaper = udg_escapers.get(i)

            if (escaper != 0) then

                if (escaper.doesCheckTerrain()) then

                    set wasCheckTerrainTriggerOn[i] = true

                    call escaper.enableCheckTerrain(false)

                else

                    set wasCheckTerrainTriggerOn[i] = false

                endif

            endif

        set i = i + 1

    endloop

endfunction





function RestartEnabledCheckTerrainTriggers takes nothing returns nothing

    local Escaper escaper

    local integer i = 0

    loop

        exitwhen (i > 11)

            set escaper = udg_escapers.get(i)

            if (escaper != 0) then

                if (wasCheckTerrainTriggerOn[i]) then

                    call escaper.enableCheckTerrain(true)

                endif

            endif

        set i = i + 1

    endloop

endfunction







endlibrary//===========================================================================

// Trigger: Change one terrain

//===========================================================================

//TESH.scrollpos=35

//TESH.alwaysfold=0

library ChangeOneTerrain needs AllTerrainFunctions, TerrainModifyingTrig





globals

    private integer oldTerrain

    private integer newTerrain

endglobals









function ChangeAppearanceOfOneTerrain_Actions takes nothing returns nothing

    local real x

    //local integer i = 1

    //loop

        //exitwhen (i > TERRAIN_MODIFYING_NB_LINES_TO_DO)

            set x = MAP_MIN_X

            loop

                exitwhen (x > MAP_MAX_X)

                    if (GetTerrainType(x, y) == oldTerrain) then

                        call ChangeTerrainType(x, y, newTerrain)

                    endif

                set x = x + LARGEUR_CASE

            endloop

            set y = y + LARGEUR_CASE

            if (y > MAP_MAX_Y) then

                call DisableTrigger(GetTriggeringTrigger())

                call RestartEnabledCheckTerrainTriggers()

                set terrainModifyWorking = false

                return

            endif

        //set i = i + 1

    //endloop

endfunction





private function StartTerrainModifying takes nothing returns nothing

    call StopEnabledCheckTerrainTriggers()

    call TriggerClearActions(gg_trg_Terrain_modifying_trig)

    call TriggerAddAction(gg_trg_Terrain_modifying_trig, function ChangeAppearanceOfOneTerrain_Actions)

    set y = MAP_MIN_Y

    call EnableTrigger(gg_trg_Terrain_modifying_trig)

    set terrainModifyWorking = true

endfunction 





function ChangeOneTerrain takes string terrainTypeLabel, string newTerrainType returns string

    local TerrainType terrainType

    if (terrainModifyWorking) then

        call Text_erA("can't execute two commands of this type simultaneously !")

        return null

    endif

    

    set terrainType = udg_terrainTypes.get(terrainTypeLabel)

    if (terrainType == 0) then

        return null

    endif

    

    set oldTerrain = terrainType.getTerrainTypeId()

    set newTerrain = TerrainTypeString2TerrainTypeId(newTerrainType)

    if (newTerrain == 0) then

        return null

    endif

    if (udg_terrainTypes.isTerrainTypeIdAlreadyUsed(newTerrain)) then

        return null

    endif

    if (not terrainType.setTerrainTypeId(newTerrain)) then

        return null

    endif

    

    call StartTerrainModifying()   

    return GetTerrainData(newTerrain)

endfunction









endlibrary







//===========================================================================

// Trigger: Change all terrains

//===========================================================================

//TESH.scrollpos=177

//TESH.alwaysfold=0

library ChangeAllTerrains needs AllTerrainFunctions, TerrainModifyingTrig





globals

    private integer array oldTerrainTypes

    private integer array newTerrainTypes  

    private integer lastTerrainArrayId  

    private integer nbNewTerrains

    private integer nbNewTerrainsAllowed

    boolean udg_changeAllTerrainsAtRevive = false

endglobals







function ChangeAllTerrains_Actions takes nothing returns nothing

    local real x

    local integer terrainTypeId

    local boolean done

    local integer j

    //local integer i = 1

    //loop

        //exitwhen (i > TERRAIN_MODIFYING_NB_LINES_TO_DO)

            set x = MAP_MIN_X

            loop

                exitwhen (x > MAP_MAX_X)

                    set terrainTypeId = GetTerrainType(x, y)

                    set done = false

                    set j = 0

                    loop

                        exitwhen (j > lastTerrainArrayId or done)

                            if (terrainTypeId == oldTerrainTypes[j]) then

                                call ChangeTerrainType(x, y, newTerrainTypes[j])

                                set done = true

                            endif

                        set j = j + 1

                    endloop

                set x = x + LARGEUR_CASE

            endloop

            set y = y + LARGEUR_CASE

            if (y > MAP_MAX_Y) then

                call DisableTrigger(GetTriggeringTrigger())

                call RestartEnabledCheckTerrainTriggers()

                set terrainModifyWorking = false

                return

            endif

        //set i = i + 1

    //endloop

endfunction





private function StartTerrainModifying takes nothing returns nothing

    set y = MAP_MIN_Y

    call StopEnabledCheckTerrainTriggers()

    call TriggerClearActions(gg_trg_Terrain_modifying_trig)

    call TriggerAddAction(gg_trg_Terrain_modifying_trig, function ChangeAllTerrains_Actions)

    call EnableTrigger(gg_trg_Terrain_modifying_trig)

    set terrainModifyWorking = true

endfunction 





private function GetRandomTerrain_checked takes nothing returns integer

    local integer i

    local integer rdmTerrain

    local boolean alreadyUsed

    loop

        if (nbNewTerrains >= nbNewTerrainsAllowed) then

            set rdmTerrain = GetRandomUsedTerrain()

        else

            set rdmTerrain = GetRandomTerrain()

        endif

            set alreadyUsed = false

            set i = 0

            loop

                exitwhen (i > lastTerrainArrayId or alreadyUsed)

                    set alreadyUsed = (newTerrainTypes[i] == rdmTerrain)

                set i = i + 1

            endloop

        exitwhen (not alreadyUsed)

    endloop

    if (not IsTerrainAlreadyUsed(rdmTerrain)) then

        set nbNewTerrains = nbNewTerrains + 1

    endif

    return rdmTerrain

endfunction





private function GetRandomKnownTerrain_checked takes nothing returns integer

    local integer i

    local integer rdmTerrain

    local boolean alreadyUsed

    loop

        set rdmTerrain = GetRandomUsedTerrain()

            set alreadyUsed = false

            set i = 0

            loop

                exitwhen (i > lastTerrainArrayId or alreadyUsed)

                    set alreadyUsed = (newTerrainTypes[i] == rdmTerrain)

                set i = i + 1

            endloop

        exitwhen (not alreadyUsed)

    endloop

    return rdmTerrain

endfunction





private function GetRandomNotKnownTerrain_checked takes nothing returns integer

    local integer i

    local integer rdmTerrain

    local boolean alreadyUsed

    loop

        set rdmTerrain = GetRandomNotUsedTerrain()

            set alreadyUsed = false

            set i = 0

            loop

                exitwhen (i > lastTerrainArrayId or alreadyUsed)

                    set alreadyUsed = (newTerrainTypes[i] == rdmTerrain)

                set i = i + 1

            endloop

        exitwhen (not alreadyUsed)

    endloop

    return rdmTerrain

endfunction







function ChangeAllTerrains takes string mode returns boolean



//modes : normal, known, notKnown

    local TerrainType array terrainTypes

    local integer n

    local integer i

    

    if (terrainModifyWorking) then

        call Text_erA("can't execute two commands of this type simultaneously !")

        return false

    endif

    

    set n = 0

    set i = 0

    loop

            set terrainTypes[n] = udg_terrainTypes.getWalk(i)

        exitwhen (terrainTypes[n] == 0)

            set oldTerrainTypes[n] = terrainTypes[n].getTerrainTypeId()

            set n = n + 1

        set i = i + 1

    endloop

    set i = 0

    loop

            set terrainTypes[n] = udg_terrainTypes.getDeath(i)

        exitwhen (terrainTypes[n] == 0)

            set oldTerrainTypes[n] = terrainTypes[n].getTerrainTypeId()

            set n = n + 1

        set i = i + 1

    endloop

    set i = 0

    loop

            set terrainTypes[n] = udg_terrainTypes.getSlide(i)

        exitwhen (terrainTypes[n] == 0)

            set oldTerrainTypes[n] = terrainTypes[n].getTerrainTypeId()

            set n = n + 1

        set i = i + 1

    endloop

    

    set lastTerrainArrayId = n - 1

    set nbNewTerrainsAllowed = NB_MAX_OF_TERRAINS - udg_nb_used_terrains

    

    if (mode == "normal") then

        set nbNewTerrains = 0

        set i = 0

        loop

            exitwhen (i > lastTerrainArrayId)

                set newTerrainTypes[i] = GetRandomTerrain_checked()

            set i = i + 1

        endloop

    else

        if (mode == "known") then

            set i = 0

            loop

                exitwhen (i > lastTerrainArrayId)

                    set newTerrainTypes[i] = GetRandomKnownTerrain_checked()

                set i = i + 1

            endloop

        else

            if (mode == "notKnown") then

                set nbNewTerrains = lastTerrainArrayId + 1

                if (nbNewTerrains > nbNewTerrainsAllowed) then

                    return false

                endif

                set i = 0

                loop

                    exitwhen (i > lastTerrainArrayId)

                        set newTerrainTypes[i] = GetRandomNotKnownTerrain_checked()

                    set i = i + 1

                endloop

            endif

        endif

    endif

    

    call StartTerrainModifying() 

    

    set i = 0

    loop

        exitwhen (i > lastTerrainArrayId)

            call terrainTypes[i].setTerrainTypeId(newTerrainTypes[i])

            call AddNewTerrain(newTerrainTypes[i])

        set i = i + 1

    endloop

    

    //call DisplayTextToForce(GetPlayersAll(), " ")

    //call DisplayTextToForce(GetPlayersAll(), udg_colorCode[TEAL] + "       All terrains changed !")

    //set i = 0

    //loop

    //    exitwhen (i > lastTerrainArrayId)

    //        call Text_A(udg_colorCode[RED] + GetTerrainData(newTerrainTypes[i]))

    //    set i = i + 1

    //endloop



    return true

endfunction









endlibrary//===========================================================================

// Trigger: Exchange terrains

//===========================================================================

//TESH.scrollpos=31

//TESH.alwaysfold=0

library ExchangeTerrains needs AllTerrainFunctions, TerrainModifyingTrig





globals

    private integer terrainA

    private integer terrainB

endglobals









function ExchangeTerrains_Actions takes nothing returns nothing

    local real x

    local integer terrainType

    //local integer i = 1

    //loop

        //exitwhen (i > TERRAIN_MODIFYING_NB_LINES_TO_DO)

            set x = MAP_MIN_X

            loop

                exitwhen (x > MAP_MAX_X)

                    set terrainType = GetTerrainType(x, y)

                    if (terrainType == terrainA) then

                        call ChangeTerrainType( x, y, terrainB )

                    else

                    if (terrainType == terrainB) then

                        call ChangeTerrainType( x, y, terrainA )

                    endif

                    endif

                set x = x + LARGEUR_CASE

            endloop

            set y = y + LARGEUR_CASE

            if (y > MAP_MAX_Y) then

                call DisableTrigger(GetTriggeringTrigger())

                call RestartEnabledCheckTerrainTriggers()

                set terrainModifyWorking = false

                return

            endif

        //set i = i + 1

    //endloop

endfunction





private function StartTerrainModifying takes nothing returns nothing

    call StopEnabledCheckTerrainTriggers()

    call TriggerClearActions(gg_trg_Terrain_modifying_trig)

    call TriggerAddAction(gg_trg_Terrain_modifying_trig, function ExchangeTerrains_Actions)

    set y = MAP_MIN_Y

    call EnableTrigger(gg_trg_Terrain_modifying_trig)

    set terrainModifyWorking = true

endfunction 







function ExchangeTerrains takes string terrainTypeLabelA, string terrainTypeLabelB returns boolean

    local TerrainType terrainTypeA = udg_terrainTypes.get(terrainTypeLabelA)

    local TerrainType terrainTypeB = udg_terrainTypes.get(terrainTypeLabelB)

    if (terrainTypeA == terrainTypeB) then

        return false

    endif

    if (terrainModifyWorking) then

        call Text_erA("can't execute two commands of this type simultaneously !")

        return false

    endif

    

    set terrainA = terrainTypeA.getTerrainTypeId()

    set terrainB = terrainTypeB.getTerrainTypeId()

    

    call StartTerrainModifying()  

    

    call terrainTypeA.setTerrainTypeId(terrainB)

    call terrainTypeB.setTerrainTypeId(terrainA)

    return true

endfunction

    







endlibrary//===========================================================================

// Trigger: Randomize terrains

//===========================================================================

//TESH.scrollpos=84

//TESH.alwaysfold=0

library RandomizeTerrains needs AllTerrainFunctions, TerrainModifyingTrig





globals

    private integer array oldTerrainTypes

    private integer array newTerrainTypes

    private integer lastTerrainArrayId

endglobals











function RandomizeTerrains_Actions takes nothing returns nothing

    local real x

    local integer terrainTypeId

    local boolean done

    local integer j

    local integer i = 1

    //loop

        //exitwhen (i > TERRAIN_MODIFYING_NB_LINES_TO_DO)

            set x = MAP_MIN_X

            loop

                exitwhen (x > MAP_MAX_X)

                    set terrainTypeId = GetTerrainType(x, y)

                    set done = false

                    set j = 0

                    loop

                        exitwhen (j > lastTerrainArrayId or done)

                            if (terrainTypeId == oldTerrainTypes[j]) then

                                call ChangeTerrainType(x, y, newTerrainTypes[j])

                                set done = true

                            endif

                        set j = j + 1

                    endloop

                set x = x + LARGEUR_CASE

            endloop

            set y = y + LARGEUR_CASE

            if (y > MAP_MAX_Y) then

                call DisableTrigger(GetTriggeringTrigger())

                call RestartEnabledCheckTerrainTriggers()

                set terrainModifyWorking = false

                return

            endif

        //set i = i + 1

    //endloop

endfunction





private function StartTerrainModifying takes nothing returns nothing

    call StopEnabledCheckTerrainTriggers()

    call TriggerClearActions(gg_trg_Terrain_modifying_trig)

    call TriggerAddAction(gg_trg_Terrain_modifying_trig, function RandomizeTerrains_Actions)

    set y = MAP_MIN_Y

    call EnableTrigger(gg_trg_Terrain_modifying_trig)

    set terrainModifyWorking = true

endfunction 





function RandomizeTerrains takes nothing returns nothing

    local integer i

    local integer n

    local boolean array isTaken

    local TerrainType array terrainTypes

    

    if (terrainModifyWorking) then

        call Text_erA("can't execute two commands of this type simultaneously !")

        return

    endif

    

    set n = 0

    set i = 0

    loop

            set terrainTypes[n] = udg_terrainTypes.getWalk(i)

        exitwhen (terrainTypes[n] == 0)

            set oldTerrainTypes[n] = terrainTypes[n].getTerrainTypeId()

            set n = n + 1

        set i = i + 1

    endloop

    set i = 0

    loop

            set terrainTypes[n] = udg_terrainTypes.getDeath(i)

        exitwhen (terrainTypes[n] == 0)

            set oldTerrainTypes[n] = terrainTypes[n].getTerrainTypeId()

            set n = n + 1

        set i = i + 1

    endloop

    set i = 0

    loop

            set terrainTypes[n] = udg_terrainTypes.getSlide(i)

        exitwhen (terrainTypes[n] == 0)

            set oldTerrainTypes[n] = terrainTypes[n].getTerrainTypeId()

            set n = n + 1

        set i = i + 1

    endloop

    

    set lastTerrainArrayId = n - 1

    

    set i = 0

    loop

        exitwhen (i > lastTerrainArrayId)

            set isTaken[i] = false

        set i = i + 1

    endloop

    

    set i = 0

    loop

        exitwhen (i > lastTerrainArrayId)

            loop

                set n = GetRandomInt(0, lastTerrainArrayId)

                exitwhen (not isTaken[n])

            endloop

            set isTaken[n] = true

            set newTerrainTypes[i] = oldTerrainTypes[n]

        set i = i + 1

    endloop

    

    call StartTerrainModifying() 

    

    set i = 0

    loop

        exitwhen (i > lastTerrainArrayId)

            call terrainTypes[i].setTerrainTypeId(newTerrainTypes[i])

        set i = i + 1

    endloop

endfunction









endlibrary//===========================================================================

// Trigger: Reinit terrains

//===========================================================================

//TESH.scrollpos=74

//TESH.alwaysfold=0

library ReinitTerrains initializer Init_ReinitTerrains needs AllTerrainFunctions, TerrainModifyingTrig







globals

    private TerrainType array terrainTypes

    private integer array terrainTypeIds

    private integer array terrainTypeIdsToReplace

endglobals





private function SaveTerrainConfig takes nothing returns nothing

    local integer n = 0

    local integer i = 0

    loop

        exitwhen (i >= udg_terrainTypes.numberOfWalk)

            set terrainTypes[n] = udg_terrainTypes.getWalk(i)

            set terrainTypeIds[n] = terrainTypes[n].getTerrainTypeId()

            set n = n + 1

        set i = i + 1

    endloop

    set i = 0

    loop

        exitwhen (i >= udg_terrainTypes.numberOfDeath)

            set terrainTypes[n] = udg_terrainTypes.getDeath(i)

            set terrainTypeIds[n] = terrainTypes[n].getTerrainTypeId()

            set n = n + 1

        set i = i + 1

    endloop

    set i = 0

    loop

        exitwhen (i >= udg_terrainTypes.numberOfSlide)

            set terrainTypes[n] = udg_terrainTypes.getSlide(i)

            set terrainTypeIds[n] = terrainTypes[n].getTerrainTypeId()

            set n = n + 1

        set i = i + 1

    endloop

endfunction





function Init_ReinitTerrains takes nothing returns nothing

    local trigger trig = CreateTrigger()

    call TriggerAddAction(trig, function SaveTerrainConfig)

    call TriggerRegisterTimerEvent(trig, 0, false)

    set trig = null

endfunction













function ReinitTerrains_Actions takes nothing returns nothing

    local real x

    local integer terrainTypeId

    local boolean done

    local integer j

    //local integer i = 1

    //loop

        //exitwhen (i > TERRAIN_MODIFYING_NB_LINES_TO_DO)

            set x = MAP_MIN_X

            loop

                exitwhen (x > MAP_MAX_X)

                    set terrainTypeId = GetTerrainType(x, y)

                    set done = false

                    set j = 0

                    loop

                        exitwhen (terrainTypes[j] == 0 or done)

                            if (terrainTypeId == terrainTypeIdsToReplace[j]) then

                                call ChangeTerrainType(x, y, terrainTypeIds[j])

                                set done = true

                            endif

                        set j = j + 1

                    endloop

                set x = x + LARGEUR_CASE

            endloop

            set y = y + LARGEUR_CASE

            if (y > MAP_MAX_Y) then

                call DisableTrigger(GetTriggeringTrigger())

                call RestartEnabledCheckTerrainTriggers()

                set terrainModifyWorking = false

                call Text_mkA("Terrains reinitialized")

                return

            endif

        //set i = i + 1

    //endloop

endfunction





private function StartTerrainModifying takes nothing returns nothing

    call StopEnabledCheckTerrainTriggers()

    call TriggerClearActions(gg_trg_Terrain_modifying_trig)

    call TriggerAddAction(gg_trg_Terrain_modifying_trig, function ReinitTerrains_Actions)

    set y = MAP_MIN_Y

    call EnableTrigger(gg_trg_Terrain_modifying_trig)

    set terrainModifyWorking = true

endfunction 





function ReinitTerrains takes nothing returns nothing

    local integer i 

    

    if (terrainModifyWorking) then

        call Text_erA("can't execute two commands of this type simultaneously !")

        return

    endif

    

    set i = 0

    loop

        exitwhen (terrainTypes[i] == 0)

            set terrainTypeIdsToReplace[i] = terrainTypes[i].getTerrainTypeId()

            call terrainTypes[i].setTerrainTypeId(terrainTypeIds[i])

        set i = i + 1

    endloop

    call StartTerrainModifying()

endfunction









endlibrary//===========================================================================

// Trigger: Reinit terrains position Change variations and ut at beginning

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library ReinitTerrainsPositions initializer Init_Reinit_terrains_position_Change_variations_and_ut_at_beginning needs AllTerrainFunctions, TerrainModifyingTrig





globals

    private TerrainType array TERRAIN_SAVE [232000]

    private integer terrainSave_id

endglobals







    //save terrain at init

    





private function SaveTerrain_Actions takes nothing returns nothing

    local integer terrainType

    local real x = MAP_MIN_X

    loop

        exitwhen (x > MAP_MAX_X)

            set terrainType = GetTerrainType(x, y)

            //mise à jour used terrain (-ut)

            call AddNewTerrain(terrainType)

            //changer variations

            call ChangeTerrainType(x, y, terrainType)

            //sauvegarde du terrain

            set TERRAIN_SAVE[terrainSave_id] = TerrainTypeId2TerrainType(terrainType)

            set terrainSave_id = terrainSave_id + 1

        set x = x + LARGEUR_CASE

    endloop

    

    set y = y + LARGEUR_CASE

    if (y > MAP_MAX_Y) then

        set terrainModifyWorking = false

        call DisableTrigger(GetTriggeringTrigger())

        return

    endif

endfunction





private function StartSaveTerrain takes nothing returns nothing

    call TriggerClearActions(gg_trg_Terrain_modifying_trig)

    call TriggerAddAction(gg_trg_Terrain_modifying_trig, function SaveTerrain_Actions)

    set terrainSave_id = 0

    set y = MAP_MIN_Y

    call EnableTrigger(gg_trg_Terrain_modifying_trig)

    set terrainModifyWorking = true

    call DestroyTrigger(GetTriggeringTrigger())

endfunction





function Init_Reinit_terrains_position_Change_variations_and_ut_at_beginning takes nothing returns nothing

    local trigger trig = CreateTrigger()

    call TriggerAddAction(trig, function StartSaveTerrain)

    call TriggerRegisterTimerEvent(trig, 0, false)

    set trig = null

endfunction







//=========================================================================





    //reinitTerrainPositions

    

    

function ReinitTerrainsPosition_Actions takes nothing returns nothing

    local real x

    //local integer i = 1

    //loop

        //exitwhen (i > TERRAIN_MODIFYING_NB_LINES_TO_DO)

            set x = MAP_MIN_X

            loop

                exitwhen (x > MAP_MAX_X)

                    if (TERRAIN_SAVE[terrainSave_id] != 0 and TERRAIN_SAVE[terrainSave_id].getTerrainTypeId() != 0) then

                        call ChangeTerrainType(x, y, TERRAIN_SAVE[terrainSave_id].getTerrainTypeId())

                    endif

                    set terrainSave_id = terrainSave_id + 1

                set x = x + LARGEUR_CASE

            endloop

            set y = y + LARGEUR_CASE

            if (y > MAP_MAX_Y) then

                call Text_mkA("Terrains position reinitialized !")

                call DisableTrigger( GetTriggeringTrigger() )

                set terrainModifyWorking = false

                call RestartEnabledCheckTerrainTriggers()

                return

            endif

        //set i = i + 1

    //endloop

endfunction







private function StartTerrainModifying takes nothing returns nothing

    call TriggerClearActions(gg_trg_Terrain_modifying_trig)

    call TriggerAddAction(gg_trg_Terrain_modifying_trig, function ReinitTerrainsPosition_Actions)

    set terrainSave_id = 0

    set y = MAP_MIN_Y

    call EnableTrigger(gg_trg_Terrain_modifying_trig)

    set terrainModifyWorking = true

    call StopEnabledCheckTerrainTriggers()

endfunction 











function ReinitTerrainsPosition takes nothing returns nothing

    if (terrainModifyWorking) then

        call Text_erA("can't execute two commands of this type simultaneously !")

        return

    endif

    call StartTerrainModifying()

endfunction













endlibrary//===========================================================================

// Trigger: Save load terrain without name

//===========================================================================

//TESH.scrollpos=54

//TESH.alwaysfold=0

library SaveLoadTerrainWithoutName needs AllTerrainFunctions, TerrainModifyingTrig





globals

    private TerrainType array terrainSave [232000]

    private integer terrainSave_id

endglobals







    //save terrain

    



private function SaveTerrain_Actions takes nothing returns nothing

    local real x = MAP_MIN_X

    loop

        exitwhen (x > MAP_MAX_X)

            set terrainSave[terrainSave_id] = udg_terrainTypes.getTerrainType(x, y)

            set terrainSave_id = terrainSave_id + 1

        set x = x + LARGEUR_CASE

    endloop

    

    set y = y + LARGEUR_CASE

    if (y > MAP_MAX_Y) then

        set terrainModifyWorking = false

        call DisableTrigger(GetTriggeringTrigger())

        call Text_mkA("Terrain saved")

        return

    endif

endfunction





function SaveTerrainWithoutName takes nothing returns nothing

    if (terrainModifyWorking) then

        call Text_erA("can't execute two commands of this type simultaneously !")

        return

    endif

    call TriggerClearActions(gg_trg_Terrain_modifying_trig)

    call TriggerAddAction(gg_trg_Terrain_modifying_trig, function SaveTerrain_Actions)

    set terrainSave_id = 0

    set y = MAP_MIN_Y

    call EnableTrigger(gg_trg_Terrain_modifying_trig)

    set terrainModifyWorking = true

endfunction













    //load terrain

    

    

    

    

private function LoadTerrain_Actions takes nothing returns nothing

    local real x

    //local integer i = 1

    //loop

        //exitwhen (i > TERRAIN_MODIFYING_NB_LINES_TO_DO)

            set x = MAP_MIN_X

            loop

                exitwhen (x > MAP_MAX_X)

                    if (terrainSave[terrainSave_id] != 0) then

                        call ChangeTerrainType(x, y, terrainSave[terrainSave_id].getTerrainTypeId())

                    endif

                    set terrainSave_id = terrainSave_id + 1

                set x = x + LARGEUR_CASE

            endloop

            set y = y + LARGEUR_CASE

            if (y > MAP_MAX_Y) then

                call RestartEnabledCheckTerrainTriggers()

                call Text_mkA("Terrain loaded")

                call DisableTrigger(GetTriggeringTrigger())

                set terrainModifyWorking = false

                return

            endif

        //set i = i + 1

    //endloop    

endfunction







function LoadTerrainWithoutName takes nothing returns nothing

    if (terrainModifyWorking) then

        call Text_erA("can't execute two commands of this type simultaneously !")

        return

    endif

    call TriggerClearActions( gg_trg_Terrain_modifying_trig )

    call TriggerAddAction( gg_trg_Terrain_modifying_trig, function LoadTerrain_Actions )

    set terrainSave_id = 0

    set y = MAP_MIN_Y

    call EnableTrigger( gg_trg_Terrain_modifying_trig )

    set terrainModifyWorking = true

    call StopEnabledCheckTerrainTriggers()

endfunction 









endlibrary//===========================================================================

// Trigger: Save load terrain with name

//===========================================================================

//TESH.scrollpos=81

//TESH.alwaysfold=0

library SaveLoadTerrainWithName needs AllTerrainFunctions, TerrainModifyingTrig





globals

    private integer saveNameInt

    private hashtable terrainSaves = InitHashtable()

    private integer terrainSave_id

endglobals







    //save terrain

    



private function SaveTerrain_Actions takes nothing returns nothing

    local real x = MAP_MIN_X

    loop

        exitwhen (x > MAP_MAX_X)

        //call Text_A("avant")

            call SaveInteger(terrainSaves, saveNameInt, terrainSave_id, integer(udg_terrainTypes.getTerrainType(x, y)))

        //call Text_A("après")

            set terrainSave_id = terrainSave_id + 1

        set x = x + LARGEUR_CASE

    endloop

    

    set y = y + LARGEUR_CASE

    if (y > MAP_MAX_Y) then

        set terrainModifyWorking = false

        call DisableTrigger(GetTriggeringTrigger())

        call Text_mkA("Terrain saved")

        return

    endif

endfunction





function SaveTerrainWithName takes string saveName returns nothing

    if (terrainModifyWorking) then

        call Text_erA("can't execute two commands of this type simultaneously !")

        return

    endif

    set saveNameInt = StringHash(saveName)

    call TriggerClearActions(gg_trg_Terrain_modifying_trig)

    call TriggerAddAction(gg_trg_Terrain_modifying_trig, function SaveTerrain_Actions)

    set terrainSave_id = 0

    set y = MAP_MIN_Y

    call EnableTrigger(gg_trg_Terrain_modifying_trig)

    set terrainModifyWorking = true

endfunction





function DeleteTerrainSaveWithName takes string saveName returns boolean

    if (terrainModifyWorking) then

        call Text_erA("can't execute two commands of this type simultaneously !")

        return false

    endif

    set saveNameInt = StringHash(saveName)

    if (not HaveSavedInteger(terrainSaves, saveNameInt, 0)) then

        return false

    endif

    call FlushChildHashtable(terrainSaves, saveNameInt)

    return true

endfunction

    













    //load terrain

    

    

    

    

private function LoadTerrain_Actions takes nothing returns nothing

    local TerrainType terrainType

    local real x

    //local integer i = 1

    //loop

        //exitwhen (i > TERRAIN_MODIFYING_NB_LINES_TO_DO)

            set x = MAP_MIN_X

            loop

                exitwhen (x > MAP_MAX_X)

                    set terrainType = TerrainType(LoadInteger(terrainSaves, saveNameInt, terrainSave_id))

                    if (terrainType != 0) then

                        call ChangeTerrainType(x, y, terrainType.getTerrainTypeId())

                    endif

                    set terrainSave_id = terrainSave_id + 1

                set x = x + LARGEUR_CASE

            endloop

            set y = y + LARGEUR_CASE

            if (y > MAP_MAX_Y) then

                call RestartEnabledCheckTerrainTriggers()

                call Text_mkA("Terrain loaded")

                call DisableTrigger(GetTriggeringTrigger())

                set terrainModifyWorking = false

                return

            endif

        //set i = i + 1

    //endloop

endfunction







function LoadTerrainWithName takes string saveName returns boolean

    if (terrainModifyWorking) then

        call Text_erA("can't execute two commands of this type simultaneously !")

        return true

    endif

    set saveNameInt = StringHash(saveName)

    if (not HaveSavedInteger(terrainSaves, saveNameInt, 0)) then

        return false

    endif

    call TriggerClearActions(gg_trg_Terrain_modifying_trig)

    call TriggerAddAction(gg_trg_Terrain_modifying_trig, function LoadTerrain_Actions)

    set terrainSave_id = 0

    set y = MAP_MIN_Y

    call EnableTrigger(gg_trg_Terrain_modifying_trig)

    set terrainModifyWorking = true

    call StopEnabledCheckTerrainTriggers()

    return true

endfunction 











endlibrary//===========================================================================

// Trigger: struct StringArrayForCache

//===========================================================================

//TESH.scrollpos=45

//TESH.alwaysfold=0

library StringArrayForCache needs Text





globals    

    constant string CACHE_SEPARATEUR_ITEM = "("

    constant string CACHE_SEPARATEUR_PARAM = ","

    

    private constant integer MAX_STRING_LENGTH = 200

    StringArrayForCache stringArrayForCache = 0

endglobals





struct StringArrayForCache [8000]

    private string array stringArray [8000]

    private integer lastStringId

    private string category

    private string variableName

    private boolean avecSeparateur

    

    static method create takes string category, string variableName, boolean avecSeparateur returns StringArrayForCache

        local StringArrayForCache sa

        if (stringArrayForCache != 0) then

            call stringArrayForCache.destroy()

        endif

        set sa = StringArrayForCache.allocate()

        set sa.lastStringId = -1

        set sa.category = category

        set sa.variableName = variableName

        set sa.avecSeparateur = avecSeparateur

        return sa

    endmethod

    

    private method nextString takes nothing returns nothing

        set .lastStringId = .lastStringId + 1

        set .stringArray[.lastStringId] = ""

    endmethod

    

    method push takes string str returns nothing

        local integer length

        local integer nbCharsDispoForCurrentString

        if (.lastStringId == -1) then

            call .nextString()

        else

            if (StringLength(.stringArray[.lastStringId]) == MAX_STRING_LENGTH) then

                call .nextString()

            endif

            if (.avecSeparateur) then

                set .stringArray[.lastStringId] = .stringArray[.lastStringId] + CACHE_SEPARATEUR_ITEM

            endif

        endif

        set nbCharsDispoForCurrentString = MAX_STRING_LENGTH - StringLength(.stringArray[.lastStringId])

        set length = StringLength(str)

        loop

            exitwhen (length == 0)

                if (length > nbCharsDispoForCurrentString) then

                    set .stringArray[.lastStringId] = .stringArray[.lastStringId] + SubStringBJ(str, 1, nbCharsDispoForCurrentString)

                    call .nextString()

                    set str = SubStringBJ(str, nbCharsDispoForCurrentString + 1, length)

                else

                    set .stringArray[.lastStringId] = .stringArray[.lastStringId] + str

                    set str = ""

                endif

                set nbCharsDispoForCurrentString = MAX_STRING_LENGTH - StringLength(.stringArray[.lastStringId])

            set length = StringLength(str)

        endloop

    endmethod

    

    method writeInCache takes nothing returns nothing

        local integer i

        if (.lastStringId > 0) then

            set i = 0

            loop

                exitwhen (i > .lastStringId)

                    call StoreString(saveMap_cache, .category, .variableName + I2S(i), .stringArray[i])

                    //call Text_A(I2S(i) + " : " + .stringArray[i])

                    //call Text_A("longueur chaîne : " + I2S(StringLength(.stringArray[i])))

                set i = i + 1

            endloop

        else

            if (.lastStringId == 0) then

                call StoreString(saveMap_cache, .category, .variableName, .stringArray[0])

                call Text_A(.stringArray[0])

                call Text_A("longueur chaîne : " + I2S(StringLength(.stringArray[0])))

            endif

        endif

        call Text_A(.category + ", " + .variableName + " : finish write in cache")

    endmethod

endstruct







endlibrary//===========================================================================

// Trigger: Save terrain config

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library SaveTerrainConfigInCache needs Text









function SaveTerrainConfig takes nothing returns nothing

    call udg_terrainTypes.saveInCache()

    call Text_A("terrain configuration saved")

endfunction











endlibrary//===========================================================================

// Trigger: Save terrain

//===========================================================================

//TESH.scrollpos=66

//TESH.alwaysfold=0

library SaveTerrain needs Text, SaveMonsterTypes





globals

    private real y

    private integer array terrainTypeIds //16 au max

    private integer nbTerrainTypesUsed

endglobals





private function SaveTerrainsUsed takes nothing returns nothing

    local integer i

    set stringArrayForCache = StringArrayForCache.create("terrain", "terrainsUsed", false)

    set i = 0

    loop

        exitwhen (i >= nbTerrainTypesUsed)

            call stringArrayForCache.push(Ascii2String(terrainTypeIds[i]))

        set i = i + 1

    endloop

    call stringArrayForCache.writeInCache()

    call Text_A("terrains used saved")

endfunction



private function SaveMapDimensions takes nothing returns nothing

    local integer largeurMap = R2I((MAP_MAX_X - MAP_MIN_X)/LARGEUR_CASE)

    local integer hauteurMap = R2I((MAP_MAX_Y - MAP_MIN_Y)/LARGEUR_CASE)

    set stringArrayForCache = StringArrayForCache.create("terrain", "largeur", false)

    call stringArrayForCache.push(I2S(largeurMap))

    call stringArrayForCache.writeInCache()

    set stringArrayForCache = StringArrayForCache.create("terrain", "hauteur", false)

    call stringArrayForCache.push(I2S(hauteurMap))

    call stringArrayForCache.writeInCache()

    call Text_A("map dimensions saved")

endfunction





private function I2HexaString takes integer n returns string

    if (n < 10) then

        return I2S(n)

    endif

    if (n == 10) then

        return "A"

    endif

    if (n == 11) then

        return "B"

    endif

    if (n == 12) then

        return "C"

    endif

    if (n == 13) then

        return "D"

    endif

    if (n == 14) then

        return "E"

    endif

    if (n == 15) then

        return "F"

    endif

    return "0"

endfunction



//crée si besoin une nouvelle instance dans le tableau et retourne l'id de cet élément de tableau

private function GetTerrainId takes real x, real y returns string

    local integer terrainTypeId = GetTerrainType(x, y)

    local integer i = 0

    loop

        exitwhen (i >= nbTerrainTypesUsed)

            if (terrainTypeId == terrainTypeIds[i]) then

                return I2S(i)

            endif

        set i = i + 1

    endloop

    set terrainTypeIds[nbTerrainTypesUsed] = terrainTypeId

    set nbTerrainTypesUsed = nbTerrainTypesUsed + 1

    return I2HexaString(nbTerrainTypesUsed - 1)

endfunction





private function SaveTerrain_Actions takes nothing returns nothing

    local real x

    if (y <= MAP_MAX_Y) then

        set x = MAP_MIN_X

        loop

            exitwhen (x > MAP_MAX_X)

                call stringArrayForCache.push(GetTerrainId(x, y))

            set x = x + LARGEUR_CASE

        endloop

        set y = y + LARGEUR_CASE

    else

        call DisableTrigger(GetTriggeringTrigger())

        call stringArrayForCache.writeInCache()

        call Text_A("terrain saved")

        call SaveTerrainsUsed()

        call SaveMapDimensions()

        call StartSaveMonsterTypes()

    endif

endfunction





function StartSaveTerrain takes nothing returns nothing

    set y = MAP_MIN_Y

    set nbTerrainTypesUsed = 0

    set stringArrayForCache = StringArrayForCache.create("terrain", "terrain", false)

    call TriggerClearActions(trigSaveMapInCache)

    call TriggerAddAction(trigSaveMapInCache, function SaveTerrain_Actions)

    call EnableTrigger(trigSaveMapInCache)

endfunction











endlibrary//===========================================================================

// Trigger: Save monster types

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library SaveMonsterTypes needs Text, SaveLevels







function StartSaveMonsterTypes takes nothing returns nothing

    call udg_monsterTypes.saveInCache()

    call Text_A("monster types saved")

    call StartSaveLevels()

endfunction







endlibrary//===========================================================================

// Trigger: Save levels

//===========================================================================

//TESH.scrollpos=230

//TESH.alwaysfold=0

library SaveLevels needs Text



globals

    private integer levelId

    private Level level

    private integer visibilityId

    private integer monsterNoMoveId

    private integer monsterSimplePatrolId

    private integer monsterMultiplePatrolsId

    private integer meteorId

    private integer monsterSpawnId

    private constant integer NB_ITEM_TO_SAVE_EACH_TIME = 10

    private StartSaveNexLevel startSaveNexLevel

endglobals







//monsterSpawns

private function SaveMonsterSpawns_Actions takes nothing returns nothing

    local integer i = 0

    loop

        exitwhen (i >= NB_ITEM_TO_SAVE_EACH_TIME)

            if (monsterSpawnId > level.monsterSpawns.getLastInstanceId()) then

                call stringArrayForCache.writeInCache()

                call DisableTrigger(GetTriggeringTrigger())

                call startSaveNexLevel.go()

                return

            endif

            if (level.monsterSpawns.get(monsterSpawnId) != 0) then

                call stringArrayForCache.push(level.monsterSpawns.get(monsterSpawnId).toString())

            endif

            set monsterSpawnId = monsterSpawnId + 1

        set i = i + 1

    endloop

endfunction



private function StartSaveMonsterSpawns takes nothing returns nothing

    if (level.monsterSpawns.count() == 0) then

        call startSaveNexLevel.go()

    else

        set stringArrayForCache = StringArrayForCache.create("level" + I2S(levelId), "monsterSpawns", true)

        call TriggerClearActions(trigSaveMapInCache)

        call TriggerAddAction(trigSaveMapInCache, function SaveMonsterSpawns_Actions)

        call EnableTrigger(trigSaveMapInCache)

        set monsterSpawnId = 0

    endif

endfunction

///////////////////////////



//meteors

private function SaveMeteors_Actions takes nothing returns nothing

    local integer i = 0

    loop

        exitwhen (i >= NB_ITEM_TO_SAVE_EACH_TIME)

            if (meteorId > level.meteors.getLastInstanceId()) then

                call stringArrayForCache.writeInCache()

                call DisableTrigger(GetTriggeringTrigger())

                call StartSaveMonsterSpawns()

                return

            endif

            if (level.meteors.get(meteorId) != 0) then

                call stringArrayForCache.push(level.meteors.get(meteorId).toString())

            endif

            set meteorId = meteorId + 1

        set i = i + 1

    endloop

endfunction



private function StartSaveMeteors takes nothing returns nothing

    if (level.meteors.count() == 0) then

        call StartSaveMonsterSpawns()

    else

        set stringArrayForCache = StringArrayForCache.create("level" + I2S(levelId), "meteors", true)

        call TriggerClearActions(trigSaveMapInCache)

        call TriggerAddAction(trigSaveMapInCache, function SaveMeteors_Actions)

        call EnableTrigger(trigSaveMapInCache)

        set meteorId = 0

    endif

endfunction

///////////////////////////



//monsters multiple patrols

private function SaveMonstersMultiplePatrols_Actions takes nothing returns nothing

    local integer i = 0

    loop

        exitwhen (i >= NB_ITEM_TO_SAVE_EACH_TIME)

            if (monsterMultiplePatrolsId > level.monstersMultiplePatrols.getLastInstanceId()) then

                call stringArrayForCache.writeInCache()

                call DisableTrigger(GetTriggeringTrigger())

                call StartSaveMeteors()

                return

            endif

            if (level.monstersMultiplePatrols.get(monsterMultiplePatrolsId) != 0) then

                call stringArrayForCache.push(level.monstersMultiplePatrols.get(monsterMultiplePatrolsId).toString())

            endif

            set monsterMultiplePatrolsId = monsterMultiplePatrolsId + 1

        set i = i + 1

    endloop

endfunction



private function StartSaveMonstersMultiplePatrols takes nothing returns nothing

    if (level.monstersMultiplePatrols.count() == 0) then

        call StartSaveMeteors()

    else

        set stringArrayForCache = StringArrayForCache.create("level" + I2S(levelId), "monstersMultiplePatrols", true)

        call TriggerClearActions(trigSaveMapInCache)

        call TriggerAddAction(trigSaveMapInCache, function SaveMonstersMultiplePatrols_Actions)

        call EnableTrigger(trigSaveMapInCache)

        set monsterMultiplePatrolsId = 0

    endif

endfunction

///////////////////////////



//monsters simple patrol

private function SaveMonstersSimplePatrol_Actions takes nothing returns nothing

    local integer i = 0

    loop

        exitwhen (i >= NB_ITEM_TO_SAVE_EACH_TIME)

            if (monsterSimplePatrolId > level.monstersSimplePatrol.getLastInstanceId()) then

                call stringArrayForCache.writeInCache()

                call DisableTrigger(GetTriggeringTrigger())

                call StartSaveMonstersMultiplePatrols()

                return

            endif

            if (level.monstersSimplePatrol.get(monsterSimplePatrolId) != 0) then

                call stringArrayForCache.push(level.monstersSimplePatrol.get(monsterSimplePatrolId).toString())

            endif

            set monsterSimplePatrolId = monsterSimplePatrolId + 1

        set i = i + 1

    endloop

endfunction



private function StartSaveMonstersSimplePatrol takes nothing returns nothing

    if (level.monstersSimplePatrol.count() == 0) then

        call StartSaveMonstersMultiplePatrols()

    else

        set stringArrayForCache = StringArrayForCache.create("level" + I2S(levelId), "monstersSimplePatrol", true)

        call TriggerClearActions(trigSaveMapInCache)

        call TriggerAddAction(trigSaveMapInCache, function SaveMonstersSimplePatrol_Actions)

        call EnableTrigger(trigSaveMapInCache)

        set monsterSimplePatrolId = 0

    endif

endfunction

///////////////////////////



//monsters no move

private function SaveMonstersNoMove_Actions takes nothing returns nothing

    local integer i = 0

    loop

        exitwhen (i >= NB_ITEM_TO_SAVE_EACH_TIME)

            if (monsterNoMoveId > level.monstersNoMove.getLastInstanceId()) then

                call stringArrayForCache.writeInCache()

                call DisableTrigger(GetTriggeringTrigger())

                call StartSaveMonstersSimplePatrol()

                return

            endif

            if (level.monstersNoMove.get(monsterNoMoveId) != 0) then

                call stringArrayForCache.push(level.monstersNoMove.get(monsterNoMoveId).toString())

            endif

            set monsterNoMoveId = monsterNoMoveId + 1

        set i = i + 1

    endloop

endfunction



private function StartSaveMonstersNoMove takes nothing returns nothing

    if (level.monstersNoMove.count() == 0) then

        call StartSaveMonstersSimplePatrol()

    else

        set stringArrayForCache = StringArrayForCache.create("level" + I2S(levelId), "monstersNoMove", true)

        call TriggerClearActions(trigSaveMapInCache)

        call TriggerAddAction(trigSaveMapInCache, function SaveMonstersNoMove_Actions)

        call EnableTrigger(trigSaveMapInCache)

        set monsterNoMoveId = 0

    endif

endfunction

///////////////////////////



//visibilities

private function SaveVisibilities_Actions takes nothing returns nothing

    local integer i = 0

    loop

        exitwhen (i >= NB_ITEM_TO_SAVE_EACH_TIME)

            if (visibilityId > level.visibilities.getLastInstanceId()) then

                call stringArrayForCache.writeInCache()

                call DisableTrigger(GetTriggeringTrigger())

                call StartSaveMonstersNoMove()

                return

            endif

            if (level.visibilities.get(visibilityId) != 0) then

                call stringArrayForCache.push(level.visibilities.get(visibilityId).toString())

            endif

            set visibilityId = visibilityId + 1

        set i = i + 1

    endloop

endfunction



private function StartSaveVisibilities takes nothing returns nothing

    if (level.visibilities.count() == 0) then

        call StartSaveMonstersNoMove()

    else

        set stringArrayForCache = StringArrayForCache.create("level" + I2S(levelId), "visibilities", true)

        call TriggerClearActions(trigSaveMapInCache)

        call TriggerAddAction(trigSaveMapInCache, function SaveVisibilities_Actions)

        call EnableTrigger(trigSaveMapInCache)

        set visibilityId = 0

    endif

endfunction

///////////////////////////









private function EndSaveLevel takes nothing returns nothing

    call Text_A("all levels saved")

    call SaveGameCache(saveMap_cache)

    call Text_A("SAVING MAP FINISHED")

endfunction



private function StartSaveLevel takes nothing returns nothing

    set level = udg_levels.get(levelId)

    if (level == 0) then

        call EndSaveLevel()

    else

        //start message

        if (level.getStartMessage() != null and level.getStartMessage() != "") then

            set stringArrayForCache = StringArrayForCache.create("level" + I2S(levelId), "startMessage", false)

            call stringArrayForCache.push(level.getStartMessage())

            call stringArrayForCache.writeInCache()

        endif

        //nb lives earned

        set stringArrayForCache = StringArrayForCache.create("level" + I2S(levelId), "nbLives", false)

        call stringArrayForCache.push(I2S(level.getNbLives()))

        call stringArrayForCache.writeInCache()

        //start

        if (level.getStart() != 0) then

            set stringArrayForCache = StringArrayForCache.create("level" + I2S(levelId), "start", false)

            call stringArrayForCache.push(level.getStart().toString())

            call stringArrayForCache.writeInCache()

        endif

        //end

        if (level.getEnd() != 0) then

            set stringArrayForCache = StringArrayForCache.create("level" + I2S(levelId), "end", false)

            call stringArrayForCache.push(level.getEnd().toString())

            call stringArrayForCache.writeInCache()

        endif

        //reste :      //visibilities  

        //monstersNoMove  //monstersSimplePatrol  //monstersMultiplePatrols  //meteors  //monsterSpawns

        call StartSaveVisibilities()        

    endif

endfunction



function StartSaveLevels takes nothing returns nothing

    local integer i = 0

    loop

        exitwhen (i > 11)

            if (udg_escapers.get(i) != 0) then

                call udg_escapers.get(i).destroyMake()

                call udg_escapers.get(i).destroyAllSavedActions()

            endif

        set i = i + 1

    endloop

    set levelId = 0

    call StartSaveLevel()

endfunction





struct StartSaveNexLevel

    method go takes nothing returns nothing

        set levelId = levelId + 1

        call StartSaveLevel()

    endmethod

endstruct









endlibrary

//===========================================================================

// Trigger: SAVE MAP in cache

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library SaveMapInCache initializer Init_SaveMapInCache needs SaveTerrainConfigInCache, SaveTerrain









globals

    gamecache saveMap_cache

    trigger trigSaveMapInCache

endglobals







function StartSaveMapInCache takes nothing returns nothing

    local integer i

    call Text_A("starting saving map in gamecache \"epicSlide\"...")

    call FlushStoredMission(saveMap_cache, "terrain")

    call FlushStoredMission(saveMap_cache, "monsterTypes")

    set i = 0

    loop

        exitwhen (i >= NB_MAX_LEVELS)

            call FlushStoredMission(saveMap_cache, "level" + I2S(i))

        set i = i + 1

    endloop

    call SaveTerrainConfig()

    call StartSaveTerrain()

endfunction









//===========================================================================

function Init_SaveMapInCache takes nothing returns nothing

    set saveMap_cache = InitGameCache("epicSlide")

    set trigSaveMapInCache = CreateTrigger()

    call DisableTrigger(trigSaveMapInCache)

    call TriggerRegisterTimerEvent(trigSaveMapInCache, LOW_PERIOD_FOR_WORK, true)

endfunction







endlibrary//===========================================================================

// Trigger: Init lives

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

globals

    Lives udg_lives = 0

endglobals





function Trig_init_lives_Actions takes nothing returns nothing

    set udg_lives = Lives.create()

endfunction







//===========================================================================

function InitTrig_Init_lives takes nothing returns nothing

    set gg_trg_Init_lives = CreateTrigger()

    call TriggerAddAction(gg_trg_Init_lives, function Trig_init_lives_Actions)

    call TriggerRegisterTimerEvent(gg_trg_Init_lives, 0.0001, false)

endfunction



//===========================================================================

// Trigger: Init escapers

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

globals

    EscaperArray udg_escapers = 0

endglobals









//===========================================================================

function InitTrig_Init_escapers takes nothing returns nothing

    set udg_escapers = EscaperArray.create()

endfunction



//===========================================================================

// Trigger: Init struct levels

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

globals

    LevelArray udg_levels = 0

endglobals



//===========================================================================

function InitTrig_Init_struct_levels takes nothing returns nothing

    if (udg_levels == 0) then

        set udg_levels = LevelArray.create()

    endif

endfunction



//===========================================================================

// Trigger: Forces ally

//===========================================================================

function Trig_Forces_ally_Actions takes nothing returns nothing

    set bj_forLoopAIndex = 1

    set bj_forLoopAIndexEnd = 12

    loop

        exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd

        call SetPlayerAllianceStateBJ( Player(0), ConvertedPlayer(GetForLoopIndexA()), bj_ALLIANCE_ALLIED_VISION )

        call SetPlayerAllianceStateBJ( ConvertedPlayer(GetForLoopIndexA()), Player(0), bj_ALLIANCE_ALLIED_VISION )

        set bj_forLoopAIndex = bj_forLoopAIndex + 1

    endloop

endfunction



//===========================================================================

function InitTrig_Forces_ally takes nothing returns nothing

    set gg_trg_Forces_ally = CreateTrigger(  )

    call TriggerAddAction( gg_trg_Forces_ally, function Trig_Forces_ally_Actions )

endfunction



//===========================================================================

// Trigger: Camera

//===========================================================================

function Trig_Camera_Actions takes nothing returns nothing

    call SetCameraField( CAMERA_FIELD_TARGET_DISTANCE, DEFAULT_CAMERA_FIELD, 0 )

endfunction



//===========================================================================

function InitTrig_Camera takes nothing returns nothing

    set gg_trg_Camera = CreateTrigger(  )

    call TriggerAddAction( gg_trg_Camera, function Trig_Camera_Actions )

endfunction



//===========================================================================

// Trigger: No selection circle

//===========================================================================

function Trig_No_selection_circle_Actions takes nothing returns nothing

    call EnableSelect( true, false )

endfunction



//===========================================================================

function InitTrig_No_selection_circle takes nothing returns nothing

    set gg_trg_No_selection_circle = CreateTrigger(  )

    call TriggerRegisterGameLoadedEventBJ( gg_trg_No_selection_circle )

    call TriggerAddAction( gg_trg_No_selection_circle, function Trig_No_selection_circle_Actions )

endfunction



//===========================================================================

// Trigger: Allways day

//===========================================================================

function Trig_Allways_day_Actions takes nothing returns nothing

    call SetTimeOfDay( 12 )

    call UseTimeOfDayBJ( false )

endfunction



//===========================================================================

function InitTrig_Allways_day takes nothing returns nothing

    set gg_trg_Allways_day = CreateTrigger(  )

    call TriggerAddAction( gg_trg_Allways_day, function Trig_Allways_day_Actions )

endfunction



//===========================================================================

// Trigger: Start sound

//===========================================================================

function Trig_Start_sound_Actions takes nothing returns nothing

    call PlaySoundBJ( gg_snd_start )

endfunction



//===========================================================================

function InitTrig_Start_sound takes nothing returns nothing

    set gg_trg_Start_sound = CreateTrigger(  )

    call TriggerRegisterTimerEventSingle( gg_trg_Start_sound, 2.00 )

    call TriggerAddAction( gg_trg_Start_sound, function Trig_Start_sound_Actions )

endfunction



//===========================================================================

// Trigger: Heroes

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library Heroes initializer Init_Heroes needs Escaper





globals

    location array startPositions

    location array startPositionsRandomized

    integer array playerIdsRandomized

    

    constant real TIME_BEFORE_HERO_SPAWN = 3.

    constant real TIME_BETWEEN_EACH_HERO_SPAWN = 0.3

    constant real HERO_START_ANGLE = 90.

    constant string EFFECT_FOR_MISSING_HEROES = "Abilities\\Spells\\Undead\\DeathPact\\DeathPactTarget.mdl"

endglobals





function RandomizeStartPositionsAndHeroSpawnOrder takes nothing returns nothing

    local boolean array alreadyAdded

    local integer n

    local integer i

    

//randomize start positions

    set i = 0

    loop

        exitwhen (i > 11)

            loop

                set n = GetRandomInt(0, 11)

                exitwhen (not alreadyAdded[n])

            endloop

            set startPositionsRandomized[i] = startPositions[n]

            set alreadyAdded[n] = true

        set i = i + 1

    endloop

    

//reinit alreadyAdded to false

    set i = 0

    loop

        exitwhen (i > 11)

            set alreadyAdded[i] = false

        set i = i + 1

    endloop

    

//randomize hero spawn order

    set i = 0

    loop

        exitwhen (i > 11)

            loop

                set n = GetRandomInt(0, 11)

                exitwhen (not alreadyAdded[n])

            endloop

            set playerIdsRandomized[i] = n

            set alreadyAdded[n] = true

        set i = i + 1

    endloop

endfunction







function Trig_heroes_Actions takes nothing returns nothing

    local boolean array alreadyAdded

    local effect anEffect

    local integer i

    local integer n



//randomize start positions

    call RandomizeStartPositionsAndHeroSpawnOrder()

    

//create heroes

    call ClearSelection()

    set i = 0

    loop

        exitwhen (i > 11)

            set n = playerIdsRandomized[i]

            if (udg_escapers.get(i) != 0) then

                call udg_escapers.get(i).createHero(GetLocationX(startPositionsRandomized[n]), GetLocationY(startPositionsRandomized[n]), HERO_START_ANGLE)

            else

                set anEffect = AddSpecialEffectLoc(EFFECT_FOR_MISSING_HEROES, startPositionsRandomized[n])

                call DestroyEffect(anEffect)

            endif

            set startPositionsRandomized[n] = null

            call TriggerSleepAction(TIME_BETWEEN_EACH_HERO_SPAWN)

        set i = i + 1

    endloop

    //call EnableTrigger(gg_trg_anticheat_teleport_and_revive)

    //set AnticheatTeleport_justRevived = true

    set anEffect = null

endfunction



//===========================================================================

function Init_Heroes takes nothing returns nothing

//define start positions

    local real minX = GetRectMinX(gg_rct_departLvl_0) + 200

    local real minY = GetRectMinY(gg_rct_departLvl_0) + 100

    local real diffX = (GetRectMaxX(gg_rct_departLvl_0) - minX) / 3

    local real diffY = (GetRectMaxY(gg_rct_departLvl_0) - minY) / 4

    local integer i = 0

    local integer j = 0

    local integer n = 0

    loop

        exitwhen (i > 2)

        loop

            exitwhen (j > 3)

                set startPositions[n] = Location(minX + diffX * j, minY + diffY * i)

            set n = n + 1

            set j = j + 1

        endloop

        set j = 0

        set i = i + 1

    endloop

    

    set gg_trg_Heroes = CreateTrigger()

    call TriggerAddAction(gg_trg_Heroes, function Trig_heroes_Actions)

    call TriggerRegisterTimerEvent(gg_trg_Heroes, TIME_BEFORE_HERO_SPAWN, false)

endfunction





endlibrary

//===========================================================================

// Trigger: Command shortcuts functions

//===========================================================================

//TESH.scrollpos=124

//TESH.alwaysfold=0

library CommandShortcuts needs BasicFunctions





globals

    string array A_shortcutCommand

    string array Z_shortcutCommand

    string array E_shortcutCommand

    string array R_shortcutCommand

    string array Q_shortcutCommand

    string array S_shortcutCommand

    string array D_shortcutCommand

    string array F_shortcutCommand

endglobals







function InitShortcutSkills takes integer playerId returns nothing

    local unit hero = udg_escapers.get(playerId).getHero()

    

    //! textmacro InitShortcut takes shortcut

    if ($shortcut$_shortcutCommand[playerId] == null) then

        call UnitRemoveAbility(hero, 'SC$shortcut$o')

        call UnitAddAbility(hero, 'SC$shortcut$u')

    else

        call UnitRemoveAbility(hero, 'SC$shortcut$u')

        call UnitAddAbility(hero, 'SC$shortcut$o')

    endif

    //! endtextmacro



    //! runtextmacro InitShortcut("A")

    //! runtextmacro InitShortcut("Z")

    //! runtextmacro InitShortcut("E")

    //! runtextmacro InitShortcut("R")

    //! runtextmacro InitShortcut("Q")

    //! runtextmacro InitShortcut("S")

    //! runtextmacro InitShortcut("D")

    //! runtextmacro InitShortcut("F")

    

    set hero = null

endfunction







function AssignShortcut takes integer playerId, string shortcut, string command returns nothing

    local unit hero = udg_escapers.get(playerId).getHero()

    set shortcut = StringCase(shortcut, true)

    

    //! textmacro AssignShortcut takes shortcut

    if (shortcut == "$shortcut$") then

        if ($shortcut$_shortcutCommand[playerId] == null) then

            call UnitRemoveAbility(hero, 'SC$shortcut$u')

            call UnitAddAbility(hero, 'SC$shortcut$o')

        endif

        set $shortcut$_shortcutCommand[playerId] = "-" + command

        return

    endif

    //! endtextmacro



    //! runtextmacro AssignShortcut("A")

    //! runtextmacro AssignShortcut("Z")

    //! runtextmacro AssignShortcut("E")

    //! runtextmacro AssignShortcut("R")

    //! runtextmacro AssignShortcut("Q")

    //! runtextmacro AssignShortcut("S")

    //! runtextmacro AssignShortcut("D")

    //! runtextmacro AssignShortcut("F")

    

    set hero = null

endfunction





function UnassignShortcut takes integer playerId, string shortcut returns nothing

    local unit hero = udg_escapers.get(playerId).getHero()

    set shortcut = StringCase(shortcut, true)

    

    //! textmacro UnassignShortcut takes shortcut

    if (shortcut == "$shortcut$") then

        if ($shortcut$_shortcutCommand[playerId] != null) then

            call UnitRemoveAbility(hero, 'SC$shortcut$o')

            call UnitAddAbility(hero, 'SC$shortcut$u')

            set $shortcut$_shortcutCommand[playerId] = null

        endif

        return

    endif

    //! endtextmacro



    //! runtextmacro UnassignShortcut("A")

    //! runtextmacro UnassignShortcut("Z")

    //! runtextmacro UnassignShortcut("E")

    //! runtextmacro UnassignShortcut("R")

    //! runtextmacro UnassignShortcut("Q")

    //! runtextmacro UnassignShortcut("S")

    //! runtextmacro UnassignShortcut("D")

    //! runtextmacro UnassignShortcut("F")

    

    set hero = null

endfunction





function IsShortcut takes string S returns boolean

    set S = StringCase(S, true)

    //! textmacro IsShortcut takes shortcut

    if (S == "$shortcut$") then

        return true

    endif

    //! endtextmacro



    //! runtextmacro IsShortcut("A")

    //! runtextmacro IsShortcut("Z")

    //! runtextmacro IsShortcut("E")

    //! runtextmacro IsShortcut("R")

    //! runtextmacro IsShortcut("Q")

    //! runtextmacro IsShortcut("S")

    //! runtextmacro IsShortcut("D")

    //! runtextmacro IsShortcut("F")



    return false

endfunction







function GetStringAssignedFromCommand takes string command returns string

    local string outputStr

    local boolean spaceFound = false

    local integer cmdLength = StringLength(command)

    local integer charId = 3

    loop

        exitwhen (charId >= cmdLength)

            if (SubStringBJ(command, charId, charId) == " ") then

                if (not spaceFound) then

                    set spaceFound = true

                else

                    set outputStr = SubStringBJ(command, charId + 1, cmdLength)

                    if (SubStringBJ(outputStr, 1, 1) == "(" and SubStringBJ(outputStr, StringLength(outputStr), StringLength(outputStr)) == ")") then

                        set outputStr = SubStringBJ(outputStr, 2, StringLength(outputStr) - 1)

                    endif

                    return outputStr

                endif

            endif

        set charId = charId + 1

    endloop

    return null

endfunction







function DisplayShortcuts takes integer playerId returns nothing

    call Text_P(Player(playerId), " ")

    call Text_P(Player(playerId), udg_colorCode[playerId] + "Your shortcuts:")

    //! textmacro ShowShortcut takes shortcut

    if ($shortcut$_shortcutCommand[playerId] == null) then

        call Text_P(Player(playerId), udg_colorCode[playerId] + "$shortcut$: |r" + udg_colorCode[GREY] + "none")

    else

        call Text_P(Player(playerId), udg_colorCode[playerId] + "$shortcut$: |r" + $shortcut$_shortcutCommand[playerId])

    endif

    //! endtextmacro



    //! runtextmacro ShowShortcut("A")

    //! runtextmacro ShowShortcut("Z")

    //! runtextmacro ShowShortcut("E")

    //! runtextmacro ShowShortcut("R")

    //! runtextmacro ShowShortcut("Q")

    //! runtextmacro ShowShortcut("S")

    //! runtextmacro ShowShortcut("D")

    //! runtextmacro ShowShortcut("F")

endfunction







endlibrary

//===========================================================================

// Trigger: Using shortcut

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

function Trig_using_shortcut_Conditions takes nothing returns boolean

    return IsHero(GetTriggerUnit())

endfunction







function Trig_using_shortcut_Actions takes nothing returns nothing

    local Escaper escaper = Hero2Escaper(GetTriggerUnit())

    local player p = escaper.getPlayer()

    

    //! textmacro UsingShortcut takes shortcut

    if (GetSpellAbilityId() == 'SC$shortcut$o') then

        call Text_P(p, udg_colorCode[GetPlayerId(p)] + GetPlayerName(p) + ":|r " + $shortcut$_shortcutCommand[GetPlayerId(p)])

        call ExecuteCommand(escaper, $shortcut$_shortcutCommand[GetPlayerId(p)])

        return

    endif

    //! endtextmacro



    //! runtextmacro UsingShortcut("A")

    //! runtextmacro UsingShortcut("Z")

    //! runtextmacro UsingShortcut("E")

    //! runtextmacro UsingShortcut("R")

    //! runtextmacro UsingShortcut("Q")

    //! runtextmacro UsingShortcut("S")

    //! runtextmacro UsingShortcut("D")

    //! runtextmacro UsingShortcut("F")

endfunction





//===========================================================================

function InitTrig_Using_shortcut takes nothing returns nothing

    set gg_trg_Using_shortcut = CreateTrigger(  )

    call TriggerRegisterAnyUnitEventBJ( gg_trg_Using_shortcut, EVENT_PLAYER_UNIT_SPELL_CAST )

    call TriggerAddCondition( gg_trg_Using_shortcut, Condition( function Trig_using_shortcut_Conditions ) )

    call TriggerAddAction( gg_trg_Using_shortcut, function Trig_using_shortcut_Actions )

endfunction



//===========================================================================

// Trigger: Camera reset

//===========================================================================

function Trig_Camera_reset_Actions takes nothing returns nothing

    local player TP = GetTriggerPlayer()

    local integer TPN = GetPlayerId(TP)

    call udg_escapers.get(TPN).resetCamera()

endfunction



//===========================================================================

function InitTrig_Camera_reset takes nothing returns nothing

    set gg_trg_Camera_reset = CreateTrigger(  )

    call TriggerRegisterPlayerEventEndCinematic( gg_trg_Camera_reset, Player(0) )

    call TriggerRegisterPlayerEventEndCinematic( gg_trg_Camera_reset, Player(1) )

    call TriggerRegisterPlayerEventEndCinematic( gg_trg_Camera_reset, Player(2) )

    call TriggerRegisterPlayerEventEndCinematic( gg_trg_Camera_reset, Player(3) )

    call TriggerRegisterPlayerEventEndCinematic( gg_trg_Camera_reset, Player(4) )

    call TriggerRegisterPlayerEventEndCinematic( gg_trg_Camera_reset, Player(5) )

    call TriggerRegisterPlayerEventEndCinematic( gg_trg_Camera_reset, Player(6) )

    call TriggerRegisterPlayerEventEndCinematic( gg_trg_Camera_reset, Player(7) )

    call TriggerRegisterPlayerEventEndCinematic( gg_trg_Camera_reset, Player(8) )

    call TriggerRegisterPlayerEventEndCinematic( gg_trg_Camera_reset, Player(9) )

    call TriggerRegisterPlayerEventEndCinematic( gg_trg_Camera_reset, Player(10) )

    call TriggerRegisterPlayerEventEndCinematic( gg_trg_Camera_reset, Player(11) )

    call TriggerAddAction( gg_trg_Camera_reset, function Trig_Camera_reset_Actions )

endfunction



//===========================================================================

// Trigger: Apm

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library Apm initializer Init_Apm needs BasicFunctions





globals

    integer array nbClicsOnSlide

    real array timeOnSlide

endglobals







function Init_Apm takes nothing returns nothing

    local integer i = 0

    loop

        exitwhen (i > 11)

            set nbClicsOnSlide[i] = 0

            set timeOnSlide[i] = 0.

        set i = i + 1

    endloop

endfunction







function DisplayApm takes integer playerId returns nothing

    local real time = timeOnSlide[playerId]

    local integer clics 

    local integer apm

    if (time > 0.) then

        set clics = nbClicsOnSlide[playerId]

        set apm = R2I(I2R(clics) * 60. / time)

        call Text_P(Player(playerId), udg_colorCode[playerId] + "clics : " + I2S(clics) + ",  time : " + I2S(R2I(time)) + ",  apm : " + I2S(apm))

    else

        call Text_P(Player(playerId), udg_colorCode[playerId] + "unknown")

    endif

endfunction





function DisplayApmAll takes integer playerId returns nothing

    local integer clics

    local real time

    local integer apm

    

    local integer i = 0

    loop

        exitwhen (i > 11)

            if (udg_escapers.get(i) != 0) then

                set time = timeOnSlide[i]

                if (time > 0.) then

                    set clics = nbClicsOnSlide[i]

                    set apm = R2I( I2R(clics) * 60. / time )

                    call Text_P(Player(playerId), udg_colorCode[i] + GetPlayerName(Player(i)) + ":  clics : " + I2S(clics) + ",  time : " + I2S(R2I(time)) + ",  apm : " + I2S(apm))

                else

                    call Text_P(Player(playerId), udg_colorCode[i] + GetPlayerName(Player(i)) + ":  unknown")

                endif

            endif

        set i = i + 1

    endloop

endfunction





endlibrary//===========================================================================

// Trigger: Afk mode

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

library AfkMode initializer Init_AfkMode







globals

    real timeMinAfk = 30.

    private constant real Z = -50.

    private constant real SIZE = 8.

    private constant real TRANSPARENCY = 0.

    

    boolean array isAfk

    timer array afkModeTimers

    texttag array afkModeTextTags

    timer killAllAfkTimer = CreateTimer()

endglobals





function AreAllAliveHeroesAfk takes nothing returns boolean //false if noone is dead

    local boolean someoneAlive = false

    local boolean someoneDead = false

    local integer i = 0

    loop

        exitwhen (i > 11)

            if (udg_escapers.get(i).getHero() != null) then

                if (IsUnitAliveBJ(udg_escapers.get(i).getHero())) then

                    set someoneAlive = true

                    if (not isAfk[i]) then

                        return false

                    endif

                else

                    set someoneDead = true

                endif

            endif

        set i = i + 1

    endloop

    return someoneAlive and someoneDead

endfunction





function KillAllHeroesIfAfk takes nothing returns nothing

    local integer i = 0    

    if (AreAllAliveHeroesAfk()) then

        loop

            exitwhen (i > 11)

                if (IsUnitAliveBJ(udg_escapers.get(i).getHero()) and isAfk[i]) then

                    call udg_escapers.get(i).kill()

                endif

            set i = i + 1

        endloop

    endif

endfunction





function KillAllHeroesAfkInFiveSeconds takes nothing returns nothing

    call TimerStart(killAllAfkTimer, 5., false, function KillAllHeroesIfAfk)

endfunction





function SetAfkMode takes integer playerId returns nothing

    if (afkModeTextTags[playerId] != null) then

        call DestroyTextTag(afkModeTextTags[playerId])

    endif

    set afkModeTextTags[playerId] = CreateTextTagUnitBJ( udg_colorCode[playerId]+"AFK", udg_escapers.get(playerId).getHero(), Z, SIZE, 100, 100, 100, TRANSPARENCY )

    set isAfk[playerId] = true

endfunction





function StopAfk takes integer playerId returns nothing

    if (isAfk[playerId]) then

        set isAfk[playerId] = false

        call DestroyTextTag(afkModeTextTags[playerId])

        set afkModeTextTags[playerId] = null

    endif

endfunction





//! textmacro AfkModeTimerExpires takes id

function AfkModeTimerExpires_$id$ takes nothing returns nothing

    call SetAfkMode($id$)

    if (AreAllAliveHeroesAfk()) then

        call KillAllHeroesAfkInFiveSeconds()

    endif

endfunction

//! endtextmacro



//! runtextmacro AfkModeTimerExpires("0")

//! runtextmacro AfkModeTimerExpires("1")

//! runtextmacro AfkModeTimerExpires("2")

//! runtextmacro AfkModeTimerExpires("3")

//! runtextmacro AfkModeTimerExpires("4")

//! runtextmacro AfkModeTimerExpires("5")

//! runtextmacro AfkModeTimerExpires("6")

//! runtextmacro AfkModeTimerExpires("7")

//! runtextmacro AfkModeTimerExpires("8")

//! runtextmacro AfkModeTimerExpires("9")

//! runtextmacro AfkModeTimerExpires("10")

//! runtextmacro AfkModeTimerExpires("11")





function GetAfkModeTimeExpiresCodeFromId takes integer id returns code

    //! textmacro GetAfkModeTimeExpiresCodeFromId takes id

    if (id == $id$) then

        return function AfkModeTimerExpires_$id$

    endif

    //! endtextmacro

    

    //! runtextmacro GetAfkModeTimeExpiresCodeFromId("0")

    //! runtextmacro GetAfkModeTimeExpiresCodeFromId("1")

    //! runtextmacro GetAfkModeTimeExpiresCodeFromId("2")

    //! runtextmacro GetAfkModeTimeExpiresCodeFromId("3")

    //! runtextmacro GetAfkModeTimeExpiresCodeFromId("4")

    //! runtextmacro GetAfkModeTimeExpiresCodeFromId("5")

    //! runtextmacro GetAfkModeTimeExpiresCodeFromId("6")

    //! runtextmacro GetAfkModeTimeExpiresCodeFromId("7")

    //! runtextmacro GetAfkModeTimeExpiresCodeFromId("8")

    //! runtextmacro GetAfkModeTimeExpiresCodeFromId("9")

    //! runtextmacro GetAfkModeTimeExpiresCodeFromId("10")

    //! runtextmacro GetAfkModeTimeExpiresCodeFromId("11")

    

    return null

endfunction





//===========================================================================

function Init_AfkMode takes nothing returns nothing

    local integer i = 0

    loop

        exitwhen i > 11

            set afkModeTimers[i] = CreateTimer()

            set isAfk[i] = false

            set afkModeTextTags[i] = null

        set i = i + 1

    endloop

endfunction





endlibrary



//===========================================================================

// Trigger: Afk mode ordre recu

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

function Trig_afk_mode_ordre_recu_Actions takes nothing returns nothing

    local integer n

    if (IsHero(GetTriggerUnit())) then

        set n = GetUnitUserData(GetTriggerUnit())

        call StopAfk(n)

        call TimerStart(afkModeTimers[n], timeMinAfk, false, GetAfkModeTimeExpiresCodeFromId(n))

    endif

endfunction



//===========================================================================

function InitTrig_Afk_mode_ordre_recu takes nothing returns nothing

    set gg_trg_Afk_mode_ordre_recu = CreateTrigger(  )

    call TriggerRegisterAnyUnitEventBJ( gg_trg_Afk_mode_ordre_recu, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER )

    call TriggerRegisterAnyUnitEventBJ( gg_trg_Afk_mode_ordre_recu, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER )

    call TriggerAddAction( gg_trg_Afk_mode_ordre_recu, function Trig_afk_mode_ordre_recu_Actions )

endfunction



//===========================================================================

// Trigger: A player leaves

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

function Trig_a_player_leaves_Actions takes nothing returns nothing

    local integer n = GetPlayerId(GetTriggerPlayer())

    call udg_escapers.remove(n)

    call StopAfk(n)

    call DisplayTextToForce(GetPlayersAll(), udg_colorCode[n] + "This is too difficult for " + GetPlayerName(GetTriggerPlayer()) + ", (s)he has left the game." )

    call StartSound(gg_snd_noob)

    //set NbPlayersMinimumThree_nbPlayers = NbPlayersMinimumThree_nbPlayers - 1

endfunction







//===========================================================================

function InitTrig_A_player_leaves takes nothing returns nothing

    local integer i = 0

    set gg_trg_A_player_leaves = CreateTrigger()

    loop

        exitwhen i > 11

        call TriggerRegisterPlayerEventLeave(gg_trg_A_player_leaves, Player(i))

        set i = i + 1

    endloop       

    call TriggerAddAction( gg_trg_A_player_leaves, function Trig_a_player_leaves_Actions )

endfunction



//===========================================================================

// Trigger: InvisUnit is getting damage

//===========================================================================

//TESH.scrollpos=13

//TESH.alwaysfold=0

//évènement ajouté à la création de l'unité invisible



function Trig_invisUnit_dies_Actions takes nothing returns nothing

    local unit invisUnit = GetTriggerUnit()

    local integer n = GetUnitUserData(invisUnit)

    local Escaper escaper = udg_escapers.get(n)

    local unit killingUnit = GetEventDamageSource()

    local string effectStr

    local effect eff

    local real x

    local real y

    

    if (not escaper.isAlive()) then

        set invisUnit = null

        set killingUnit = null

        return

    endif



    if (escaper.isGodModeOn()) then

        if (escaper.doesGodModeKills()) then

            if(GetUnitUserData(killingUnit) != 0)then

                call Monster(GetUnitUserData(killingUnit)).killUnit() //on ne tue pas directement le monstre, pour pouvoir exécuter des actions secondaires

            else

                call KillUnit(killingUnit)

            endif

        endif

        set x = GetUnitX(killingUnit)

        set y = GetUnitY(killingUnit)

        set eff = AddSpecialEffect(GM_KILLING_EFFECT, x, y)

        call DestroyEffect(eff)

        set eff = null

        set invisUnit = null

        set killingUnit = null

        return  

    endif



    call escaper.kill()



    //effet de tuation du héros par le monstre, suivant le type du monstre

    set effectStr = udg_monsterTypes.monsterUnit2KillEffectStr(killingUnit)

    if (effectStr != null) then

        set x = GetUnitX(invisUnit)

        set y = GetUnitY(invisUnit)

        set eff = AddSpecialEffect(effectStr, x, y)

        call TriggerSleepAction(3)

        call DestroyEffect(eff)

        set eff = null

    endif



    set invisUnit = null

    set killingUnit = null

endfunction



//===========================================================================

function InitTrig_InvisUnit_is_getting_damage takes nothing returns nothing

    set gg_trg_InvisUnit_is_getting_damage = CreateTrigger()

    call TriggerAddAction(gg_trg_InvisUnit_is_getting_damage, function Trig_invisUnit_dies_Actions)

endfunction



//===========================================================================

// Trigger: A hero dies check if all dead and sounds

//===========================================================================

//TESH.scrollpos=24

//TESH.alwaysfold=0

globals

    integer udg_nbKilled = 0

endglobals





function Trig_a_hero_dies_Conditions takes nothing returns boolean

    return IsHero(GetTriggerUnit())

endfunction





function Trig_a_hero_dies_Actions takes nothing returns nothing

    local integer n = GetUnitUserData(GetTriggerUnit())

    local integer nbAlive = 0

    local boolean last = false

    local integer i



    set udg_nbKilled = udg_nbKilled + 1

    if (udg_nbKilled == 3 and udg_tripleKillSoundOn) then

        call StartSound(gg_snd_multisquish)

        set udg_nbKilled = 0

    endif



    set i = 0

    loop

        exitwhen (i > 11)

            if (udg_escapers.get(i).isAlive()) then

                set nbAlive = nbAlive + 1

            endif

        set i = i + 1

    endloop



    if (nbAlive == 0) then

        call TriggerExecute(gg_trg_Lose_a_life_and_res)

        call TriggerSleepAction(2)

        call StartSound(gg_snd_questFailed)

        set last = true

    else

        if (nbAlive == 1) then

            call StartSound( gg_snd_warning )

        endif

    endif

    

    if (isAfk[n]) then

        call DestroyTextTag(afkModeTextTags[n])

    else

        call PauseTimer(afkModeTimers[n])

    endif

    

    if (AreAllAliveHeroesAfk()) then

        call KillAllHeroesAfkInFiveSeconds()

    endif

        

    if (last) then //à cause du sleepAction plus haut

        call TriggerSleepAction( 3 )

    else

        call TriggerSleepAction( 5 )

    endif



    call SetUnitAnimation(GetTriggerUnit(), "stand")

    set udg_nbKilled = udg_nbKilled - 1

endfunction



//===========================================================================

function InitTrig_A_hero_dies_check_if_all_dead_and_sounds takes nothing returns nothing

    set gg_trg_A_hero_dies_check_if_all_dead_and_sounds = CreateTrigger(  )

    call TriggerRegisterAnyUnitEventBJ( gg_trg_A_hero_dies_check_if_all_dead_and_sounds, EVENT_PLAYER_UNIT_DEATH )

    call TriggerAddCondition( gg_trg_A_hero_dies_check_if_all_dead_and_sounds, Condition( function Trig_a_hero_dies_Conditions ) )

    call TriggerAddAction( gg_trg_A_hero_dies_check_if_all_dead_and_sounds, function Trig_a_hero_dies_Actions )

endfunction



//===========================================================================

// Trigger: Lose a life and res

//

// actions when the last hero alive dies

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

function Trig_Lose_a_life_and_res_Actions takes nothing returns nothing

    local integer i

    call udg_lives.loseALife()

    if (udg_lives.get() < 0) then

        call DisplayTextToForce( GetPlayersAll(), "You have no more lives !" )

        call TriggerSleepAction( 2 )

        call DisplayTextToForce( GetPlayersAll(), "The game will restart in 10 seconds." )

        call TriggerSleepAction( 10.00 )

        call udg_levels.restartTheGame()

    else

        if (udg_changeAllTerrainsAtRevive) then

            call TriggerSleepAction( 6.00 )

            call ChangeAllTerrains("normal")

            call TriggerSleepAction( 2.00 )

        else

            call TriggerSleepAction( 8.00 )

        endif

        set i = 0

        loop

            exitwhen (i > 11)

                if (udg_escapers.get(i) != 0) then

                    call udg_escapers.get(i).reviveAtStart()

                endif

            set i = i + 1

        endloop

        call Text_A("|cff5c2e2eYou have lost a life !")

        //set AnticheatTeleport_justRevived = true

    endif

endfunction



//===========================================================================

function InitTrig_Lose_a_life_and_res takes nothing returns nothing

    set gg_trg_Lose_a_life_and_res = CreateTrigger(  )

    call TriggerAddAction( gg_trg_Lose_a_life_and_res, function Trig_Lose_a_life_and_res_Actions )

endfunction



//===========================================================================

// Trigger: Sound monster dies

//===========================================================================

function Trig_Sound_monster_dies_Conditions takes nothing returns boolean

    if ( not ( GetOwningPlayer(GetTriggerUnit()) == Player(PLAYER_NEUTRAL_AGGRESSIVE) ) ) then

        return false

    endif

    return true

endfunction



function Trig_Sound_monster_dies_Actions takes nothing returns nothing

    call PlaySoundBJ( gg_snd_goodJob )

endfunction



//===========================================================================

function InitTrig_Sound_monster_dies takes nothing returns nothing

    set gg_trg_Sound_monster_dies = CreateTrigger(  )

    call TriggerRegisterAnyUnitEventBJ( gg_trg_Sound_monster_dies, EVENT_PLAYER_UNIT_DEATH )

    call TriggerAddCondition( gg_trg_Sound_monster_dies, Condition( function Trig_Sound_monster_dies_Conditions ) )

    call TriggerAddAction( gg_trg_Sound_monster_dies, function Trig_Sound_monster_dies_Actions )

endfunction



//===========================================================================

// Trigger: Giving making rights

//

// Disable or delete this trigger when your map is finished

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

function Trig_Giving_making_rights_Actions takes nothing returns nothing

    local integer playerId = 0

    //giving admin rights to the first player

    loop

        exitwhen udg_escapers.get(playerId) != 0

        set playerId = playerId + 1

    endloop

    call udg_escapers.get(playerId).setIsTrueMaximaxou(true)

    //giving other players make rights

    loop

        set playerId = playerId + 1

        exitwhen playerId > 11

            if(udg_escapers.get(playerId) != 0)then

                call udg_escapers.get(playerId).setCanCheat(true)

            endif

    endloop            

endfunction



//===========================================================================

function InitTrig_Giving_making_rights takes nothing returns nothing

    set gg_trg_Giving_making_rights = CreateTrigger(  )

    call TriggerRegisterTimerEventSingle( gg_trg_Giving_making_rights, 0.00 )

    call TriggerAddAction( gg_trg_Giving_making_rights, function Trig_Giving_making_rights_Actions )

endfunction



//===========================================================================

// Trigger: Welcome message

//===========================================================================

function Trig_Welcome_message_Actions takes nothing returns nothing

    call DisplayTimedTextToForce( GetPlayersAll(), 45.00, "TRIGSTR_185" )

    call DisplayTimedTextToForce( GetPlayersAll(), 45.00, "TRIGSTR_186" )

    call FlashQuestDialogButtonBJ(  )

endfunction



//===========================================================================

function InitTrig_Welcome_message takes nothing returns nothing

    set gg_trg_Welcome_message = CreateTrigger(  )

    call TriggerAddAction( gg_trg_Welcome_message, function Trig_Welcome_message_Actions )

endfunction



//===========================================================================

// Trigger: Commands 1

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

globals



    constant string Commands1 = "-cameraField(cf) x

changes the camera field (height), default is 2500



-resetCamera(rc)

puts the camera back like chosen field



-resetCameraInit(rci)

changes the camera field back to its default value (2500)



-animation(an) <string>

makes your hero doing an animation. ex : -an attack



-mapNbMonsters(mnbm) [moving(m)|all(a)|notMoving(nm)]

displays the number of monsters in the map, of the chosen kind. \"Moving\" is the default kind. ex : -mnbm nm



-levelNbMonsters(lnbm) [moving(m)|all(a)|notMoving(nm)]

displays the number of monsters in the current level, of the chosen kind



-kill(kl) : kills your hero



-kick(kc) : kicks yourself



-disco(d) [off|1~30]

chooses the number of color changes in ten seconds, or stop color changing (without parameter : once a second)



-clearText(clr)

removes the text on the screen



-getCurrentLevel(getcl)

displays the number of the current level (first one is number 0)"





//===========================================================================

    constant string Commands1Requirement1 = "Here is the first part of various commands you can use in game"

    constant string Commands1Requirement2 = ""

    constant string Commands1Requirement3 = "cf, rc, rci, an, mnbm, lnbm, kl, kc, d, clr, getcl"



endglobals













//===========================================================================

function InitTrig_Commands_1 takes nothing returns nothing

endfunction



//===========================================================================

// Trigger: Commands 2

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

globals



    constant string Commands2 = "-drunk(-) <real drunkValue>  --> value between 5 and 60

makes your hero drink alcohol



-noDrunk(-) 

stops drunk mode



-apm(-) [all|a]

displays apm on slide of everybody or just yourself



-saveCommand(sc) <commandLabel> <command>

saves a command or group of commands into a name of your choice



-executeCommand(ec) <commandLabel>

execute a command or group of commands you saved with \"saveCommand\"



-autoContinueAfterSliding(acas) <boolean status>

activated at the beginning of the game

ex: -acas off, -acas 1



-usedTerrains(ut)

displays the terrains used in this game



-getTerrainInfo(gti) [ <terrain> | <lowInteger> <upInteger> ]

gets information about terrains used in the game and all terrains of warcraft 3

terrains are numbered between 1 and 177

without parameter you'll get information about terrains you right click on (use -stop to stop this mode)



-stop(s) 

stops getTerrainInfoMode"





//===========================================================================

    constant string Commands2Requirement1 = "Here is the second part of various commands you can use in game"

    constant string Commands2Requirement2 = ""

    constant string Commands2Requirement3 = "drunk, noDrunk, apm, sc, ec, acas, ut, gti, s"



endglobals













//===========================================================================

function InitTrig_Commands_2 takes nothing returns nothing

endfunction



//===========================================================================

// Trigger: Colors

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

globals



    constant string Colors = "The colors are :

red or rd, blue or be

teal or tl, purple or pe

yellow or yw, orange or oe

green or gn, pink or pk

grey or gray or gy, lightblue or lb

darkgreen or dg, brown or bn

black or bk



-<color>

change the base color of your character



-vertexColor [ <red> <green> <blue> [<transparency>] ]

alias -vc, change the vertex color of you character.

The result color depends on the basic color of your character.

The parameters are integer percentage or x to take a random percentage.

Without parameter, it will do like -vc x x x.



You can also specify onnly the red part of the vertex color :

-vertexColorRed [<red>], alias -vcr

Same for green, blue and transparency (vcg, vcb, vct)



-noVertex

alias -nv, cancel the vertex color of your character

it's like -vc 100 100 100



-colorInfo [<Pcolor>]

alias -ci, display info about the color of your character, or of an other player's character"

    

//==================================================================================================================    

    constant string ColorsRequirement1 = "Here are all commands to change the color of your character."

    constant string ColorsRequirement2 = ""

    constant string ColorsRequirement3 = "rd, be, tl, pe, yw, oe, gn, pk, gy, lb, dg, bn, bk, vc, vcr, vcg, vcb, vct, nv, ci"

    

endglobals

































//===========================================================================

function InitTrig_Colors takes nothing returns nothing

endfunction



//===========================================================================

// Trigger: Effects

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

globals



    constant string Effects = "The effects are :

light or l

fire or f

ice or i

corruption or c

poison or p

slow or s



-effect <effect>

alias -ef, puts an effect on each hand of your hero



-customEffect <effect> <bodyPart>

alias -ce, puts an effect on the specified bodyPart

The body parts are :

leftHand or lh

rightHand or rh

leftFoot or lf

rightFoot or rf

overhead or oh

head or h

origin or o

chest or c



-effectsEverywhere <effect>

alias -efe, puts the same effect to each body part of your hero



-deleteEffects [<numberOfEffectsToRemove n>]

alias -de, deletes the n last effects of your hero, all effects if no parameter specified"

    



//==================================================================================================================   

    constant string EffectsRequirement1 = "Here are all commands to add effects on your character."

    constant string EffectsRequirement2 = ""

    constant string EffectsRequirement3 = "ef, ce, efe, de"

    

endglobals

































//===========================================================================

function InitTrig_Effects takes nothing returns nothing

endfunction



//===========================================================================

// Trigger: Red commands

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

globals



    constant string RedCommands = "-kill <Pcolor>

alias -kl, kills a hero

examples : -kill be,  -kl teal



-kick <Pcolor>

alias -kc, kicks a player

examples : -kick be,  -kc teal



-restart

just restart the game like when lose"





    

//==================================================================================================================   

    constant string RedCommandsRequirement1 = "If a player is afk, no more need to kill him (autokill if needed)."

    constant string RedCommandsRequirement2 = "If a player is really boring, still need to kick him."

    constant string RedCommandsRequirement3 = "kl, kc, restart"

    

endglobals

































//===========================================================================

function InitTrig_Red_commands takes nothing returns nothing

endfunction



//===========================================================================

// Trigger: Map description

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

globals



    constant string MapDescription = "Max Escape Creation is a tool made by Maximaxou to create escapes during the game with commands. The good point is that it's possible to save the map. We can make escapes in multiplayer without any map making knowledge."

    

//==================================================================================================================   



    constant string MapDescriptionRequirement1 = "This map was made with Max Escape Creation"

    constant string MapDescriptionRequirement2 = "http:/max.slid.free.fr/maxEscapeCreation"

    

endglobals

































//===========================================================================

function InitTrig_Map_description takes nothing returns nothing

endfunction



//===========================================================================

// Trigger: Contact

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

globals



    constant string Contact = "How to contact me : ---

How to contact Maximaxou, creator of Max Escape Creation : maxpolar@hotmail.fr"

    

//==================================================================================================================   

    constant string ContactRequirement1 = "Titre1"

    constant string ContactRequirement2 = "Titre2"

    

endglobals

































//===========================================================================

function InitTrig_Contact takes nothing returns nothing

endfunction



//===========================================================================

// Trigger: Command shortcuts

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

globals



    constant string CommandShortcuts = "To assign a command to a key, use this command :

-assign <key> <command>

alias as

don't put the \"-\" of the command you wanna save

ex: -assign A red, -as d vc, -as e mirror on, -as R m off



To assign an other command to a already used shortcut, just type command assign again.



To disable a shortcut, use this command :

-unassign <key>

alias uas



To display your current shortcuts, use this command :

-displayShortcuts

alias -ds"





    

//==================================================================================================================    

    constant string CommandShortcutsRequirement1 = "You can now use 8 shortcuts to execute your favorite commands !"

    constant string CommandShortcutsRequirement2 = "Press A, Z, E, R, Q, S, D or F !"



endglobals















//===========================================================================

function InitTrig_Command_shortcuts takes nothing returns nothing

endfunction



//===========================================================================

// Trigger: Adding quests

//===========================================================================

//TESH.scrollpos=6

//TESH.alwaysfold=0

function Trig_adding_quests_Actions takes nothing returns nothing



//GAUCHE



    //Commands1

    call CreateQuestBJ( bj_QUESTTYPE_REQ_DISCOVERED, "Commands 1", Commands1, "ReplaceableTextures\\CommandButtons\\BTNEnt.blp" )

    call CreateQuestItemBJ( GetLastCreatedQuestBJ(), Commands1Requirement1 )
    call CreateQuestItemBJ( GetLastCreatedQuestBJ(), Commands1Requirement2 )

    call CreateQuestItemBJ( GetLastCreatedQuestBJ(), Commands1Requirement3 )



    //Commands2

    call CreateQuestBJ( bj_QUESTTYPE_REQ_DISCOVERED, "Commands 2", Commands2, "ReplaceableTextures\\CommandButtons\\BTNEnt.blp" )

    call CreateQuestItemBJ( GetLastCreatedQuestBJ(), Commands2Requirement1 )

    call CreateQuestItemBJ( GetLastCreatedQuestBJ(), Commands2Requirement2 )

    call CreateQuestItemBJ( GetLastCreatedQuestBJ(), Commands2Requirement3 )

    

    // Colors

    call CreateQuestBJ( bj_QUESTTYPE_REQ_DISCOVERED, "Colors", Colors, "ReplaceableTextures\\CommandButtons\\BTNAmbush.blp" )

    call CreateQuestItemBJ( GetLastCreatedQuestBJ(), ColorsRequirement1 )

    call CreateQuestItemBJ( GetLastCreatedQuestBJ(), ColorsRequirement2 )

    call CreateQuestItemBJ( GetLastCreatedQuestBJ(), ColorsRequirement3 )

    

    // Effects

    call CreateQuestBJ( bj_QUESTTYPE_REQ_DISCOVERED, "Effects", Effects, "ReplaceableTextures\\CommandButtons\\BTNDevotion.blp" )

    call CreateQuestItemBJ( GetLastCreatedQuestBJ(), EffectsRequirement1 )

    call CreateQuestItemBJ( GetLastCreatedQuestBJ(), EffectsRequirement2 )

    call CreateQuestItemBJ( GetLastCreatedQuestBJ(), EffectsRequirement3 )



    // Red commands

    call CreateQuestBJ( bj_QUESTTYPE_REQ_DISCOVERED, "Red commands", RedCommands, "ReplaceableTextures\\CommandButtons\\BTNAncientOfLore.blp" )

    call CreateQuestItemBJ( GetLastCreatedQuestBJ(), RedCommandsRequirement1 )

    call CreateQuestItemBJ( GetLastCreatedQuestBJ(), RedCommandsRequirement2 )

    call CreateQuestItemBJ( GetLastCreatedQuestBJ(), RedCommandsRequirement3 )

    



    

    

//DROITE



    // Map description

    call CreateQuestBJ( bj_QUESTTYPE_OPT_DISCOVERED, "Map description", MapDescription, "ReplaceableTextures\\CommandButtons\\BTNCOP.blp" )

    call CreateQuestItemBJ( GetLastCreatedQuestBJ(), MapDescriptionRequirement1 )

    call CreateQuestItemBJ( GetLastCreatedQuestBJ(), MapDescriptionRequirement2 )

    

    // Contact

    call CreateQuestBJ( bj_QUESTTYPE_OPT_DISCOVERED, "Contact", Contact, "ReplaceableTextures\\CommandButtons\\BTNEvilIllidan.blp" )

    call CreateQuestItemBJ( GetLastCreatedQuestBJ(), ContactRequirement1 )

    call CreateQuestItemBJ( GetLastCreatedQuestBJ(), ContactRequirement2 )

    

    //Command shortcuts

    call CreateQuestBJ( bj_QUESTTYPE_OPT_DISCOVERED, "Command shortcuts", CommandShortcuts, "ReplaceableTextures\\CommandButtons\\BTNImmolationOff.blp" )

    call CreateQuestItemBJ( GetLastCreatedQuestBJ(), CommandShortcutsRequirement1 )

    call CreateQuestItemBJ( GetLastCreatedQuestBJ(), CommandShortcutsRequirement2 )

    

    

endfunction



//===========================================================================

function InitTrig_Adding_quests takes nothing returns nothing

    set gg_trg_Adding_quests = CreateTrigger(  )

    call TriggerAddAction( gg_trg_Adding_quests, function Trig_adding_quests_Actions )

endfunction

//===========================================================================

// Trigger: Antisave

//===========================================================================

function Trig_Antisave_Actions takes nothing returns nothing

    call TriggerExecute( GetTriggeringTrigger() )

endfunction



//===========================================================================

function InitTrig_Antisave takes nothing returns nothing

    set gg_trg_Antisave = CreateTrigger(  )

    call DisableTrigger( gg_trg_Antisave )

    call TriggerRegisterGameLoadedEventBJ( gg_trg_Antisave )

    call TriggerAddAction( gg_trg_Antisave, function Trig_Antisave_Actions )

endfunction



//===========================================================================

// Trigger: Antisave warning

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

function Trig_antisave_warning_Actions takes nothing returns nothing

    if (IsTriggerEnabled(gg_trg_Antisave)) then

        call DisplayTextToForce(GetPlayersAll(), udg_colorCode[RED] + "Warning ! Loading the game won't work !")

    else

        call DisplayTextToForce(GetPlayersAll(), udg_colorCode[RED] + "Don't forget to type -saveTerrain to save the whole terrain before saving the game. (load with -loadTerrain)")

    endif

endfunction





//===========================================================================

function InitTrig_Antisave_warning takes nothing returns nothing

    set gg_trg_Antisave_warning = CreateTrigger(  )

    call TriggerRegisterGameSavedEventBJ( gg_trg_Antisave_warning )

    call TriggerAddAction( gg_trg_Antisave_warning, function Trig_antisave_warning_Actions )

endfunction



//===========================================================================

// Trigger: Init terrain types

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

globals

	TerrainTypeArray udg_terrainTypes = 0

endglobals





function InitTrig_Init_terrain_types takes nothing returns nothing

	if (udg_terrainTypes == 0) then

		set udg_terrainTypes = TerrainTypeArray.create()

	endif

endfunction//===========================================================================

// Trigger: Init monster types

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

globals

	MonsterTypeArray udg_monsterTypes = 0

endglobals





function InitTrig_Init_monster_types takes nothing returns nothing

	if (udg_monsterTypes == 0) then

		set udg_monsterTypes = MonsterTypeArray.create()

	endif

endfunction//===========================================================================

// Trigger: Init levels

//===========================================================================

//TESH.scrollpos=0

//TESH.alwaysfold=0

//===========================================================================

function InitCustomTriggers takes nothing returns nothing

    call InitTrig_Constants(  )

    call InitTrig_Text(  )

    call InitTrig_Init_terrain_limit_variables(  )

    call InitTrig_Init_colorCodes(  )

    call InitTrig_Basic_functions(  )

    call InitTrig_Functions_on_numbers(  )

    call InitTrig_Ascii(  )

    call InitTrig_Decode_string(  )

    call InitTrig_View_all_hide_all(  )

    call InitTrig_Immolation_skills(  )

    call InitTrig_MonsterType(  )

    call InitTrig_MonsterTypeArray(  )

    call InitTrig_Monster_creation_functions(  )

    call InitTrig_MonsterInterface(  )

    call InitTrig____trig_Monsters_clickable_set_life(  )

    call InitTrig_MonsterNoMove(  )

    call InitTrig_MonsterNoMoveArray(  )

    call InitTrig_MonsterSimplePatrol(  )

    call InitTrig_MonsterSimplePatrolArray(  )

    call InitTrig_MonsterMultiplePatrols(  )

    call InitTrig_MonsterMultiplePatrolsArray(  )

    call InitTrig_MonsterSpawn(  )

    call InitTrig_MonsterSpawnArray(  )

    call InitTrig_Terrain_type_functions(  )

    call InitTrig_TerrainType(  )

    call InitTrig_TerrainTypeWalk(  )

    call InitTrig_TerrainTypeDeath_functions(  )

    call InitTrig_TerrainTypeDeath_KillingTimers(  )

    call InitTrig_TerrainTypeDeath(  )

    call InitTrig_TerrainTypeSlide(  )

    call InitTrig_TerrainTypeArray(  )

    call InitTrig_Time_of_game_trigger(  )

    call InitTrig_Lives_and_game_time(  )

    call InitTrig_Meteor(  )

    call InitTrig_MeteorArray(  )

    call InitTrig_Meteor_functions(  )

    call InitTrig_Right_click_on_widget(  )

    call InitTrig_Meteor_being_used(  )

    call InitTrig_Stop_using_normal_meteor(  )

    call InitTrig_Effect_meteor_on_pick_up(  )

    call InitTrig_VisibilityModifier(  )

    call InitTrig_VisibilityModifierArray(  )

    call InitTrig_StartAndEnd(  )

    call InitTrig_Triggers(  )

    call InitTrig_Level(  )

    call InitTrig____Level_functions(  )

    call InitTrig____Trig_checkpoint_revive_heroes(  )

    call InitTrig_LevelArray(  )

    call InitTrig_EscaperEffect_functions(  )

    call InitTrig_EscaperEffect(  )

    call InitTrig_EscaperEffectArray(  )

    call InitTrig_Escaper_functions(  )

    call InitTrig_Escaper_disco(  )

    call InitTrig_Escaper(  )

    call InitTrig_EscaperArray(  )

    call InitTrig_EscaperSavedCommands(  )

    call InitTrig_Make(  )

    call InitTrig_Monster_making_no_move_Actions(  )

    call InitTrig_MakeMonsterNoMove(  )

    call InitTrig_Monster_making_simple_patrol_Actions(  )

    call InitTrig_MakeMonsterSimplePatrol(  )

    call InitTrig_Monster_making_multiple_patrols_Actions(  )

    call InitTrig_MakeMonsterMultiplePatrols(  )

    call InitTrig_Monster_spawn_making_Actions(  )

    call InitTrig_MakeMonsterSpawn(  )

    call InitTrig_Monster_delete_Actions(  )

    call InitTrig_MakeDeleteMonsters(  )

    call InitTrig_Meteor_making_Actions(  )

    call InitTrig_MakeMeteor(  )

    call InitTrig_Meteor_delete_Actions(  )

    call InitTrig_MakeDeleteMeteors(  )

    call InitTrig_Terrain_making_Actions(  )

    call InitTrig_MakeTerrainCreate(  )

    call InitTrig_Terrain_copy_paste_Actions(  )

    call InitTrig_MakeTerrainCopyPaste(  )

    call InitTrig_Terrain_vertical_symmetry_Actions(  )

    call InitTrig_MakeTerrainVerticalSymmetry(  )

    call InitTrig_Terrain_horizontal_symmetry_Actions(  )

    call InitTrig_MakeTerrainHorizontalSymmetry(  )

    call InitTrig_Make_exchange_terrains_Actions(  )

    call InitTrig_MakeExchangeTerrains(  )

    call InitTrig_Start_making_Actions(  )

    call InitTrig_MakeStart(  )

    call InitTrig_End_making_Actions(  )

    call InitTrig_MakeEnd(  )

    call InitTrig_VisibilityModifier_making_Actions(  )

    call InitTrig_MakeVisibilityModifier(  )

    call InitTrig_Getting_terrain_type_info_Actions(  )

    call InitTrig_MakeGetTerrainType(  )

    call InitTrig_MakeAction(  )

    call InitTrig_MakeMonsterAction(  )

    call InitTrig_MakeDeleteMonstersAction(  )

    call InitTrig_MakeMeteorAction(  )

    call InitTrig_MakeDeleteMeteorsAction(  )

    call InitTrig_MakeTerrainCreateAction(  )

    call InitTrig_MakeTerrainCopyPasteAction(  )

    call InitTrig_MakeTerrainVerticalSymmetryAction(  )

    call InitTrig_MakeTerrainHorizontalSymmetryAction(  )

    call InitTrig_MakeVisibilityModifierAction(  )

    call InitTrig_MakeLastActions(  )

    call InitTrig_Command_functions(  )

    call InitTrig_Teleport_once_only(  )

    call InitTrig_Teleport(  )

    call InitTrig_Autorevive(  )

    call InitTrig_Command_all(  )

    call InitTrig_Command_red(  )

    call InitTrig_Command_cheat(  )

    call InitTrig_Command_make(  )

    call InitTrig_Command_max(  )

    call InitTrig_Command_true_max(  )

    call InitTrig_Command_execution(  )

    call InitTrig_Slide(  )

    call InitTrig_To_turn_on_slide(  )

    call InitTrig_Auto_continue_after_sliding(  )

    call InitTrig_CheckTerrain(  )

    call InitTrig_All_terrain_functions(  )

    call InitTrig_Terrain_type_ascii_conversion(  )

    call InitTrig_Terrain_type_max(  )

    call InitTrig_Terrain_type_grass(  )

    call InitTrig_Terrain_type_names_and_data(  )

    call InitTrig_Terrain_functions(  )

    call InitTrig_Terrain_type_from_string(  )

    call InitTrig_Modify_terrain_functions(  )

    call InitTrig_Terrain_modifying_trig(  )

    call InitTrig_Change_one_terrain(  )

    call InitTrig_Change_all_terrains(  )

    call InitTrig_Exchange_terrains(  )

    call InitTrig_Randomize_terrains(  )

    call InitTrig_Reinit_terrains(  )

    call InitTrig_Reinit_terrains_position_Change_variations_and_ut_at_beginning(  )

    call InitTrig_Save_load_terrain_without_name(  )

    call InitTrig_Save_load_terrain_with_name(  )

    call InitTrig_struct_StringArrayForCache(  )

    call InitTrig_Save_terrain_config(  )

    call InitTrig_Save_terrain(  )

    call InitTrig_Save_monster_types(  )

    call InitTrig_Save_levels(  )

    call InitTrig_SAVE_MAP_in_cache(  )

    call InitTrig_Init_lives(  )

    call InitTrig_Init_escapers(  )

    call InitTrig_Init_struct_levels(  )

    call InitTrig_Forces_ally(  )

    call InitTrig_Camera(  )

    call InitTrig_No_selection_circle(  )

    call InitTrig_Allways_day(  )

    call InitTrig_Start_sound(  )

    call InitTrig_Heroes(  )

    call InitTrig_Command_shortcuts_functions(  )

    call InitTrig_Using_shortcut(  )

    call InitTrig_Camera_reset(  )

    call InitTrig_Apm(  )

    call InitTrig_Afk_mode(  )

    call InitTrig_Afk_mode_ordre_recu(  )

    call InitTrig_A_player_leaves(  )

    call InitTrig_InvisUnit_is_getting_damage(  )

    call InitTrig_A_hero_dies_check_if_all_dead_and_sounds(  )

    call InitTrig_Lose_a_life_and_res(  )

    call InitTrig_Sound_monster_dies(  )

    call InitTrig_Giving_making_rights(  )

    call InitTrig_Welcome_message(  )

    call InitTrig_Commands_1(  )

    call InitTrig_Commands_2(  )

    call InitTrig_Colors(  )

    call InitTrig_Effects(  )

    call InitTrig_Red_commands(  )

    call InitTrig_Map_description(  )

    call InitTrig_Contact(  )

    call InitTrig_Command_shortcuts(  )

    call InitTrig_Adding_quests(  )

    call InitTrig_Antisave(  )

    call InitTrig_Antisave_warning(  )

    call InitTrig_Init_terrain_types(  )

    call InitTrig_Init_monster_types(  )

    call InitTrig_Init_levels(  )

endfunction



//===========================================================================

function RunInitializationTriggers takes nothing returns nothing

    call ConditionalTriggerExecute( gg_trg_Init_terrain_limit_variables )

    call ConditionalTriggerExecute( gg_trg_Init_colorCodes )

    call ConditionalTriggerExecute( gg_trg_Forces_ally )

    call ConditionalTriggerExecute( gg_trg_Camera )

    call ConditionalTriggerExecute( gg_trg_No_selection_circle )

    call ConditionalTriggerExecute( gg_trg_Allways_day )

    call ConditionalTriggerExecute( gg_trg_Welcome_message )

    call ConditionalTriggerExecute( gg_trg_Adding_quests )

endfunction



//***************************************************************************

//*

//*  Players

//*

//***************************************************************************



function InitCustomPlayerSlots takes nothing returns nothing



    // Player 0

    call SetPlayerStartLocation( Player(0), 0 )

    call SetPlayerColor( Player(0), ConvertPlayerColor(0) )

    call SetPlayerRacePreference( Player(0), RACE_PREF_HUMAN )

    call SetPlayerRaceSelectable( Player(0), false )

    call SetPlayerController( Player(0), MAP_CONTROL_USER )



    // Player 1

    call SetPlayerStartLocation( Player(1), 1 )

    call SetPlayerColor( Player(1), ConvertPlayerColor(1) )

    call SetPlayerRacePreference( Player(1), RACE_PREF_ORC )

    call SetPlayerRaceSelectable( Player(1), false )

    call SetPlayerController( Player(1), MAP_CONTROL_USER )



    // Player 2

    call SetPlayerStartLocation( Player(2), 2 )

    call SetPlayerColor( Player(2), ConvertPlayerColor(2) )

    call SetPlayerRacePreference( Player(2), RACE_PREF_UNDEAD )

    call SetPlayerRaceSelectable( Player(2), false )

    call SetPlayerController( Player(2), MAP_CONTROL_USER )



    // Player 3

    call SetPlayerStartLocation( Player(3), 3 )

    call SetPlayerColor( Player(3), ConvertPlayerColor(3) )

    call SetPlayerRacePreference( Player(3), RACE_PREF_NIGHTELF )

    call SetPlayerRaceSelectable( Player(3), false )

    call SetPlayerController( Player(3), MAP_CONTROL_USER )



    // Player 4

    call SetPlayerStartLocation( Player(4), 4 )

    call SetPlayerColor( Player(4), ConvertPlayerColor(4) )

    call SetPlayerRacePreference( Player(4), RACE_PREF_HUMAN )

    call SetPlayerRaceSelectable( Player(4), false )

    call SetPlayerController( Player(4), MAP_CONTROL_USER )



    // Player 5

    call SetPlayerStartLocation( Player(5), 5 )

    call SetPlayerColor( Player(5), ConvertPlayerColor(5) )

    call SetPlayerRacePreference( Player(5), RACE_PREF_ORC )

    call SetPlayerRaceSelectable( Player(5), false )

    call SetPlayerController( Player(5), MAP_CONTROL_USER )



    // Player 6

    call SetPlayerStartLocation( Player(6), 6 )

    call SetPlayerColor( Player(6), ConvertPlayerColor(6) )

    call SetPlayerRacePreference( Player(6), RACE_PREF_UNDEAD )

    call SetPlayerRaceSelectable( Player(6), false )

    call SetPlayerController( Player(6), MAP_CONTROL_USER )



    // Player 7

    call SetPlayerStartLocation( Player(7), 7 )

    call SetPlayerColor( Player(7), ConvertPlayerColor(7) )

    call SetPlayerRacePreference( Player(7), RACE_PREF_NIGHTELF )

    call SetPlayerRaceSelectable( Player(7), false )

    call SetPlayerController( Player(7), MAP_CONTROL_USER )



    // Player 8

    call SetPlayerStartLocation( Player(8), 8 )

    call SetPlayerColor( Player(8), ConvertPlayerColor(8) )

    call SetPlayerRacePreference( Player(8), RACE_PREF_HUMAN )

    call SetPlayerRaceSelectable( Player(8), false )

    call SetPlayerController( Player(8), MAP_CONTROL_USER )



    // Player 9

    call SetPlayerStartLocation( Player(9), 9 )

    call SetPlayerColor( Player(9), ConvertPlayerColor(9) )

    call SetPlayerRacePreference( Player(9), RACE_PREF_ORC )

    call SetPlayerRaceSelectable( Player(9), false )

    call SetPlayerController( Player(9), MAP_CONTROL_USER )



    // Player 10

    call SetPlayerStartLocation( Player(10), 10 )

    call SetPlayerColor( Player(10), ConvertPlayerColor(10) )

    call SetPlayerRacePreference( Player(10), RACE_PREF_UNDEAD )

    call SetPlayerRaceSelectable( Player(10), false )

    call SetPlayerController( Player(10), MAP_CONTROL_USER )



    // Player 11

    call SetPlayerStartLocation( Player(11), 11 )

    call SetPlayerColor( Player(11), ConvertPlayerColor(11) )

    call SetPlayerRacePreference( Player(11), RACE_PREF_NIGHTELF )

    call SetPlayerRaceSelectable( Player(11), false )

    call SetPlayerController( Player(11), MAP_CONTROL_USER )



endfunction



function InitCustomTeams takes nothing returns nothing

    // Force: TRIGSTR_016

    call SetPlayerTeam( Player(0), 0 )

    call SetPlayerState( Player(0), PLAYER_STATE_ALLIED_VICTORY, 1 )



    // Force: TRIGSTR_017

    call SetPlayerTeam( Player(1), 1 )

    call SetPlayerState( Player(1), PLAYER_STATE_ALLIED_VICTORY, 1 )

    call SetPlayerTeam( Player(2), 1 )

    call SetPlayerState( Player(2), PLAYER_STATE_ALLIED_VICTORY, 1 )

    call SetPlayerTeam( Player(3), 1 )

    call SetPlayerState( Player(3), PLAYER_STATE_ALLIED_VICTORY, 1 )

    call SetPlayerTeam( Player(4), 1 )

    call SetPlayerState( Player(4), PLAYER_STATE_ALLIED_VICTORY, 1 )

    call SetPlayerTeam( Player(5), 1 )

    call SetPlayerState( Player(5), PLAYER_STATE_ALLIED_VICTORY, 1 )

    call SetPlayerTeam( Player(6), 1 )

    call SetPlayerState( Player(6), PLAYER_STATE_ALLIED_VICTORY, 1 )

    call SetPlayerTeam( Player(7), 1 )

    call SetPlayerState( Player(7), PLAYER_STATE_ALLIED_VICTORY, 1 )

    call SetPlayerTeam( Player(8), 1 )

    call SetPlayerState( Player(8), PLAYER_STATE_ALLIED_VICTORY, 1 )

    call SetPlayerTeam( Player(9), 1 )

    call SetPlayerState( Player(9), PLAYER_STATE_ALLIED_VICTORY, 1 )

    call SetPlayerTeam( Player(10), 1 )

    call SetPlayerState( Player(10), PLAYER_STATE_ALLIED_VICTORY, 1 )

    call SetPlayerTeam( Player(11), 1 )

    call SetPlayerState( Player(11), PLAYER_STATE_ALLIED_VICTORY, 1 )



    //   Allied

    call SetPlayerAllianceStateAllyBJ( Player(1), Player(2), true )

    call SetPlayerAllianceStateAllyBJ( Player(1), Player(3), true )

    call SetPlayerAllianceStateAllyBJ( Player(1), Player(4), true )

    call SetPlayerAllianceStateAllyBJ( Player(1), Player(5), true )

    call SetPlayerAllianceStateAllyBJ( Player(1), Player(6), true )

    call SetPlayerAllianceStateAllyBJ( Player(1), Player(7), true )

    call SetPlayerAllianceStateAllyBJ( Player(1), Player(8), true )

    call SetPlayerAllianceStateAllyBJ( Player(1), Player(9), true )

    call SetPlayerAllianceStateAllyBJ( Player(1), Player(10), true )

    call SetPlayerAllianceStateAllyBJ( Player(1), Player(11), true )

    call SetPlayerAllianceStateAllyBJ( Player(2), Player(1), true )

    call SetPlayerAllianceStateAllyBJ( Player(2), Player(3), true )

    call SetPlayerAllianceStateAllyBJ( Player(2), Player(4), true )

    call SetPlayerAllianceStateAllyBJ( Player(2), Player(5), true )

    call SetPlayerAllianceStateAllyBJ( Player(2), Player(6), true )

    call SetPlayerAllianceStateAllyBJ( Player(2), Player(7), true )

    call SetPlayerAllianceStateAllyBJ( Player(2), Player(8), true )

    call SetPlayerAllianceStateAllyBJ( Player(2), Player(9), true )

    call SetPlayerAllianceStateAllyBJ( Player(2), Player(10), true )

    call SetPlayerAllianceStateAllyBJ( Player(2), Player(11), true )

    call SetPlayerAllianceStateAllyBJ( Player(3), Player(1), true )

    call SetPlayerAllianceStateAllyBJ( Player(3), Player(2), true )

    call SetPlayerAllianceStateAllyBJ( Player(3), Player(4), true )

    call SetPlayerAllianceStateAllyBJ( Player(3), Player(5), true )

    call SetPlayerAllianceStateAllyBJ( Player(3), Player(6), true )

    call SetPlayerAllianceStateAllyBJ( Player(3), Player(7), true )

    call SetPlayerAllianceStateAllyBJ( Player(3), Player(8), true )

    call SetPlayerAllianceStateAllyBJ( Player(3), Player(9), true )

    call SetPlayerAllianceStateAllyBJ( Player(3), Player(10), true )

    call SetPlayerAllianceStateAllyBJ( Player(3), Player(11), true )

    call SetPlayerAllianceStateAllyBJ( Player(4), Player(1), true )

    call SetPlayerAllianceStateAllyBJ( Player(4), Player(2), true )

    call SetPlayerAllianceStateAllyBJ( Player(4), Player(3), true )

    call SetPlayerAllianceStateAllyBJ( Player(4), Player(5), true )

    call SetPlayerAllianceStateAllyBJ( Player(4), Player(6), true )

    call SetPlayerAllianceStateAllyBJ( Player(4), Player(7), true )

    call SetPlayerAllianceStateAllyBJ( Player(4), Player(8), true )

    call SetPlayerAllianceStateAllyBJ( Player(4), Player(9), true )

    call SetPlayerAllianceStateAllyBJ( Player(4), Player(10), true )

    call SetPlayerAllianceStateAllyBJ( Player(4), Player(11), true )

    call SetPlayerAllianceStateAllyBJ( Player(5), Player(1), true )

    call SetPlayerAllianceStateAllyBJ( Player(5), Player(2), true )

    call SetPlayerAllianceStateAllyBJ( Player(5), Player(3), true )

    call SetPlayerAllianceStateAllyBJ( Player(5), Player(4), true )

    call SetPlayerAllianceStateAllyBJ( Player(5), Player(6), true )

    call SetPlayerAllianceStateAllyBJ( Player(5), Player(7), true )

    call SetPlayerAllianceStateAllyBJ( Player(5), Player(8), true )

    call SetPlayerAllianceStateAllyBJ( Player(5), Player(9), true )

    call SetPlayerAllianceStateAllyBJ( Player(5), Player(10), true )

    call SetPlayerAllianceStateAllyBJ( Player(5), Player(11), true )

    call SetPlayerAllianceStateAllyBJ( Player(6), Player(1), true )

    call SetPlayerAllianceStateAllyBJ( Player(6), Player(2), true )

    call SetPlayerAllianceStateAllyBJ( Player(6), Player(3), true )

    call SetPlayerAllianceStateAllyBJ( Player(6), Player(4), true )

    call SetPlayerAllianceStateAllyBJ( Player(6), Player(5), true )

    call SetPlayerAllianceStateAllyBJ( Player(6), Player(7), true )

    call SetPlayerAllianceStateAllyBJ( Player(6), Player(8), true )

    call SetPlayerAllianceStateAllyBJ( Player(6), Player(9), true )

    call SetPlayerAllianceStateAllyBJ( Player(6), Player(10), true )

    call SetPlayerAllianceStateAllyBJ( Player(6), Player(11), true )

    call SetPlayerAllianceStateAllyBJ( Player(7), Player(1), true )

    call SetPlayerAllianceStateAllyBJ( Player(7), Player(2), true )

    call SetPlayerAllianceStateAllyBJ( Player(7), Player(3), true )

    call SetPlayerAllianceStateAllyBJ( Player(7), Player(4), true )

    call SetPlayerAllianceStateAllyBJ( Player(7), Player(5), true )

    call SetPlayerAllianceStateAllyBJ( Player(7), Player(6), true )

    call SetPlayerAllianceStateAllyBJ( Player(7), Player(8), true )

    call SetPlayerAllianceStateAllyBJ( Player(7), Player(9), true )

    call SetPlayerAllianceStateAllyBJ( Player(7), Player(10), true )

    call SetPlayerAllianceStateAllyBJ( Player(7), Player(11), true )

    call SetPlayerAllianceStateAllyBJ( Player(8), Player(1), true )

    call SetPlayerAllianceStateAllyBJ( Player(8), Player(2), true )

    call SetPlayerAllianceStateAllyBJ( Player(8), Player(3), true )

    call SetPlayerAllianceStateAllyBJ( Player(8), Player(4), true )

    call SetPlayerAllianceStateAllyBJ( Player(8), Player(5), true )

    call SetPlayerAllianceStateAllyBJ( Player(8), Player(6), true )

    call SetPlayerAllianceStateAllyBJ( Player(8), Player(7), true )

    call SetPlayerAllianceStateAllyBJ( Player(8), Player(9), true )

    call SetPlayerAllianceStateAllyBJ( Player(8), Player(10), true )

    call SetPlayerAllianceStateAllyBJ( Player(8), Player(11), true )

    call SetPlayerAllianceStateAllyBJ( Player(9), Player(1), true )

    call SetPlayerAllianceStateAllyBJ( Player(9), Player(2), true )

    call SetPlayerAllianceStateAllyBJ( Player(9), Player(3), true )

    call SetPlayerAllianceStateAllyBJ( Player(9), Player(4), true )

    call SetPlayerAllianceStateAllyBJ( Player(9), Player(5), true )

    call SetPlayerAllianceStateAllyBJ( Player(9), Player(6), true )

    call SetPlayerAllianceStateAllyBJ( Player(9), Player(7), true )

    call SetPlayerAllianceStateAllyBJ( Player(9), Player(8), true )

    call SetPlayerAllianceStateAllyBJ( Player(9), Player(10), true )

    call SetPlayerAllianceStateAllyBJ( Player(9), Player(11), true )

    call SetPlayerAllianceStateAllyBJ( Player(10), Player(1), true )

    call SetPlayerAllianceStateAllyBJ( Player(10), Player(2), true )

    call SetPlayerAllianceStateAllyBJ( Player(10), Player(3), true )

    call SetPlayerAllianceStateAllyBJ( Player(10), Player(4), true )

    call SetPlayerAllianceStateAllyBJ( Player(10), Player(5), true )

    call SetPlayerAllianceStateAllyBJ( Player(10), Player(6), true )

    call SetPlayerAllianceStateAllyBJ( Player(10), Player(7), true )

    call SetPlayerAllianceStateAllyBJ( Player(10), Player(8), true )

    call SetPlayerAllianceStateAllyBJ( Player(10), Player(9), true )

    call SetPlayerAllianceStateAllyBJ( Player(10), Player(11), true )

    call SetPlayerAllianceStateAllyBJ( Player(11), Player(1), true )

    call SetPlayerAllianceStateAllyBJ( Player(11), Player(2), true )

    call SetPlayerAllianceStateAllyBJ( Player(11), Player(3), true )

    call SetPlayerAllianceStateAllyBJ( Player(11), Player(4), true )

    call SetPlayerAllianceStateAllyBJ( Player(11), Player(5), true )

    call SetPlayerAllianceStateAllyBJ( Player(11), Player(6), true )

    call SetPlayerAllianceStateAllyBJ( Player(11), Player(7), true )

    call SetPlayerAllianceStateAllyBJ( Player(11), Player(8), true )

    call SetPlayerAllianceStateAllyBJ( Player(11), Player(9), true )

    call SetPlayerAllianceStateAllyBJ( Player(11), Player(10), true )



    //   Shared Vision

    call SetPlayerAllianceStateVisionBJ( Player(1), Player(2), true )

    call SetPlayerAllianceStateVisionBJ( Player(1), Player(3), true )

    call SetPlayerAllianceStateVisionBJ( Player(1), Player(4), true )

    call SetPlayerAllianceStateVisionBJ( Player(1), Player(5), true )

    call SetPlayerAllianceStateVisionBJ( Player(1), Player(6), true )

    call SetPlayerAllianceStateVisionBJ( Player(1), Player(7), true )

    call SetPlayerAllianceStateVisionBJ( Player(1), Player(8), true )

    call SetPlayerAllianceStateVisionBJ( Player(1), Player(9), true )

    call SetPlayerAllianceStateVisionBJ( Player(1), Player(10), true )

    call SetPlayerAllianceStateVisionBJ( Player(1), Player(11), true )

    call SetPlayerAllianceStateVisionBJ( Player(2), Player(1), true )

    call SetPlayerAllianceStateVisionBJ( Player(2), Player(3), true )

    call SetPlayerAllianceStateVisionBJ( Player(2), Player(4), true )

    call SetPlayerAllianceStateVisionBJ( Player(2), Player(5), true )

    call SetPlayerAllianceStateVisionBJ( Player(2), Player(6), true )

    call SetPlayerAllianceStateVisionBJ( Player(2), Player(7), true )

    call SetPlayerAllianceStateVisionBJ( Player(2), Player(8), true )

    call SetPlayerAllianceStateVisionBJ( Player(2), Player(9), true )

    call SetPlayerAllianceStateVisionBJ( Player(2), Player(10), true )

    call SetPlayerAllianceStateVisionBJ( Player(2), Player(11), true )

    call SetPlayerAllianceStateVisionBJ( Player(3), Player(1), true )

    call SetPlayerAllianceStateVisionBJ( Player(3), Player(2), true )

    call SetPlayerAllianceStateVisionBJ( Player(3), Player(4), true )

    call SetPlayerAllianceStateVisionBJ( Player(3), Player(5), true )

    call SetPlayerAllianceStateVisionBJ( Player(3), Player(6), true )

    call SetPlayerAllianceStateVisionBJ( Player(3), Player(7), true )

    call SetPlayerAllianceStateVisionBJ( Player(3), Player(8), true )

    call SetPlayerAllianceStateVisionBJ( Player(3), Player(9), true )

    call SetPlayerAllianceStateVisionBJ( Player(3), Player(10), true )

    call SetPlayerAllianceStateVisionBJ( Player(3), Player(11), true )

    call SetPlayerAllianceStateVisionBJ( Player(4), Player(1), true )

    call SetPlayerAllianceStateVisionBJ( Player(4), Player(2), true )

    call SetPlayerAllianceStateVisionBJ( Player(4), Player(3), true )

    call SetPlayerAllianceStateVisionBJ( Player(4), Player(5), true )

    call SetPlayerAllianceStateVisionBJ( Player(4), Player(6), true )

    call SetPlayerAllianceStateVisionBJ( Player(4), Player(7), true )

    call SetPlayerAllianceStateVisionBJ( Player(4), Player(8), true )

    call SetPlayerAllianceStateVisionBJ( Player(4), Player(9), true )

    call SetPlayerAllianceStateVisionBJ( Player(4), Player(10), true )

    call SetPlayerAllianceStateVisionBJ( Player(4), Player(11), true )

    call SetPlayerAllianceStateVisionBJ( Player(5), Player(1), true )

    call SetPlayerAllianceStateVisionBJ( Player(5), Player(2), true )

    call SetPlayerAllianceStateVisionBJ( Player(5), Player(3), true )

    call SetPlayerAllianceStateVisionBJ( Player(5), Player(4), true )

    call SetPlayerAllianceStateVisionBJ( Player(5), Player(6), true )

    call SetPlayerAllianceStateVisionBJ( Player(5), Player(7), true )

    call SetPlayerAllianceStateVisionBJ( Player(5), Player(8), true )

    call SetPlayerAllianceStateVisionBJ( Player(5), Player(9), true )

    call SetPlayerAllianceStateVisionBJ( Player(5), Player(10), true )

    call SetPlayerAllianceStateVisionBJ( Player(5), Player(11), true )

    call SetPlayerAllianceStateVisionBJ( Player(6), Player(1), true )

    call SetPlayerAllianceStateVisionBJ( Player(6), Player(2), true )

    call SetPlayerAllianceStateVisionBJ( Player(6), Player(3), true )

    call SetPlayerAllianceStateVisionBJ( Player(6), Player(4), true )

    call SetPlayerAllianceStateVisionBJ( Player(6), Player(5), true )

    call SetPlayerAllianceStateVisionBJ( Player(6), Player(7), true )

    call SetPlayerAllianceStateVisionBJ( Player(6), Player(8), true )

    call SetPlayerAllianceStateVisionBJ( Player(6), Player(9), true )

    call SetPlayerAllianceStateVisionBJ( Player(6), Player(10), true )

    call SetPlayerAllianceStateVisionBJ( Player(6), Player(11), true )

    call SetPlayerAllianceStateVisionBJ( Player(7), Player(1), true )

    call SetPlayerAllianceStateVisionBJ( Player(7), Player(2), true )

    call SetPlayerAllianceStateVisionBJ( Player(7), Player(3), true )

    call SetPlayerAllianceStateVisionBJ( Player(7), Player(4), true )

    call SetPlayerAllianceStateVisionBJ( Player(7), Player(5), true )

    call SetPlayerAllianceStateVisionBJ( Player(7), Player(6), true )

    call SetPlayerAllianceStateVisionBJ( Player(7), Player(8), true )

    call SetPlayerAllianceStateVisionBJ( Player(7), Player(9), true )

    call SetPlayerAllianceStateVisionBJ( Player(7), Player(10), true )

    call SetPlayerAllianceStateVisionBJ( Player(7), Player(11), true )

    call SetPlayerAllianceStateVisionBJ( Player(8), Player(1), true )

    call SetPlayerAllianceStateVisionBJ( Player(8), Player(2), true )

    call SetPlayerAllianceStateVisionBJ( Player(8), Player(3), true )

    call SetPlayerAllianceStateVisionBJ( Player(8), Player(4), true )

    call SetPlayerAllianceStateVisionBJ( Player(8), Player(5), true )

    call SetPlayerAllianceStateVisionBJ( Player(8), Player(6), true )

    call SetPlayerAllianceStateVisionBJ( Player(8), Player(7), true )

    call SetPlayerAllianceStateVisionBJ( Player(8), Player(9), true )

    call SetPlayerAllianceStateVisionBJ( Player(8), Player(10), true )

    call SetPlayerAllianceStateVisionBJ( Player(8), Player(11), true )

    call SetPlayerAllianceStateVisionBJ( Player(9), Player(1), true )

    call SetPlayerAllianceStateVisionBJ( Player(9), Player(2), true )

    call SetPlayerAllianceStateVisionBJ( Player(9), Player(3), true )

    call SetPlayerAllianceStateVisionBJ( Player(9), Player(4), true )

    call SetPlayerAllianceStateVisionBJ( Player(9), Player(5), true )

    call SetPlayerAllianceStateVisionBJ( Player(9), Player(6), true )

    call SetPlayerAllianceStateVisionBJ( Player(9), Player(7), true )

    call SetPlayerAllianceStateVisionBJ( Player(9), Player(8), true )

    call SetPlayerAllianceStateVisionBJ( Player(9), Player(10), true )

    call SetPlayerAllianceStateVisionBJ( Player(9), Player(11), true )

    call SetPlayerAllianceStateVisionBJ( Player(10), Player(1), true )

    call SetPlayerAllianceStateVisionBJ( Player(10), Player(2), true )

    call SetPlayerAllianceStateVisionBJ( Player(10), Player(3), true )

    call SetPlayerAllianceStateVisionBJ( Player(10), Player(4), true )

    call SetPlayerAllianceStateVisionBJ( Player(10), Player(5), true )

    call SetPlayerAllianceStateVisionBJ( Player(10), Player(6), true )

    call SetPlayerAllianceStateVisionBJ( Player(10), Player(7), true )

    call SetPlayerAllianceStateVisionBJ( Player(10), Player(8), true )

    call SetPlayerAllianceStateVisionBJ( Player(10), Player(9), true )

    call SetPlayerAllianceStateVisionBJ( Player(10), Player(11), true )

    call SetPlayerAllianceStateVisionBJ( Player(11), Player(1), true )

    call SetPlayerAllianceStateVisionBJ( Player(11), Player(2), true )

    call SetPlayerAllianceStateVisionBJ( Player(11), Player(3), true )

    call SetPlayerAllianceStateVisionBJ( Player(11), Player(4), true )

    call SetPlayerAllianceStateVisionBJ( Player(11), Player(5), true )

    call SetPlayerAllianceStateVisionBJ( Player(11), Player(6), true )

    call SetPlayerAllianceStateVisionBJ( Player(11), Player(7), true )

    call SetPlayerAllianceStateVisionBJ( Player(11), Player(8), true )

    call SetPlayerAllianceStateVisionBJ( Player(11), Player(9), true )

    call SetPlayerAllianceStateVisionBJ( Player(11), Player(10), true )



endfunction



function InitAllyPriorities takes nothing returns nothing



    call SetStartLocPrioCount( 0, 11 )

    call SetStartLocPrio( 0, 0, 1, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 0, 1, 2, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 0, 2, 3, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 0, 3, 4, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 0, 4, 5, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 0, 5, 6, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 0, 6, 7, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 0, 7, 8, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 0, 8, 9, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 0, 9, 10, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 0, 10, 11, MAP_LOC_PRIO_HIGH )



    call SetStartLocPrioCount( 1, 11 )

    call SetStartLocPrio( 1, 0, 0, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 1, 1, 2, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 1, 2, 3, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 1, 3, 4, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 1, 4, 5, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 1, 5, 6, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 1, 6, 7, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 1, 7, 8, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 1, 8, 9, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 1, 9, 10, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 1, 10, 11, MAP_LOC_PRIO_HIGH )



    call SetStartLocPrioCount( 2, 11 )

    call SetStartLocPrio( 2, 0, 0, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 2, 1, 1, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 2, 2, 3, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 2, 3, 4, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 2, 4, 5, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 2, 5, 6, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 2, 6, 7, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 2, 7, 8, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 2, 8, 9, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 2, 9, 10, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 2, 10, 11, MAP_LOC_PRIO_HIGH )



    call SetStartLocPrioCount( 3, 11 )

    call SetStartLocPrio( 3, 0, 0, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 3, 1, 1, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 3, 2, 2, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 3, 3, 4, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 3, 4, 5, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 3, 5, 6, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 3, 6, 7, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 3, 7, 8, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 3, 8, 9, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 3, 9, 10, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 3, 10, 11, MAP_LOC_PRIO_HIGH )



    call SetStartLocPrioCount( 4, 11 )

    call SetStartLocPrio( 4, 0, 0, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 4, 1, 1, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 4, 2, 2, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 4, 3, 3, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 4, 4, 5, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 4, 5, 6, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 4, 6, 7, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 4, 7, 8, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 4, 8, 9, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 4, 9, 10, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 4, 10, 11, MAP_LOC_PRIO_HIGH )



    call SetStartLocPrioCount( 5, 11 )

    call SetStartLocPrio( 5, 0, 0, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 5, 1, 1, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 5, 2, 2, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 5, 3, 3, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 5, 4, 4, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 5, 5, 6, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 5, 6, 7, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 5, 7, 8, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 5, 8, 9, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 5, 9, 10, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 5, 10, 11, MAP_LOC_PRIO_HIGH )



    call SetStartLocPrioCount( 6, 11 )

    call SetStartLocPrio( 6, 0, 0, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 6, 1, 1, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 6, 2, 2, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 6, 3, 3, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 6, 4, 4, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 6, 5, 5, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 6, 6, 7, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 6, 7, 8, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 6, 8, 9, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 6, 9, 10, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 6, 10, 11, MAP_LOC_PRIO_HIGH )



    call SetStartLocPrioCount( 7, 11 )

    call SetStartLocPrio( 7, 0, 0, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 7, 1, 1, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 7, 2, 2, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 7, 3, 3, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 7, 4, 4, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 7, 5, 5, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 7, 6, 6, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 7, 7, 8, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 7, 8, 9, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 7, 9, 10, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 7, 10, 11, MAP_LOC_PRIO_HIGH )



    call SetStartLocPrioCount( 8, 11 )

    call SetStartLocPrio( 8, 0, 0, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 8, 1, 1, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 8, 2, 2, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 8, 3, 3, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 8, 4, 4, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 8, 5, 5, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 8, 6, 6, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 8, 7, 7, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 8, 8, 9, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 8, 9, 10, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 8, 10, 11, MAP_LOC_PRIO_HIGH )



    call SetStartLocPrioCount( 9, 11 )

    call SetStartLocPrio( 9, 0, 0, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 9, 1, 1, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 9, 2, 2, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 9, 3, 3, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 9, 4, 4, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 9, 5, 5, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 9, 6, 6, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 9, 7, 7, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 9, 8, 8, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 9, 9, 10, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 9, 10, 11, MAP_LOC_PRIO_HIGH )



    call SetStartLocPrioCount( 10, 11 )

    call SetStartLocPrio( 10, 0, 0, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 10, 1, 1, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 10, 2, 2, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 10, 3, 3, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 10, 4, 4, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 10, 5, 5, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 10, 6, 6, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 10, 7, 7, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 10, 8, 8, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 10, 9, 9, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 10, 10, 11, MAP_LOC_PRIO_HIGH )



    call SetStartLocPrioCount( 11, 11 )

    call SetStartLocPrio( 11, 0, 0, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 11, 1, 1, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 11, 2, 2, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 11, 3, 3, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 11, 4, 4, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 11, 5, 5, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 11, 6, 6, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 11, 7, 7, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 11, 8, 8, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 11, 9, 9, MAP_LOC_PRIO_HIGH )

    call SetStartLocPrio( 11, 10, 10, MAP_LOC_PRIO_HIGH )

endfunction



//***************************************************************************

//*

//*  Main Initialization

//*

//***************************************************************************



//===========================================================================

function main takes nothing returns nothing

    call SetCameraBounds( -1280.0 + GetCameraMargin(CAMERA_MARGIN_LEFT), -1536.0 + GetCameraMargin(CAMERA_MARGIN_BOTTOM), 1280.0 - GetCameraMargin(CAMERA_MARGIN_RIGHT), 1024.0 - GetCameraMargin(CAMERA_MARGIN_TOP), -1280.0 + GetCameraMargin(CAMERA_MARGIN_LEFT), 1024.0 - GetCameraMargin(CAMERA_MARGIN_TOP), 1280.0 - GetCameraMargin(CAMERA_MARGIN_RIGHT), -1536.0 + GetCameraMargin(CAMERA_MARGIN_BOTTOM) )

    call SetDayNightModels( "Environment\\DNC\\DNCLordaeron\\DNCLordaeronTerrain\\DNCLordaeronTerrain.mdl", "Environment\\DNC\\DNCLordaeron\\DNCLordaeronUnit\\DNCLordaeronUnit.mdl" )

    call NewSoundEnvironment( "Default" )

    call SetAmbientDaySound( "LordaeronSummerDay" )

    call SetAmbientNightSound( "LordaeronSummerNight" )

    call SetMapMusic( "Music", true, 0 )

    call InitSounds(  )

    call CreateRegions(  )

    call InitBlizzard(  )

    call InitGlobals(  )

    call InitCustomTriggers(  )

    call RunInitializationTriggers(  )



endfunction



//***************************************************************************

//*

//*  Map Configuration

//*

//***************************************************************************



function config takes nothing returns nothing

    call SetMapName( "TRIGSTR_018" )

    call SetMapDescription( "TRIGSTR_020" )

    call SetPlayers( 12 )

    call SetTeams( 12 )

    call SetGamePlacement( MAP_PLACEMENT_TEAMS_TOGETHER )



    call DefineStartLocation( 0, -10432.0, 10304.0 )

    call DefineStartLocation( 1, -10432.0, 10304.0 )

    call DefineStartLocation( 2, -10432.0, 10304.0 )

    call DefineStartLocation( 3, -10432.0, 10304.0 )

    call DefineStartLocation( 4, -10432.0, 10304.0 )

    call DefineStartLocation( 5, -10432.0, 10304.0 )

    call DefineStartLocation( 6, -10432.0, 10304.0 )

    call DefineStartLocation( 7, -10432.0, 10304.0 )

    call DefineStartLocation( 8, -10432.0, 10304.0 )

    call DefineStartLocation( 9, -10432.0, 10304.0 )

    call DefineStartLocation( 10, -10432.0, 10304.0 )

    call DefineStartLocation( 11, -10432.0, 10304.0 )



    // Player setup

    call InitCustomPlayerSlots(  )

    call InitCustomTeams(  )

    call InitAllyPriorities(  )

endfunction



