1. Are you planning to upload your awesome map to Hive? Please review the rules here.
    Dismiss Notice
  2. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  3. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still haven't received your rank award? Then please contact the administration.
    Dismiss Notice
  4. Weave light to take you to your highest hopes - the 6th Special Effect Contest is here!
    Dismiss Notice
  5. Lead your forces to battle in the 15th Techtree Contest. The call is yours, commander!
    Dismiss Notice
  6. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

Trigger Viewer

Bs Antarctica PreAlpha 0.35 (opt).w3x
Variables
Initialization Triggers
Weapon Initializer
InitTemplate
InitTutorial
TradeSys Init
WeaponsTest
Upgrades Init
Map Init
Pirates Movement Control
ShipTypes Init
Level Init
ShipCargo
ShipReqs
Weight Init
AdminRights
Bounty System
Bounty
Spawner
Wave System
Spawner
Search / Sort
QSort
Bsearch
Features
Toggle Messages
Multiboard
HelpFile
BankSys
TaxSys
Status actualizer
Zoom
Reviver
Reviver
Mapper Tools
TeamSys
NamePlayer
GetPlayerFeedback
Attacher
Dialogs
GameTime
Hash
ItemAttacher
PUI
RandomSet
RectTools
TriggerGroups
Unit Attacher
UtilDebugger
Utilities
Debugger
Tutorial
Tutorial
Weapon systems
NewWeaponSys
ItemSwitcher
ItemUpgrader
ItemUpgrade on Click
ItemStacker
Combiner
WeaponSys
Main
Leveable ItemSkills
TradeItemSwitcher
AdminSystem
Cargo System
LeaverHandler
Gold per second
Upgrader
Spells
Template
Master of the wind
Old TradeSystem
TradeSystem
TradepointUpgradeSystem
TradeRoute
TradeRouteSettings
ResourceHandler
AITraders
TradeSystem
New TS
Tp Inspector
Ship Change
Change Ship
TODO:
//TESH.scrollpos=0
//TESH.alwaysfold=0
library IMG
function CreateImageEx takes string imagePath, real size, real x, real y, real z, boolean showImage returns image
    local image i = CreateImage(imagePath, size, size, 0, x - (size / 2), y - (size / 2), z, 0, 0, 0, 2)
    call SetImageRenderAlways(i, true)
    call ShowImage(i, showImage)
    return i
endfunction
endlibrary
Name Type Is Array Initial Value
//TESH.scrollpos=-1
//TESH.alwaysfold=0
//WARNING: Computergenerated script by WeaponScript.py version 0.01. DO NOT EDIT manually.
//! runtextmacro Filter( "BHC", "true",  "true",  "true" )
//! runtextmacro Filter( "BH",  "true",  "true",  "false" )
//! runtextmacro Filter( "BC",  "true",  "false", "true" )
//! runtextmacro Filter( "HC",  "false", "true",  "true" )
//! runtextmacro Filter( "B",   "true",  "true",  "true" )
//! runtextmacro Filter( "H",   "false", "true",  "false" )
//! runtextmacro Filter( "C",   "false", "false", "true" )

library WeaponInit initializer InitWeapons needs ItemUpgrader, Combiner, CostAttacherUnit, CostAttacherItem, WeightAttacherItem, BHC, BH, BC, B, HC, H, C
//! textmacro Filter takes NAME, B, H, C

globals
    boolexpr $NAME$Filter
endglobals

library $NAME$ initializer INIT

private function FilterFunc takes nothing returns boolean
    local unit target = GetFilterUnit()
    if IsUnitType( target, UNIT_TYPE_STRUCTURE ) then
        return $B$
    elseif IsUnitType( target, UNIT_TYPE_HERO ) then
        return $H$
    else
        return $C$
    endif
    return false
endfunction

private function INIT takes nothing returns nothing
    set $NAME$Filter = Filter( function FilterFunc )
endfunction

endlibrary

//! endtextmacro

private function InitUpgrades takes nothing returns nothing
 
    call SetItemUpgrade( 'I009', 'I00A', 455 ) // Rocket Pack        -> Rocket Pack ( upgrade )
 
    call SetItemUpgrade( 'I004', 'I006', 220 ) // Light Cannon       -> Light Cannon ( upgrade )
 
    call SetItemUpgrade( 'I005', 'I007', 1095 ) // Advanced Cannon    -> Advanced Cannon ( upgrade )
 
    call SetItemUpgrade( 'I000', 'I001', 1180 ) // Energy Torpedo     -> Energy Torpedo ( upgrade )
 
    call SetItemUpgrade( 'I00C', 'I00B', 810 ) // Howitze            -> Howitze ( upgrade )
 
    call SetItemUpgrade( 'I002', 'I003', 415 ) // Rocket Cannon      -> Rocket Cannon ( upgrade )
 
    call SetItemUpgrade( 'I00D', 'I00I', 415 ) // Firebolt Cannon    -> Firebolt Cannon ( upgrade )
 
    call SetItemUpgrade( 'I00E', 'I00I', 1295 ) // Pure Atom Ownage Cannon -> Pure Atom Ownage Cannon ( upgrade )
 
    call SetItemUpgrade( 'I00F', 'I00I', 320 ) // Vine-Repeater A-39 -> Vine-Repeater A-39 ( upgrade )

    call NewCombineRecipe( 'n00H', 'I006', 'I00A', 'I00J' ) // Light Cannon ( upgrade ) + Rocket Pack ( upgrade ) -> Submachine Gun    
    call SetUnitTypeCost( 'n00H', 2015 )
   
    call NewCombineRecipe( 'n00D', 'I007', 'I006', 'I008' ) // Advanced Cannon ( upgrade ) + Light Cannon ( upgrade ) -> Advanced Battery  
    call SetUnitTypeCost( 'n00D', 1505 )
   
    call NewCombineRecipe( 'n00F', 'I00B', 'I003', 'I00H' ) // Howitze ( upgrade ) + Rocket Cannon ( upgrade ) -> Mortar Team      
    call SetUnitTypeCost( 'n00F', 1640 )
   
endfunction
globals
    autoweapontype Basic_Cannon
    autoweapontype Light_Rocket
    autoweapontype Light_Gun
    autoweapontype Light_Cannon
    autoweapontype Light_Cannon___upgrade
    autoweapontype Rocket_Cannon
    autoweapontype Firebolt_Cannon
    autoweapontype Rocket_Cannon___upgrade
    autoweapontype Vine_Repeater_A_39
    autoweapontype Rocket_Pack
    autoweapontype Firebolt_Cannon___upgrade
    autoweapontype Advanced_Cannon
    autoweapontype Vine_Repeater_A_39___upgrade
    autoweapontype Rocket_Pack___upgrade
    autoweapontype Energy_Torpedo
    autoweapontype Advanced_Cannon___upgrade
    autoweapontype Howitze
    autoweapontype Energy_Torpedo___upgrade
    autoweapontype Howitze___upgrade
    autoweapontype Pure_Atom_Ownage_Cannon
    autoweapontype Submachine_Gun
    autoweapontype Advanced_Battery
    autoweapontype Pure_Atom_Ownage_Cannon___upgrade
    autoweapontype Mortar_Team
endglobals

private function InitWeapons takes nothing returns nothing
   
    set Basic_Cannon = CreateWeaponType( 60, 1.600000, 850.000000, 1, 1.600000, HCFilter, TARGET_MODE_SALVE, 'n00J', "attack" )
    call WeaponTypeAddItemTypeId( Basic_Cannon, 'I004' )
   
    call SetItemTypeCost( 'I004', 750)
    call SetItemTypeWeight( 'I004', 6)
   
    set Light_Rocket = CreateWeaponType( 30, 0.600000, 550.000000, 1, 0.600000, HCFilter, TARGET_MODE_SALVE, 'n00J', "attack" )
    call WeaponTypeAddItemTypeId( Light_Rocket, 'I004' )
   
    call SetItemTypeCost( 'I004', 750)
    call SetItemTypeWeight( 'I004', 5)
   
    set Light_Gun = CreateWeaponType( 50, 1.800000, 1250.000000, 1, 1.800000, HCFilter, TARGET_MODE_SALVE, 'n00J', "attack" )
    call WeaponTypeAddItemTypeId( Light_Gun, 'I004' )
   
    call SetItemTypeCost( 'I004', 750)
    call SetItemTypeWeight( 'I004', 12)
   
    set Light_Cannon = CreateWeaponType( 50, 1.400000, 900.000000, 1, 1.400000, HCFilter, TARGET_MODE_SALVE, 'n00J', "attack" )
    call WeaponTypeAddItemTypeId( Light_Cannon, 'I004' )
   
    call SetItemTypeCost( 'I006', 1055)
    call SetItemTypeWeight( 'I006', 6)
   
    call SetItemTypeCost( 'I004', 835)
    call SetItemTypeWeight( 'I004', 6)
   
    set Light_Cannon___upgrade = CreateWeaponType( 50, 1.100000, 900.000000, 1, 1.100000, HCFilter, TARGET_MODE_SALVE, 'n00J', "attack" )
    call WeaponTypeAddItemTypeId( Light_Cannon___upgrade, 'I006' )
   
    set Rocket_Cannon = CreateWeaponType( 15, 0.500000, 1300.000000, 1, 0.500000, HCFilter, TARGET_MODE_SALVE, 'n00J', "attack" )
    call WeaponTypeAddItemTypeId( Rocket_Cannon, 'I002' )
   
    call SetItemTypeCost( 'I003', 1550)
    call SetItemTypeWeight( 'I003', 10)
   
    call SetItemTypeCost( 'I002', 1135)
    call SetItemTypeWeight( 'I002', 10)
   
    set Firebolt_Cannon = CreateWeaponType( 200, 3.000000, 825.000000, 1, 3.000000, HCFilter, TARGET_MODE_SALVE, 'n00J', "attack" )
    call WeaponTypeAddItemTypeId( Firebolt_Cannon, 'I00D' )
   
    call SetItemTypeCost( 'I00I', 1855)
    call SetItemTypeWeight( 'I00I', 10)
   
    call SetItemTypeCost( 'I00D', 1440)
    call SetItemTypeWeight( 'I00D', 10)
   
    set Rocket_Cannon___upgrade = CreateWeaponType( 20, 0.500000, 1300.000000, 1, 0.500000, HCFilter, TARGET_MODE_SALVE, 'n00J', "attack" )
    call WeaponTypeAddItemTypeId( Rocket_Cannon___upgrade, 'I003' )
   
    set Vine_Repeater_A_39 = CreateWeaponType( 30, 0.500000, 900.000000, 1, 0.500000, BHCFilter, TARGET_MODE_SALVE, 'n00J', "attack" )
    call WeaponTypeAddItemTypeId( Vine_Repeater_A_39, 'I00F' )
   
    call SetItemTypeCost( 'I00I', 2055)
    call SetItemTypeWeight( 'I00I', 12)
   
    call SetItemTypeCost( 'I00F', 1735)
    call SetItemTypeWeight( 'I00F', 12)
   
    set Rocket_Pack = CreateWeaponType( 40, 0.500000, 600.000000, 1, 0.500000, BHCFilter, TARGET_MODE_SALVE, 'n00J', "attack" )
    call WeaponTypeAddItemTypeId( Rocket_Pack, 'I009' )
   
    call SetItemTypeCost( 'I00A', 2225)
    call SetItemTypeWeight( 'I00A', 10)
   
    call SetItemTypeCost( 'I009', 1770)
    call SetItemTypeWeight( 'I009', 10)
   
    set Firebolt_Cannon___upgrade = CreateWeaponType( 200, 3.000000, 1050.000000, 1, 3.000000, HCFilter, TARGET_MODE_SALVE, 'n00J', "attack" )
    call WeaponTypeAddItemTypeId( Firebolt_Cannon___upgrade, 'I00I' )
   
    set Advanced_Cannon = CreateWeaponType( 90, 1.500000, 1050.000000, 1, 1.500000, BHCFilter, TARGET_MODE_SALVE, 'n00J', "attack" )
    call WeaponTypeAddItemTypeId( Advanced_Cannon, 'I005' )
   
    call SetItemTypeCost( 'I007', 3025)
    call SetItemTypeWeight( 'I007', 15)
   
    call SetItemTypeCost( 'I005', 1930)
    call SetItemTypeWeight( 'I005', 15)
   
    set Vine_Repeater_A_39___upgrade = CreateWeaponType( 45, 0.500000, 900.000000, 1, 0.500000, HCFilter, TARGET_MODE_SALVE, 'n00J', "attack" )
    call WeaponTypeAddItemTypeId( Vine_Repeater_A_39___upgrade, 'I00I' )
   
    set Rocket_Pack___upgrade = CreateWeaponType( 40, 0.400000, 600.000000, 1, 0.400000, BHCFilter, TARGET_MODE_SALVE, 'n00J', "attack" )
    call WeaponTypeAddItemTypeId( Rocket_Pack___upgrade, 'I00A' )
   
    set Energy_Torpedo = CreateWeaponType( 300, 4.000000, 1150.000000, 1, 4.000000, HCFilter, TARGET_MODE_SALVE, 'n00J', "attack" )
    call WeaponTypeAddItemTypeId( Energy_Torpedo, 'I000' )
   
    call SetItemTypeCost( 'I001', 3785)
    call SetItemTypeWeight( 'I001', 22)
   
    call SetItemTypeCost( 'I000', 2605)
    call SetItemTypeWeight( 'I000', 22)
   
    set Advanced_Cannon___upgrade = CreateWeaponType( 125, 1.500000, 1050.000000, 1, 1.500000, BHCFilter, TARGET_MODE_SALVE, 'n00J', "attack" )
    call WeaponTypeAddItemTypeId( Advanced_Cannon___upgrade, 'I007' )
   
    set Howitze = CreateWeaponType( 80, 1.000000, 1300.000000, 1, 1.000000, HCFilter, TARGET_MODE_SALVE, 'n00J', "attack" )
    call WeaponTypeAddItemTypeId( Howitze, 'I00C' )
   
    call SetItemTypeCost( 'I00B', 3865)
    call SetItemTypeWeight( 'I00B', 28)
   
    call SetItemTypeCost( 'I00C', 3055)
    call SetItemTypeWeight( 'I00C', 28)
   
    set Energy_Torpedo___upgrade = CreateWeaponType( 400, 4.000000, 1150.000000, 1, 4.000000, HCFilter, TARGET_MODE_SALVE, 'n00J', "attack" )
    call WeaponTypeAddItemTypeId( Energy_Torpedo___upgrade, 'I001' )
   
    set Howitze___upgrade = CreateWeaponType( 80, 0.800000, 1300.000000, 1, 0.800000, HCFilter, TARGET_MODE_SALVE, 'n00J', "attack" )
    call WeaponTypeAddItemTypeId( Howitze___upgrade, 'I00B' )
   
    set Pure_Atom_Ownage_Cannon = CreateWeaponType( 500, 3.000000, 750.000000, 1, 3.000000, BHCFilter, TARGET_MODE_SALVE, 'n00J', "attack" )
    call WeaponTypeAddItemTypeId( Pure_Atom_Ownage_Cannon, 'I00E' )
   
    call SetItemTypeCost( 'I00I', 6345)
    call SetItemTypeWeight( 'I00I', 27)
   
    call SetItemTypeCost( 'I00E', 5050)
    call SetItemTypeWeight( 'I00E', 27)
   
    set Submachine_Gun = CreateWeaponType( 40, 0.180000, 575.000000, 1, 0.180000, BHCFilter, TARGET_MODE_SALVE, 'n00J', "attack" )
    call WeaponTypeAddItemTypeId( Submachine_Gun, 'I00J' )
   
    call SetItemTypeCost( 'I00J', 5295)
    call SetItemTypeWeight( 'I00J', 29)
   
    set Advanced_Battery = CreateWeaponType( 95, 1.200000, 1050.000000, 2, 0.600000, BHCFilter, TARGET_MODE_SALVE, 'n00J', "attack" )
    call WeaponTypeAddItemTypeId( Advanced_Battery, 'I008' )
   
    call SetItemTypeCost( 'I008', 5585)
    call SetItemTypeWeight( 'I008', 45)
   
    set Pure_Atom_Ownage_Cannon___upgrade = CreateWeaponType( 1000, 4.000000, 750.000000, 1, 4.000000, HCFilter, TARGET_MODE_SALVE, 'n00J', "attack" )
    call WeaponTypeAddItemTypeId( Pure_Atom_Ownage_Cannon___upgrade, 'I00I' )
   
    set Mortar_Team = CreateWeaponType( 130, 0.750000, 1250.000000, 1, 0.750000, HCFilter, TARGET_MODE_SALVE, 'n00J', "attack" )
    call WeaponTypeAddItemTypeId( Mortar_Team, 'I00H' )
   
    call SetItemTypeCost( 'I00H', 7055)
    call SetItemTypeWeight( 'I00H', 64)
   
    call InitUpgrades()
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope Init initializer INIT

private function INIT_REALLY takes nothing returns nothing
   
endfunction

//===========================================================================
private function INIT takes nothing returns nothing
    call ExecuteFunc( SCOPE_PRIVATE + "INIT_REALLY" )
endfunction

endscope

 
//TESH.scrollpos=36
//TESH.alwaysfold=0
scope Init initializer INIT
globals
    private string DEFAULT = GREY
endglobals

private function Key takes string msg returns string
    return " |cffcc5555" + StringCase( msg, true ) + DEFAULT
endfunction

private function Target takes string msg returns string
    return " |cffc8a000" + msg + DEFAULT
endfunction

private function String takes string msg returns string
    return " '|cff7777aa" + msg + DEFAULT + "'"
endfunction

private function F takes string msg returns string
    return msg + DEFAULT
endfunction

private function INIT_REALLY takes nothing returns nothing
    local string north = F( PlayerNameUncolored[ NorthTeamId ] )
    local string south = F( PlayerNameUncolored[ SouthTeamId ] )
    local helpfile Trading     = Help( "trading",        "For trading, just buy a" + Key("trade resource") + ". Your " + Key( "cargo bay" ) + " will instantly fill up with that trade resource. Then just sail to another" + Key( "colony" ) + " and sell the resources there.\n  For trading, you will gain a little bit of" + Key("experience") +", depending on the" + Key("profit")+" you make.", 0 )
    local helpfile Colony      = Help( "colony",         "You can only buy and sell" + Key("trade resources") + " in colonies. The price is static and can be accessed whith an" + Key("ability") + " of the cargoship. Also, you can use" + String( "-h NAME" ) + " to get the prices of a special colony", Trading )
    local helpfile Resource    = Help( "trade resource", "Trade resources are represented by items. All traderesources are tradeable by all teams, but" + Key( "wood" ) + " should only be traded by " + north + " while" + Key( "iron" ) + " is profitable for " + south + " only.", Trading )
    local helpfile CargoBay    = Help( "cargo bay",      "Each shiptype can only carry a certain" + Key( "weight" ) + ", which is denoted by the cargo hold of that ship.\n  Look at your" + Key( "stats" ) + " to see how much free cargo you still have.", 0 )
    local helpfile ShipUpgrade = Help( "upgrade",        "Ships have items that will improve their fighting capabilities.\n  " + Target( "Left-Click" ) + " on an upgrade to reach the next stage.\n  " + Target( "Left-Click" ) + " on a currently upgrading item to cancel the upgrade.", 0 )
    local helpfile ChangeShip  = Help( "change ship",    "In order to change your ship, you need to fulfill certain" + Key("requirements") + ", and if the ship is of a higher ship-level you will also have to pay" + Key( "experience" ) + " for the change.\n  If you change back, you will get the experience back.", 0 )
    local helpfile Reqs        = Help( "requirements",   "The requirements you need to meet are" + Key("upgrade")+"s. A high level ship will need a high level of upgrades.", ChangeShip )
    // Resources
    local helpfile HFood        = Help( "food",   "Food is the easiest resource to trade, but profit is quite low.\n  Profitable buy:" + Key("ipion rush") + "\n  Profitable sell: Everywhere else", Resource )
    local helpfile HWood        = Help( "wood",   "Wood can only be traded by " + north + ".\n  Profitable buy:" + Key("port haddocs") + "\n  Profitable sell: All but" + Key("Ipion Rush") + " and" + Key("port haddocs"), Resource )    
    local helpfile HIron        = Help( "iron",   "Iron can only be traded by " + south + ".\n  Profitable buy:" + Key("port brooks") + "\n  Profitable sell: All but" + Key("Ipion Rush") + " and" + Key("port brooks"), Resource )    
    local helpfile HLuxuryGoods = Help( "luxury goods",   "Luxury goods take long to trade, but return the highest profit.\n  Profitable buy:" + Key("Shalhaven") + "\n  Profitable sell: Everywhere else", Resource )
   
    // "Port Brooks",  - Left Up
    // "Say Noto",     - Right up
       
    // "Ipion Rush",   - Mid
    // "Shalhaven",    - Right
   
    // "Port Haddocs", - Left Down
    // "Port Serral",  - Right Down
   
    // Help takes string name, string help, helpfile parent
    // Help( "", "", )
   
    //Commands
    local helpfile Commands    = Help( "commands",   "There is a bunch of special commands for the chat line in" + Target( "Battleships Antarctica" ) + ", most start with a '-'. The currently documented commands are all childfiles of this helpfile.", 0 )
    local helpfile HBalance    = Help( "balance",    String( "-balance" ) + " will toggle wether the balance will be your current multiboard or not. You can optionally use" + String( "-balance on" ) + " or" + String( "-balance off" ) + " for more control over its behaviour.", Commands )
    local helpfile HStats      = Help( "stats",      String( "-stats" ) + " will toggle wether the kills/deaths multiboard will be your current multiboard or not. You can optionally use" + String( "-stats on" ) + " or" + String( "-stats off" ) + " for more control over its behaviour.", Commands )
    local helpfile HShow       = Help( "show",       String( "-show toggle" ) + " will toggle wether all game-messages (not chatmessages!) will be showed to you or only a few. You can optionally use" + String( "-show all" ) + " or" + String( "-show few" ) + " for more control over its behaviour.", Commands )
    local helpfile HZoom       = Help( "zoom",       String( "-zoom" + Target( "XXXX" ) ) + " will allow you to control the field of view. You can optionally use" + String( "-f" ) + "," + String( "-m" ) + " or " + String( "-n" ) + " as well as some other commands for a faster access to preset views.", Commands )
    local helpfile HKick       = Help( "kick",       String( "-kick" + Target( "NAME" ) ) + " or" + String( "-kick" + Target( "ID" ) ) + " will start a voting to kick that player. The" + Key( "ID" ) + " can be looked at in the kills/deaths multiboard. If you leave out the argument, the command will try to give you a list of all available targets. When the vote started, simply vote with" + String( "-yes" ) + " or" + String( "-no" ) + "\n  " + Key( "NOTE: Kick is not implemented yet!" ), Commands )
   
    //call AddTutorialMessage( "" )
    set DEFAULT = LIGHTGREY
    call AddTutorialMessage( "First, take a look into your" + Key( "inventory" ) + ".\n  Do you see the items there? These are" +Key( "upgrades" ) + " that will change the stats of your ship.\n  The number of" + Key( "charges" ) + " shows which level they currently have.\n  Left-Click on the" + Target( "Sails" ) + " upgrade.")
    call AddTutorialMessage( "As you have seen, you will loose a bit of" + Target( "Gold" ) + " when you upgrade stuff. The amount you loose is shown in the" + Key( "tooltip" ) + ".\n  Peforming the upgrade, your" + Key("speed") + " has been increased. You can see that in your" +Key("stats") + "." )
    call AddTutorialMessage( "You might wonder why there is" + Key( "no weapon shop" ) + ". That is becouse you can't buy weapons yourself. The weapons are built into the" + Key( "ship" ) +".\n  Sail to the" + Target( "Left Lane" ) + ", where the creeps are currently fighting." )
    call AddTutorialMessage( "Once you are there, you will see how your ship fires firebolts. At the beginning, they do" + Key( "40" ) + " damage every" + Key( "1" ) + " second, but you can change that by upgrading your" + Target( "Weaponry" ) + " and" + Target( "Cooldown" ) + "." )    
    call AddTutorialMessage( "In" +Target("Battleships Antarctica") + ", you will have to" + Key("change your ship") + " in order to get better weapons and skills. Upgrades will be carried over to the next ship.\n  To change your ship, however, you need to fulfill a few" + Key( "requirements" ) + " and will need a bunch of " + Key( "experience" ) + ". You will loose that experience, but don't worry - your new ship is much stronger anyway." )
    call AddTutorialMessage( "If you still need any help, you can use" + String("-h" + Key("TOPIC")) + " to get help on that topic.\n  For a list of all help files, use" + String("-h index") + "." )

endfunction

//===========================================================================
private function INIT takes nothing returns nothing
    call ExecuteFunc( SCOPE_PRIVATE + "INIT_REALLY" )
endfunction

endscope

 
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope InitTradeSystem initializer INIT
globals
    tradepoint array Tp
   
    resource Food
    resource Wood
    resource Iron
    resource Luxury
   
    constant integer COST_FACTOR_FOOD = 200
    constant integer COST_FACTOR_WOOD = 500
    constant integer COST_FACTOR_IRON = 500
    constant integer COST_FACTOR_LUX  = 300
endglobals


private function INIT_RESOURCE takes nothing returns nothing
    local integer i = 0
    local integer j = 0
    local integer array tmp_ItemId
    local integer teamId
    set tmp_ItemId[ NorthTeamId ] = 'I00L'
    set tmp_ItemId[ SouthTeamId ] = 'I00M'
   
    set teamId = Team[ GetPlayerId( LOCAL_PLAYER ) ].id
   
    call AddItemToAllStock( tmp_ItemId[ teamId ], 1, 1 )
endfunction

private function TP_F takes nothing returns nothing

call Tp[5].setCost( Food.id,   0, R2I( COST_FACTOR_FOOD * 0.75 ) )
call Tp[5].setCost( Wood.id,   0, R2I( COST_FACTOR_WOOD * 0.87 ) )
call Tp[5].setCost( Iron.id,   0, R2I( COST_FACTOR_IRON * 0.8 ) )
call Tp[5].setCost( Luxury.id, 0, R2I( COST_FACTOR_LUX  * 0.75 ) )
call Tp[5].setCost( Food.id,   1, R2I( COST_FACTOR_FOOD * 0.8 ) )
call Tp[5].setCost( Wood.id,   1, R2I( COST_FACTOR_WOOD * 0.938 ) )
call Tp[5].setCost( Iron.id,   1, R2I( COST_FACTOR_IRON * 0.8 ) )
call Tp[5].setCost( Luxury.id, 1, R2I( COST_FACTOR_LUX  * 0.8 ) )
    call INIT_RESOURCE()
endfunction


private function TP_E takes nothing returns nothing

call Tp[4].setCost( Food.id,   0, R2I( COST_FACTOR_FOOD * 0.75 ) )
call Tp[4].setCost( Wood.id,   0, R2I( COST_FACTOR_WOOD * 0.6 ) )
call Tp[4].setCost( Iron.id,   0, R2I( COST_FACTOR_IRON * 0.86 ) )
call Tp[4].setCost( Luxury.id, 0, R2I( COST_FACTOR_LUX  * 0.85 ) )
call Tp[4].setCost( Food.id,   1, R2I( COST_FACTOR_FOOD * 0.8 ) )
call Tp[4].setCost( Wood.id,   1, R2I( COST_FACTOR_WOOD * 0.5 ) )
call Tp[4].setCost( Iron.id,   1, R2I( COST_FACTOR_IRON * 0.75 ) )
call Tp[4].setCost( Luxury.id, 1, R2I( COST_FACTOR_LUX  * 1 ) )


    call TimerStart( GetExpiredTimer(), 0.04, false, function TP_F )
endfunction

private function TP_D takes nothing returns nothing

call Tp[3].setCost( Food.id,   0, R2I( COST_FACTOR_FOOD * 0.86 ) )
call Tp[3].setCost( Wood.id,   0, R2I( COST_FACTOR_WOOD * 0.93 ) )
call Tp[3].setCost( Iron.id,   0, R2I( COST_FACTOR_IRON * 1 ) )
call Tp[3].setCost( Luxury.id, 0, R2I( COST_FACTOR_LUX  * 0.5 ) )
call Tp[3].setCost( Food.id,   1, R2I( COST_FACTOR_FOOD * 0.86 ) )
call Tp[3].setCost( Wood.id,   1, R2I( COST_FACTOR_WOOD * 1 ) )
call Tp[3].setCost( Iron.id,   1, R2I( COST_FACTOR_IRON * 0.93 ) )
call Tp[3].setCost( Luxury.id, 1, R2I( COST_FACTOR_LUX  * 0.5 ) )

    call TimerStart( GetExpiredTimer(), 0.04, false, function TP_E )
endfunction

private function TP_C takes nothing returns nothing

call Tp[2].setCost( Food.id,   0, R2I( COST_FACTOR_FOOD * 0.5 ) )
call Tp[2].setCost( Wood.id,   0, R2I( COST_FACTOR_WOOD * 0.7 ) )
call Tp[2].setCost( Iron.id,   0, R2I( COST_FACTOR_IRON * 0.7 ) )
call Tp[2].setCost( Luxury.id, 0, R2I( COST_FACTOR_LUX  * 0.86 ) )
call Tp[2].setCost( Food.id,   1, R2I( COST_FACTOR_FOOD * 0.5 ) )
call Tp[2].setCost( Wood.id,   1, R2I( COST_FACTOR_WOOD * 0.7 ) )
call Tp[2].setCost( Iron.id,   1, R2I( COST_FACTOR_IRON * 0.7 ) )
call Tp[2].setCost( Luxury.id, 1, R2I( COST_FACTOR_LUX  * 0.86 ) )


    call TimerStart( GetExpiredTimer(), 0.04, false, function TP_D )
endfunction

private function TP_B takes nothing returns nothing

call Tp[1].setCost( Food.id,   0, R2I( COST_FACTOR_FOOD * 0.8 ) )
call Tp[1].setCost( Wood.id,   0, R2I( COST_FACTOR_WOOD * 0.8 ) )
call Tp[1].setCost( Iron.id,   0, R2I( COST_FACTOR_IRON * 0.938 ) )
call Tp[1].setCost( Luxury.id, 0, R2I( COST_FACTOR_LUX  * 0.8 ) )
call Tp[1].setCost( Food.id,   1, R2I( COST_FACTOR_FOOD * 0.75 ) )
call Tp[1].setCost( Wood.id,   1, R2I( COST_FACTOR_WOOD * 0.8 ) )
call Tp[1].setCost( Iron.id,   1, R2I( COST_FACTOR_IRON * 0.87 ) )
call Tp[1].setCost( Luxury.id, 1, R2I( COST_FACTOR_LUX  * 0.75 ) )


    call TimerStart( GetExpiredTimer(), 0.04, false, function TP_C )
endfunction

private function TP_A takes nothing returns nothing
   
call Tp[0].setCost( Food.id,   0, R2I( COST_FACTOR_FOOD * 0.8 ) )
call Tp[0].setCost( Wood.id,   0, R2I( COST_FACTOR_WOOD * 0.75 ) )
call Tp[0].setCost( Iron.id,   0, R2I( COST_FACTOR_IRON * 0.5 ) )
call Tp[0].setCost( Luxury.id, 0, R2I( COST_FACTOR_LUX  * 1 ) )
call Tp[0].setCost( Food.id,   1, R2I( COST_FACTOR_FOOD * 0.75 ) )
call Tp[0].setCost( Wood.id,   1, R2I( COST_FACTOR_WOOD * 0.86 ) )
call Tp[0].setCost( Iron.id,   1, R2I( COST_FACTOR_IRON * 0.6 ) )
call Tp[0].setCost( Luxury.id, 1, R2I( COST_FACTOR_LUX  * 0.85 ) )

    call TimerStart( GetExpiredTimer(), 0.04, false, function TP_B )
endfunction


private function INIT takes nothing returns nothing
    local player  tpPlayer = Players[ PLAYER_NEUTRAL_PASSIVE ]
    set Food   = resource.create( "Food",         'I00N' )
    set Wood   = resource.create( "Wood",         'I00L' )
    set Iron   = resource.create( "Iron",         'I00M' )
    set Luxury = resource.create( "Luxury Goods", 'I00O' )
   
    call TimerStart( CreateTimer(), 0.08, false, function TP_A )
   
    set Tp[ 0 ] = tradepoint.create( "Port Brooks",  tpPlayer, 'n00K', -5312,  2624 ) //Left Up
    set Tp[ 1 ] = tradepoint.create( "Say Noto",     tpPlayer, 'n00K',  1472,  1348 ) //Right up
       
    set Tp[ 2 ] = tradepoint.create( "Ipion Rush",   tpPlayer, 'n00K', -1664,  -744 ) //mid
    set Tp[ 3 ] = tradepoint.create( "Shalhaven",    tpPlayer, 'n00L',  5120,  -256 ) //Right
   
    set Tp[ 4 ] = tradepoint.create( "Port Haddocs", tpPlayer, 'n00K', -5056, -2496 ) // Left Down
    set Tp[ 5 ] = tradepoint.create( "Port Serral",  tpPlayer, 'n00K',  2112, -2752 ) // Right Down
       

endfunction

endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope WeaponsInit initializer INIT

//===========================================================================
private function INIT takes nothing returns nothing
    local weapontypearray BB1 = weapontypearray.create()
    local weapontypearray BB2 = weapontypearray.create()
    local weapontypearray BB3 = weapontypearray.create()
   
    local weapontypearray BS0 = weapontypearray.create()
    local weapontypearray BS1 = weapontypearray.create()
    local weapontypearray BS2 = weapontypearray.create()
    local weapontypearray BS3 = weapontypearray.create()
   
    local weapontypearray NG1 = weapontypearray.create()
    local weapontypearray NG2 = weapontypearray.create()
    local weapontypearray NG3 = weapontypearray.create()
   
    local weapontypearray CR1 = weapontypearray.create()
    local weapontypearray CR2 = weapontypearray.create()
    local weapontypearray CR3 = weapontypearray.create()
   
    local weapontypearray SY1 = weapontypearray.create()
    local weapontypearray SY2 = weapontypearray.create()
    local weapontypearray SY3 = weapontypearray.create()
   
    local weapontypearray SU1 = weapontypearray.create()
    local weapontypearray SU2 = weapontypearray.create()
    local weapontypearray SU3 = weapontypearray.create()
   
    local weapontypearray XO1 = weapontypearray.create()
    local weapontypearray XO2 = weapontypearray.create()
    local weapontypearray XO3 = weapontypearray.create()
   
    local weapontypearray CI1 = weapontypearray.create()
    local weapontypearray CI2 = weapontypearray.create()
    local weapontypearray CI3 = weapontypearray.create()
   
    local weapontypearray EL1 = weapontypearray.create()
    local weapontypearray EL2 = weapontypearray.create()
    local weapontypearray EL3 = weapontypearray.create()

//-----------------------------------------------------------    
    set BB1[ 0 ] = 'n00M'
    set BB1[ 1 ] = 'n00M'
   
    set BB2[ 0 ] = 'n00N'    

    set BB3[ 0 ] = 'n00Y'
//-----------------------------------------------------------        
    set BS0[ 0 ] = 'n00T'    
//-----------------------------------------------------------        
    set BS1[ 0 ] = 'n00O'
    set BS1[ 1 ] = 'n00Q'
   
    set BS2[ 0 ] = 'n00P'
    set BS2[ 1 ] = 'n00S'
       
    set BS3[ 0 ] = 'n00P'
    set BS3[ 1 ] = 'n00S'
    set BS3[ 2 ] = 'n00X'    
//-----------------------------------------------------------    
    set NG1[ 0 ] = 'n00M'
   
    set NG2[ 0 ] = 'n00M'
    set NG2[ 1 ] = 'n00M'
   
    set NG3[ 0 ] = 'n00M'
    set NG3[ 1 ] = 'n00M'
    set NG3[ 3 ] = 'n00M'
//-----------------------------------------------------------
    set CR1[ 0 ] = 'n010'
   
    set CR2[ 0 ] = 'n00R'
   
    set CR3[ 0 ] = 'n00Z'      
    set CR3[ 1 ] = 'n00Z'      
    set CR3[ 2 ] = 'n00Z'        
//-----------------------------------------------------------
    set EL1[ 0 ] = 'n011'
   
    set EL2[ 0 ] = 'n013'
   
    set EL3[ 0 ] = 'n012'
//-----------------------------------------------------------
    set SY1[ 0 ] = 'n014'
   
    set SY2[ 0 ] = 'n015'
   
    set SY3[ 0 ] = 'n016'
//-----------------------------------------------------------

//-----------------------------------------------------------
    call onboardweapon.create( 'H005', BS0 ) // BS0

    call onboardweapon.create( 'H006', BS1 ) // BS1
    call onboardweapon.create( 'H00E', BS2 ) // BS2
    call onboardweapon.create( 'H00P', BS3 ) // BS3
   
    call onboardweapon.create( 'H00D', BB1 ) // BB1
    call onboardweapon.create( 'H00R', BB2 ) // BB2
    call onboardweapon.create( 'H00T', BB3 ) // BB3
   
    call onboardweapon.create( 'H00Q', CI1 ) // CI1
    call onboardweapon.create( 'H00J', CI2 ) // CI2
    call onboardweapon.create( 'H00N', CI3 ) // CI3
   
    call onboardweapon.create( 'H00C', CR1 ) // CR1
    call onboardweapon.create( 'H00F', CR2 ) // CR2
    call onboardweapon.create( 'H00W', CR3 ) // CR3
   
    call onboardweapon.create( 'H009', EL1 ) // EL1
    call onboardweapon.create( 'H00G', EL2 ) // EL2
    call onboardweapon.create( 'H00Y', EL3 ) // EL3
   
    call onboardweapon.create( 'H00B', NG1 ) // NG1
    call onboardweapon.create( 'H00H', NG2 ) // NG2
    call onboardweapon.create( 'H00S', NG3 ) // NG3
   
    call onboardweapon.create( 'H008', XO1 ) // XO1
    call onboardweapon.create( 'H00V', XO2 ) // XO2
    call onboardweapon.create( 'H00I', XO3 ) // XO3
   
    call onboardweapon.create( 'H004', SY1 ) // SY1
    call onboardweapon.create( 'H00K', SY2 ) // SY2
    call onboardweapon.create( 'H00U', SY3 ) // SY3
   
    call onboardweapon.create( 'H007', SU1 ) // SU1
    call onboardweapon.create( 'H00L', SU2 ) // SU2
    call onboardweapon.create( 'H00M', SU3 ) // SU3
endfunction

endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope UpgradesInit initializer INIT

globals
    real array Profit
endglobals

private function INIT_REALLY takes nothing returns nothing
    // SAILS
    call SetItemUpgrade( 'I00F', 'I00E',  150 ) // Level 0     -> Level 1
    call SetItemUpgrade( 'I00E', 'I00G',  600 ) // Level 1     -> Level 2
    call SetItemUpgrade( 'I00G', 'I00P', 1050 ) // Level 2     -> Level 3
    call SetItemUpgrade( 'I00P', 'I00Q', 1700 ) // Level 3     -> Level 4
    set UpgradeType[ 'I00F' ] = REQ_SAILS
    set UpgradeType[ 'I00E' ] = REQ_SAILS
    set UpgradeType[ 'I00G' ] = REQ_SAILS
    set UpgradeType[ 'I00P' ] = REQ_SAILS
    set UpgradeType[ 'I00Q' ] = REQ_SAILS
   
    // PROFIT    
    call SetItemUpgrade( 'I019', 'I01A',  600 ) // Level 0     -> Level 1
    call SetItemUpgrade( 'I01A', 'I01B',  900 ) // Level 1     -> Level 2
    call SetItemUpgrade( 'I01B', 'I01C', 1200 ) // Level 2     -> Level 3
    call SetItemUpgrade( 'I01C', 'I01D', 1500 ) // Level 3     -> Level 4
    set UpgradeType[ 'I019' ] = REQ_PROFIT
    set UpgradeType[ 'I01A' ] = REQ_PROFIT
    set UpgradeType[ 'I01B' ] = REQ_PROFIT
    set UpgradeType[ 'I01C' ] = REQ_PROFIT
    set UpgradeType[ 'I01D' ] = REQ_PROFIT
   
    set Profit[ 0 ] = 0.8
    set Profit[ 1 ] = 0.82
    set Profit[ 2 ] = 0.84
    set Profit[ 3 ] = 0.87
    set Profit[ 4 ] = 0.9
   
   
    // POW
    call SetItemUpgrade( 'I00R', 'I00S',  900 ) // Level 0     -> Level 1
    call SetItemUpgrade( 'I00S', 'I00T', 1300 ) // Level 1     -> Level 2
    call SetItemUpgrade( 'I00T', 'I00U', 1700 ) // Level 2     -> Level 3
    call SetItemUpgrade( 'I00U', 'I00W', 2100 ) // Level 3     -> Level 4
    call SetItemUpgrade( 'I00W', 'I00X', 2500 ) // Level 4     -> Level 5
    call SetItemUpgrade( 'I00X', 'I00V', 2900 ) // Level 5     -> Level 6
    call SetItemUpgrade( 'I00V', 'I00Y', 3500 ) // Level 6     -> Level 7
    set UpgradeType[ 'I00R' ] = REQ_POW
    set UpgradeType[ 'I00S' ] = REQ_POW
    set UpgradeType[ 'I00T' ] = REQ_POW
    set UpgradeType[ 'I00U' ] = REQ_POW
    set UpgradeType[ 'I00V' ] = REQ_POW
    set UpgradeType[ 'I00W' ] = REQ_POW
    set UpgradeType[ 'I00X' ] = REQ_POW
    set UpgradeType[ 'I00Y' ] = REQ_POW
   
    // CD
    call SetItemUpgrade( 'I00Z', 'I010',  600 ) // Level 0     -> Level 1
    call SetItemUpgrade( 'I010', 'I013',  900 ) // Level 1     -> Level 2
    call SetItemUpgrade( 'I013', 'I012', 1200 ) // Level 2     -> Level 3
    call SetItemUpgrade( 'I012', 'I011', 1500 ) // Level 3     -> Level 4
    set UpgradeType[ 'I00Z' ] = REQ_CD
    set UpgradeType[ 'I010' ] = REQ_CD
    set UpgradeType[ 'I011' ] = REQ_CD
    set UpgradeType[ 'I012' ] = REQ_CD
    set UpgradeType[ 'I013' ] = REQ_CD
   
   
    // CARGO
    call SetItemUpgrade( 'I01E', 'I01F',  900 ) // Level 0     -> Level 1
    call SetItemUpgrade( 'I01F', 'I01G', 1300 ) // Level 1     -> Level 2
    call SetItemUpgrade( 'I01G', 'I01H', 1700 ) // Level 2     -> Level 3
    call SetItemUpgrade( 'I01H', 'I01I', 2100 ) // Level 3     -> Level 4
    call SetItemUpgrade( 'I01I', 'I01J', 2500 ) // Level 4     -> Level 5
    call SetItemUpgrade( 'I01J', 'I01K', 2900 ) // Level 5     -> Level 6
    call SetItemUpgrade( 'I01K', 'I01L', 3500 ) // Level 6     -> Level 7
    set UpgradeType[ 'I01E' ] = REQ_CARGO
    set UpgradeType[ 'I01F' ] = REQ_CARGO
    set UpgradeType[ 'I01G' ] = REQ_CARGO
    set UpgradeType[ 'I01H' ] = REQ_CARGO
    set UpgradeType[ 'I01I' ] = REQ_CARGO
    set UpgradeType[ 'I01J' ] = REQ_CARGO
    set UpgradeType[ 'I01K' ] = REQ_CARGO
    set UpgradeType[ 'I01L' ] = REQ_CARGO
   
    //HULL
    call SetItemUpgrade( 'I014', 'I015',  200 ) // Level 0     -> Level 1
    call SetItemUpgrade( 'I015', 'I016', 1000 ) // Level 1     -> Level 2
    call SetItemUpgrade( 'I016', 'I017', 2200 ) // Level 2     -> Level 3
    call SetItemUpgrade( 'I017', 'I018', 3200 ) // Level 3     -> Level 4
    set UpgradeType[ 'I014' ] = REQ_HULL
    set UpgradeType[ 'I015' ] = REQ_HULL
    set UpgradeType[ 'I016' ] = REQ_HULL
    set UpgradeType[ 'I017' ] = REQ_HULL
    set UpgradeType[ 'I018' ] = REQ_HULL
   
    //THULL
   
    call SetItemUpgrade( 'I01Q', 'I01M',  200 ) // Level 0     -> Level 1
    call SetItemUpgrade( 'I01M', 'I01N', 1000 ) // Level 1     -> Level 2
    call SetItemUpgrade( 'I01N', 'I01O', 2200 ) // Level 2     -> Level 3
    call SetItemUpgrade( 'I01O', 'I01P', 3200 ) // Level 3     -> Level 4
    set UpgradeType[ 'I01Q' ] = REQ_HULL
    set UpgradeType[ 'I01M' ] = REQ_HULL
    set UpgradeType[ 'I01N' ] = REQ_HULL
    set UpgradeType[ 'I01O' ] = REQ_HULL
    set UpgradeType[ 'I01P' ] = REQ_HULL
endfunction

private function INIT takes nothing returns nothing
    call ExecuteFunc( SCOPE_PRIVATE + "INIT_REALLY" )
endfunction
endscope
//TESH.scrollpos=209
//TESH.alwaysfold=0
//// VER 0A
//TODO  Set Unit Values

//! runtextmacro CreateRect( "NorthBase", "-2464", "4448", "-1696", "5088" )
//! runtextmacro CreateRect( "SouthBase", "-2464", "-5088", "-1696", "-4448" )


//! runtextmacro CreateRect( "SouthHarborLeft" , "-3392", "-4736", "-3008", "-4480" )
//! runtextmacro CreateRect( "SouthHarborRight", "-1088", "-4736",  "-704", "-4480" )

//! runtextmacro CreateRect( "NorthHarborLeft" , "-3392", "4480", "-3008", "4736" )
//! runtextmacro CreateRect( "NorthHarborRight", "-1088", "4480",  "-704", "4736" )

//! runtextmacro AddUnitValue( "Cost", "integer", "0" )
//! runtextmacro AddUnitValue( "MaxCargo", "integer", "0" )
//! runtextmacro AddItemValue( "Cost", "integer", "0" )
//! runtextmacro AddItemValue( "Weight", "integer", "0" )


library AntarcticaMapInit initializer MapInit needs BountySystem, Utilities, TradeSystem, TaxSys, IMG, TeamSys

globals
                     rect          SouthHarborLeft
                     rect          SouthHarborRight
                     rect          NorthHarborLeft
                     rect          NorthHarborRight
                     rect          SouthBase
                     rect          NorthBase

                     unit    array Hero

                     integer array Kills
                     integer array Deaths
                     
                     boolean       GameRuns   = true
                     boolean array ShowMessages
            constant trigger       HarborEnd  = CreateTrigger()
            constant trigger       AttackNorthBase = CreateTrigger()
            constant trigger       AttackSouthBase = CreateTrigger()
                     
            constant integer       DamageUpgrade = 'R001'
            constant integer       LifeUpgrade   = 'R002'
                     
            constant player        NorthPlayer = Player( 1 )
            constant player        SouthPlayer = Player( 0 )
                     
                     
            constant integer       PirateShip  = 'h011'
            constant integer       PirFlagShip = 'h012'
           
            constant integer       AssaultShip = 'h001'
            constant integer       Frigate     = 'h002'
            constant integer       AeroCruiser = 'h003'
            constant integer       Bombarder   = 'h000'
            constant integer       StartHero   = 'H005'
           
            constant integer       MaxAIPlayerId    = 1
            constant integer       MaxTeam1PlayerId = 6
            constant integer       MaxTeam2PlayerId = 11

            constant integer       AssaultMinBounty =  24
            constant integer       AssaultMaxBounty =  30
                     
            constant integer       FrigateMinBounty =  21
            constant integer       FrigateMaxBounty =  26
                     
            constant integer       CruiserMinBounty =  41
            constant integer       CruiserMaxBounty =  50
                     
            constant integer       BombardMinBounty =  90
            constant integer       BombardMaxBounty = 100
                     
            constant integer       PirateMinBounty  =  18
            constant integer       PirateMaxBounty  =  23
           
            constant integer       PirFlagMinBounty =  53
            constant integer       PirFlagMaxBounty =  58
           
           
                     unit          SouthContor
                     unit          NorthContor      
           
                     integer array NumTeamPlayers
                     integer       TotalPlayers = 0
                     integer       LeaverGold = 0
                     
                     string  array TeamName
                     string  array TeamColor
                     
            constant integer       SouthTeamId      = 0
            constant integer       NorthTeamId      = 1
                     
                     // DebugMode
                     boolean       Debug            = false
               
endglobals


private function Disclaim takes string disclaimer returns nothing
    call DisplayTimedTextToPlayer( LOCAL_PLAYER, 0.5, 0.5, 30, disclaimer )
endfunction

private function Drop takes nothing returns nothing
    local player trigPlayer = GetTriggerPlayer()
    if GetPlayerFeedback( trigPlayer ) then
        call PauseUnit( Hero[ GetPlayerId( trigPlayer ) ], false )
    else
        call WinGame( trigPlayer, false, "Bye bye!" )
        call DisplayText( LOCAL_PLAYER, PlayerName[ GetPlayerId( trigPlayer ) ] + LIGHTGREY + "has chosen not to play the Prealpha." )
    endif
endfunction

function ExitCode takes integer winner returns nothing                
    local integer       playerId = 0
    local integer       looser   = ModuloInteger( winner + 1, 2 )        
    local string  array winMSG                                            
    local player  localPlayer    = GetLocalPlayer ( )
    local integer teamId
    set winMSG[ winner ] = PositiveTag + "Your glorious empire has established peace!"
    set winMSG[ looser ] = NegativeTag + TeamName[ looser ] + " has fallen into ruins..."
   
    set GameRuns = false
    if IsPlayerAlly( localPlayer, Players[ winner ] ) then
        call DisplayTimedTextToPlayer( localPlayer, 0, 0, 20, NeutralTag  + "For " + NegativeTag + "PEACE!" + NeutralTag + " For " + NegativeTag + "FREEDOM!" + NeutralTag + " For " + NegativeTag + "LIFE!" + NeutralTag + " Down with the Empire!" )      
        call DisplayTimedTextToPlayer( localPlayer, 0, 0, 20, NeutralTag  + "The enemy has signed the total capitulation!" )
    else
        call DisplayTimedTextToPlayer( localPlayer, 0, 0, 20, NeutralTag  + "For " + NegativeTag + "PEACE!" + NeutralTag + " For " + NegativeTag + "FREEDOM!" + NeutralTag + " For " + NegativeTag + "LIFE!" + NeutralTag + " Down with the Empire!" )
        call DisplayTimedTextToPlayer( localPlayer, 0, 0, 20, NegativeTag + "You need to accept your defeat and sign the total capitulation..." )
    endif
   
    call TriggerSleepAction(    5 )
    call PauseAllUnitsBJ   ( true )
    call TriggerSleepAction(   20 )
    loop
        exitwhen playerId > NUMPLAYERS
        if PlayerActive[ playerId ] then
            set teamId = Team[ playerId ].id
            call WinGame( Players[ playerId ], teamId == winner, winMSG[ teamId ] )
        endif            
        set playerId = playerId + 1
    endloop

endfunction

function HarborEnd_Actions  takes nothing returns nothing
    local player  looser      = GetOwningPlayer( GetTriggerUnit() )
    local integer looserId    = GetPlayerId    ( looser )
    local integer winnerId    = looserId + 1 - ( ( looserId + 1 ) / 2 ) * 2
    local player  localPlayer = GetLocalPlayer ( )
    if IsPlayerAlly( localPlayer, looser ) then
        call DisplayTimedTextToPlayer( localPlayer, 0, 0, 20, NegativeTag + "Your Kontor has been destroyed." + NeutralTag + " The surviving population no longer supports the war and started a revolution against you! " )
    else
        call DisplayTimedTextToPlayer( localPlayer, 0, 0, 20, PositiveTag + "You have succesfully destroyed the hostile Kontor!" + NeutralTag + " Our spies have observed that the surviving population started a revolt against " + TeamName[ looserId ] )
    endif
    call ExitCode( winnerId )
endfunction
   
function AttackNorthBase_Actions takes nothing returns nothing
    local unit trigUnit = GetTriggerUnit()
    local player trigPlayer = GetOwningPlayer( trigUnit )
    local integer playerId = GetPlayerId( trigPlayer )
    if not IsUnitType( trigUnit, UNIT_TYPE_HERO ) and IsPlayerEnemy( trigPlayer, Players[ 1 ]) then
        call IssuePointOrder( trigUnit, "attack", NorthBaseCenterX, NorthBaseCenterY )
    endif
    set trigUnit = null
endfunction
   
function AttackSouthBase_Actions takes nothing returns nothing
    local unit trigUnit = GetTriggerUnit()
    local player trigPlayer = GetOwningPlayer( trigUnit )
    local integer playerId = GetPlayerId( trigPlayer )
    if not IsUnitType( trigUnit, UNIT_TYPE_HERO ) and IsPlayerEnemy( trigPlayer, Players[ 0 ]) then
        call IssuePointOrder( trigUnit, "attack", SouthBaseCenterX, SouthBaseCenterY )
    endif
    set trigUnit = null
endfunction
   
private function DoPlayersWantToPlayAlpha takes nothing returns nothing
    debug       local integer i = 0
    debug       loop
    debug           exitwhen i > MAX_USER_SLOT
    debug           call PauseUnit( Hero[ i ], true )
    debug           call AskPlayerFeedback( Players[ i ], "Play prealpha?", function Drop )
    debug           set i = i + 1
    debug       endloop
    call DestroyTimer( GetExpiredTimer() )
endfunction

private function MapInitExtended takes nothing returns nothing
    local integer i = MaxAIPlayerId + 1
    local integer j = 0
   
       
    call SetUnitTypeBounty( AssaultShip, AssaultMinBounty, AssaultMaxBounty )
    call SetUnitTypeBounty( Frigate,     FrigateMinBounty, FrigateMaxBounty )
    call SetUnitTypeBounty( AeroCruiser, CruiserMinBounty, CruiserMaxBounty )
    call SetUnitTypeBounty( Bombarder,   BombardMinBounty, BombardMaxBounty )
       
    call SetUnitTypeBounty( PirateShip,  PirateMinBounty, PirateMaxBounty )
    call SetUnitTypeBounty( PirFlagShip, PirFlagMinBounty, PirFlagMaxBounty )
   
    call TriggerRegisterUnitEvent( HarborEnd, SouthContor, EVENT_UNIT_DEATH )
    call TriggerRegisterUnitEvent( HarborEnd, NorthContor, EVENT_UNIT_DEATH )
    call TriggerAddAction        ( HarborEnd, function HarborEnd_Actions )
   
    call SetPlayerAbilityAvailable( Players[ 0 ], 'A00L', false )
    call SetPlayerAbilityAvailable( Players[ 1 ], 'A00L', false )
   
    call TriggerRegisterEnterRectSimple( AttackNorthBase, NorthHarborRight )
    call TriggerRegisterEnterRectSimple( AttackNorthBase, NorthHarborLeft )
    call TriggerAddAction              ( AttackNorthBase, function AttackNorthBase_Actions )
    call TriggerRegisterEnterRectSimple( AttackSouthBase, SouthHarborRight )
    call TriggerRegisterEnterRectSimple( AttackSouthBase, SouthHarborLeft )
    call TriggerAddAction              ( AttackSouthBase, function AttackSouthBase_Actions )
   
    loop
        exitwhen i > MAX_USER_SLOT
        call Transfer( 600, Team[ i ].id, i, TRANSFERTYPE_PLAYER_PLAYER, "Empire" )
        set TaxSys_LastMoney[ i ] = 600
        set ShowMessages[ i ] = true
        if PlayerActive[ i ] then
            set TotalPlayers = TotalPlayers + 1
            call SetPlayerBank        ( Players[ i ], GetPlayerEmpireSJ( Players[ i ] ) )
            call SetPlayerTaxCollector( Players[ i ], GetPlayerEmpireSJ( Players[ i ] ) )
           
            set  Hero[ i ] = CreateUnit( Players[ i ] , StartHero , StartLocX[ i ] , StartLocY[ i ] , 90 + Team[ i ].id * 180)
           
            if Players[ i ] == LOCAL_PLAYER then
                call ClearSelection(     )
                call SelectUnit    ( Hero[ i ], true )
            endif
            call UnitAddItemById( Hero[ i ], 'I00R' )
            call UnitAddItemById( Hero[ i ], 'I00F' )
            call UnitAddItemById( Hero[ i ], 'I00Z' )
            call UnitAddItemById( Hero[ i ], 'I014' )
            call CreateFogModifierRect( Players[ i ], FOG_OF_WAR_VISIBLE, gg_rct_Give_Vision, true, true )
        else
            call TeamRemovePlayerSJ( GetPlayerTeamSJ( Players[ i ] ), Players[ i ] )
        endif
       
        set i = i + 1
    endloop
   
    call Disclaim( RED + "Battleships Antarctica is NOT a normal battleships map! Don't apply Battleships knowledge here.\n  If you play this for the first time, use " + LIGHTGREY + "-help" + RED + ", " + LIGHTGREY + "-start tut" + RED + " or " + LIGHTGREY + "-tutorial" + RED + "."  )
   
    call FogEnable( false )
    call FogEnable( true )
    debug   call Disclaim( RED + "This is a prealpha version! Not all features have been implemented yet!" )
        if TotalPlayers > 1 then
    debug       call TimerStart( GetExpiredTimer(), 5.0, false, function DoPlayersWantToPlayAlpha )
        else
            call AdminRights_SinglePlayer.execute()
        endif
    call InitRevivalSystem.execute()
endfunction

function MapInit takes nothing returns nothing

    local integer playerId = 0
    local integer teamId   = 0
    local player  localPlayer = LOCAL_PLAYER
    local fogmodifier array fogMod
   
    set TeamColor  [ SouthTeamId ] = "|c00ff0303"
    set TeamName   [ SouthTeamId ] = TeamColor[ SouthTeamId ] + "The Cargian Empire|r"
    set TeamColor  [ NorthTeamId ] = "|c000042ff"
    set TeamName   [ NorthTeamId ] = TeamColor[ NorthTeamId ] + "The Strorvan Empire|r"
   
    call SetPlayerNameSJ( PiratePlayer, "Pirates" )
debug   set Debug = true
 
    loop
        exitwhen playerId > MaxAIPlayerId
        call SetPlayerState( Players[ playerId ], PLAYER_STATE_RESOURCE_GOLD, 22500 )
        call SetPlayerState( Players[ playerId ], PLAYER_STATE_GOLD_GATHERED, 22500 )
       
        call SetPlayerTeamSJ( Players[ playerId ], playerId )
       
        set playerId = playerId + 1
       
       
        set Kills [ playerId ] = 0
        set Deaths[ playerId ] = 0
        set fogMod[ playerId ] = CreateFogModifierRect( Players[ playerId ], FOG_OF_WAR_VISIBLE, bj_mapInitialPlayableArea, true, false )
       
    endloop
 
    loop
        exitwhen playerId > MaxTeam1PlayerId
        set Kills [ playerId ] = 0
        set Deaths[ playerId ] = 0
        call SetPlayerTeamSJ( Players[ playerId ], SouthTeamId )
        set playerId = playerId + 1
    endloop  

    loop
        exitwhen playerId > MaxTeam2PlayerId
        set Kills [ playerId ] = 0
        set Deaths[ playerId ] = 0
        call SetPlayerTeamSJ( Players[ playerId ], NorthTeamId )
        set playerId = playerId + 1
    endloop
           
   
    call SetMaxStack( 'I00N', 45 )
    call SetMaxStack( 'I00M', 45 )
    call SetMaxStack( 'I00O', 45 )
    call SetMaxStack( 'I00L', 45 )

    set  SouthContor = CreateUnit( Players[ 0 ], 'n000', -2048, -5120, 270 )
    set  NorthContor = CreateUnit( Players[ 1 ], 'n000', -2048,  5120, 270 )
   
    call SetSkyModel( "Environment\\Sky\\Sky\\SkyLight.mdl" )
    call TimerStart( CreateTimer(), 0.04, false, function MapInitExtended )
   
    call CreateImageEx( "CannonSkin.blp", 512, -2112, -3904, 0, true )
    call CreateImageEx( "CannonSkin.blp", 512, -1984,  4672, 0, true )
           
    call SetPlayerState( PiratePlayer, PLAYER_STATE_GIVES_BOUNTY, 0 )
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
//! runtextmacro Attach( "NextPirLoc", "region", "pir_loc", "0" )

//! runtextmacro CreateRect( "NorthPirateLoc1", " 1536", " 2016",  "2016", "2464" )
//! runtextmacro CreateRect( "NorthPirateLoc2", "  288", "  160",  " 768", " 608" )
//! runtextmacro CreateRect( "NorthPirateLoc3", "-1024", "  608",  "-544", "1056" )

//! runtextmacro CreateRect( "SouthPirateLoc1", " 2016", "-3168",  "2496", "-2720" )
//! runtextmacro CreateRect( "SouthPirateLoc2", "  160", " -832",  " 640", " -384" )
//! runtextmacro CreateRect( "SouthPirateLoc3", "-1056", "-1664",  "-576", "-1216" )

//! runtextmacro CreateRect( "PirateBase",      " 1376", "  -32",  "2016", "  736" )

library PiratesMovementControl

globals
    rect SouthPirateLoc1
    rect SouthPirateLoc2
    rect SouthPirateLoc3
   
    rect NorthPirateLoc1
    rect NorthPirateLoc2
    rect NorthPirateLoc3
   
    rect PirateBase
endglobals

function IsEnterUnitPirate takes nothing returns boolean
    return GetOwningPlayer( GetFilterUnit() ) == PiratePlayer
endfunction

function Rect2Region takes rect toconvert returns region
    local region result = CreateRegion()
    call RegionAddRect( result, toconvert )
   
    set ReturnHandle = result
    set toconvert = null
    set result = null
    return ReturnHandle
endfunction

private function Controller_Actions takes nothing returns nothing
    local pir_loc nextLoc = NextPirLoc[ GetTriggeringRegion() ]
    local unit trigUnit = GetTriggerUnit()
    if nextLoc == 0 then
        call IssuePointOrder( trigUnit, "attack", nextLoc.firstLoc.x, nextLoc.firstLoc.y )
    else
        call IssuePointOrder( trigUnit, "attack", nextLoc.x, nextLoc.y )
    endif
    set trigUnit = null
endfunction

struct pir_loc
    real x
    real y
    region self
    pir_loc firstLoc
    static constant trigger controller = CreateTrigger()
    static boolexpr ispirate
   
    static method create takes pir_loc lastloc, rect self returns pir_loc
        local pir_loc this = .allocate()
        set .x = GetRectCenterX( self )
        set .y = GetRectCenterY( self )
        set .self = Rect2Region( self )
        if lastloc == 0 then
            set .firstLoc = this
        else
            set .firstLoc = lastloc.firstLoc
            set NextPirLoc[ lastloc.self ] = this
        endif
        call TriggerRegisterEnterRegion( .controller, .self, .ispirate )
        set self = null
        return this
    endmethod
   
    private static method onInit takes nothing returns nothing
        call TriggerAddAction( .controller, function Controller_Actions )
        set .ispirate = Filter( function IsEnterUnitPirate )
    endmethod
endstruct
endlibrary

scope InitPirMovement initializer INIT
private function INIT_REALLY takes nothing returns nothing
    local pir_loc lastLocS = 0
    local pir_loc lastLocN = 0
   
    set lastLocS = pir_loc.create( lastLocS, SouthPirateLoc1 )
    set lastLocS = pir_loc.create( lastLocS, SouthPirateLoc2 )
    set lastLocS = pir_loc.create( lastLocS, SouthPirateLoc3 )
   
    set lastLocN = pir_loc.create( lastLocN, NorthPirateLoc1 )
    set lastLocN = pir_loc.create( lastLocN, NorthPirateLoc2 )
    set lastLocN = pir_loc.create( lastLocN, NorthPirateLoc3 )
endfunction

private function INIT takes nothing returns nothing
    call ExecuteFunc( SCOPE_PRIVATE + "INIT_REALLY" )
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope TradeUpgradesInit initializer INIT
globals
    constant integer SHIP_TYPE_NORMAL = 0
    constant integer SHIP_TYPE_TRADER = 1
    constant integer SHIP_TYPE_TARGET = 2
endglobals
//===========================================================================
private function INIT takes nothing returns nothing
    call SetUnitTypeShipId( 'H00A', SHIP_TYPE_TRADER )
    call SetUnitTypeShipId( 'H00O', SHIP_TYPE_TRADER )
    call SetUnitTypeShipId( 'H00X', SHIP_TYPE_TRADER )
   
    //call SetUnitTypeShipId( 'H00C', SHIP_TYPE_TARGET )
    call SetUnitTypeShipId( 'H00F', SHIP_TYPE_TARGET )
    call SetUnitTypeShipId( 'H00W', SHIP_TYPE_TARGET )
   
endfunction
endscope

 
//TESH.scrollpos=0
//TESH.alwaysfold=0
//! runtextmacro AddUnitValue( "ShipLevel", "integer", "0" )
scope InitLevels initializer INIT
private function INIT_REALLY takes nothing returns nothing
    call SetUnitTypeShipLevel( 'H005', 0 ) // BS0

    call SetUnitTypeShipLevel( 'H006', 1 ) // BS1
    call SetUnitTypeShipLevel( 'H00E', 2 ) // BS2
    call SetUnitTypeShipLevel( 'H00P', 3 ) // BS3
   
    call SetUnitTypeShipLevel( 'H00D', 1 ) // BB1
    call SetUnitTypeShipLevel( 'H00R', 2 ) // BB2
    call SetUnitTypeShipLevel( 'H00T', 3 ) // BB3
   
    call SetUnitTypeShipLevel( 'H00J', 1 ) // CI1
    call SetUnitTypeShipLevel( 'H00N', 2 ) // CI2
    call SetUnitTypeShipLevel( 'H00Q', 3 ) // CI3
   
    call SetUnitTypeShipLevel( 'H00A', 1 ) // TT1
    call SetUnitTypeShipLevel( 'H00O', 2 ) // TT2
    call SetUnitTypeShipLevel( 'H00X', 3 ) // TT3
   
    call SetUnitTypeShipLevel( 'H00C', 1 ) // CR1
    call SetUnitTypeShipLevel( 'H00F', 2 ) // CR2
    call SetUnitTypeShipLevel( 'H00W', 3 ) // CR3
   
    call SetUnitTypeShipLevel( 'H009', 1 ) // EL1
    call SetUnitTypeShipLevel( 'H00G', 2 ) // EL2
    call SetUnitTypeShipLevel( 'H00Y', 3 ) // EL3
   
    call SetUnitTypeShipLevel( 'H00B', 1 ) // NG1
    call SetUnitTypeShipLevel( 'H00H', 2 ) // NG2
    call SetUnitTypeShipLevel( 'H00S', 3 ) // NG3
   
    call SetUnitTypeShipLevel( 'H008', 1 ) // XO1
    call SetUnitTypeShipLevel( 'H00V', 2 ) // XO2
    call SetUnitTypeShipLevel( 'H00I', 3 ) // XO3
   
    call SetUnitTypeShipLevel( 'H004', 1 ) // SY1
    call SetUnitTypeShipLevel( 'H00K', 2 ) // SY2
    call SetUnitTypeShipLevel( 'H00U', 3 ) // SY3
   
    call SetUnitTypeShipLevel( 'H007', 1 ) // SU1
    call SetUnitTypeShipLevel( 'H00L', 2 ) // SU2
    call SetUnitTypeShipLevel( 'H00M', 3 ) // SU3
   
endfunction

private function INIT takes nothing returns nothing
    call ExecuteFunc( SCOPE_PRIVATE + "INIT_REALLY" )
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope InitCargo initializer INIT
private function INIT_REALLY takes nothing returns nothing
    call SetUnitTypeMaxCargo( 'H005', 4 ) // BS0

    call SetUnitTypeMaxCargo( 'H006',  6 ) // BS1
    call SetUnitTypeMaxCargo( 'H00E', 11 ) // BS2
    call SetUnitTypeMaxCargo( 'H00P', 16 ) // BS3
   
    call SetUnitTypeMaxCargo( 'H00D',  6 ) // BB1
    call SetUnitTypeMaxCargo( 'H00R', 11 ) // BB2
    call SetUnitTypeMaxCargo( 'H00T', 16 ) // BB3
   
    call SetUnitTypeMaxCargo( 'H00J',  5 ) // CI1
    call SetUnitTypeMaxCargo( 'H00N', 10 ) // CI2
    call SetUnitTypeMaxCargo( 'H00Q', 15 ) // CI3
   
    call SetUnitTypeMaxCargo( 'H00A',  8 ) // TT1
    call SetUnitTypeMaxCargo( 'H00O', 14 ) // TT2
    call SetUnitTypeMaxCargo( 'H00X', 20 ) // TT3
   
    call SetUnitTypeMaxCargo( 'H00C',  5 ) // CR1
    call SetUnitTypeMaxCargo( 'H00F',  9 ) // CR2
    call SetUnitTypeMaxCargo( 'H00W', 13 ) // CR3
   
    call SetUnitTypeMaxCargo( 'H009',  5 ) // EL1
    call SetUnitTypeMaxCargo( 'H00G', 10 ) // EL2
    call SetUnitTypeMaxCargo( 'H00Y', 15 ) // EL3
   
    call SetUnitTypeMaxCargo( 'H00B',  6 ) // NG1
    call SetUnitTypeMaxCargo( 'H00H', 11 ) // NG2
    call SetUnitTypeMaxCargo( 'H00S', 15 ) // NG3
   
    call SetUnitTypeMaxCargo( 'H008',  5 ) // XO1
    call SetUnitTypeMaxCargo( 'H00V',  9 ) // XO2
    call SetUnitTypeMaxCargo( 'H00I', 12 ) // XO3
   
    call SetUnitTypeMaxCargo( 'H004',  5 ) // SY1
    call SetUnitTypeMaxCargo( 'H00K', 10 ) // SY2
    call SetUnitTypeMaxCargo( 'H00U', 15 ) // SY3
   
    call SetUnitTypeMaxCargo( 'H007',  6 ) // SU1
    call SetUnitTypeMaxCargo( 'H00L', 11 ) // SU2
    call SetUnitTypeMaxCargo( 'H00M', 16 ) // SU3
   
endfunction

private function INIT takes nothing returns nothing
    call ExecuteFunc( SCOPE_PRIVATE + "INIT_REALLY" )
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope ShipReq initializer INIT
private function INIT_REALLY takes nothing returns nothing
    call SetUnitRequirements( 'H005', 0, 0, 0, 0 ) // BS0

    call SetUnitRequirements( 'H006', 1, 0, 0, 1 ) // BS1
    call SetUnitRequirements( 'H00E', 2, 1, 0, 1 ) // BS2
    call SetUnitRequirements( 'H00P', 3, 1, 0, 2 ) // BS3
   
    call SetUnitRequirements( 'H00D', 0, 0, 0, 1 ) // BB1
    call SetUnitRequirements( 'H00R', 0, 0, 0, 2 ) // BB2
    call SetUnitRequirements( 'H00T', 0, 0, 0, 3 ) // BB3
   
    call SetUnitRequirements( 'H00J', 0, 0, 1, 1 ) // CI1
    call SetUnitRequirements( 'H00N', 0, 0, 1, 2 ) // CI2
    call SetUnitRequirements( 'H00Q', 1, 0, 1, 3 ) // CI3
   
    call SetUnitRequirements( 'H00A', 0, 0, 1, 0 ) // TT1
    call SetUnitRequirements( 'H00O', 0, 2, 1, 0 ) // TT2
    call SetUnitRequirements( 'H00X', 0, 2, 1, 2 ) // TT3
   
    call SetUnitRequirements( 'H00C', 0, 1, 1, 0 ) // CR1
    call SetUnitRequirements( 'H00F', 0, 1, 2, 1 ) // CR2
    call SetUnitRequirements( 'H00W', 1, 1, 3, 1 ) // CR3
   
    call SetUnitRequirements( 'H009', 1, 0, 1, 0 ) // EL1
    call SetUnitRequirements( 'H00G', 2, 0, 2, 0 ) // EL2
    call SetUnitRequirements( 'H00Y', 3, 0, 2, 1 ) // EL3
   
    call SetUnitRequirements( 'H00B', 0, 0, 1, 1 ) // NG1
    call SetUnitRequirements( 'H00H', 0, 0, 1, 2 ) // NG2
    call SetUnitRequirements( 'H00S', 0, 0, 2, 2 ) // NG3
   
    call SetUnitRequirements( 'H008', 1, 0, 0, 1 ) // XO1
    call SetUnitRequirements( 'H00V', 2, 1, 0, 1 ) // XO2
    call SetUnitRequirements( 'H00I', 3, 2, 0, 1 ) // XO3
   
    call SetUnitRequirements( 'H004', 1, 0, 1, 0 ) // SY1
    call SetUnitRequirements( 'H00K', 2, 0, 2, 0 ) // SY2
    call SetUnitRequirements( 'H00U', 3, 0, 2, 1 ) // SY3
   
    call SetUnitRequirements( 'H007', 0, 0, 1, 1 ) // SU1
    call SetUnitRequirements( 'H00L', 0, 0, 2, 1 ) // SU2
    call SetUnitRequirements( 'H00M', 0, 0, 3, 1 ) // SU3
   
endfunction

private function INIT takes nothing returns nothing
    call ExecuteFunc( SCOPE_PRIVATE + "INIT_REALLY" )
endfunction

endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope WeightInit initializer INIT
//===========================================================================
private function INIT_REALLY takes nothing returns nothing
    call SetItemTypeWeight( 'I00N', 1 )
    call SetItemTypeWeight( 'I00M', 2 )
    call SetItemTypeWeight( 'I00L', 2 )
    call SetItemTypeWeight( 'I00O', 1 )
   
    call SetItemTypeWeight( 'I01F',  -2 )
    call SetItemTypeWeight( 'I01G',  -4 )
    call SetItemTypeWeight( 'I01H',  -6 )
    call SetItemTypeWeight( 'I01I',  -9 )
    call SetItemTypeWeight( 'I01J', -12 )
    call SetItemTypeWeight( 'I01K', -15 )
    call SetItemTypeWeight( 'I01L', -20 )
   
    return
   
   
    call SetItemTypeWeight( 'I00E', 1 )
    call SetItemTypeWeight( 'I00G', 2 )
    call SetItemTypeWeight( 'I00P', 3 )
    call SetItemTypeWeight( 'I00Q', 5 )
   
    call SetItemTypeWeight( 'I00S', 1 )
    call SetItemTypeWeight( 'I00T', 2 )
    call SetItemTypeWeight( 'I00U', 3 )
    call SetItemTypeWeight( 'I00W', 4 )
    call SetItemTypeWeight( 'I00X', 5 )
    call SetItemTypeWeight( 'I00V', 6 )
    call SetItemTypeWeight( 'I00Y', 8 )
   
    call SetItemTypeWeight( 'I015', 1 )
    call SetItemTypeWeight( 'I016', 2 )
    call SetItemTypeWeight( 'I017', 4 )
    call SetItemTypeWeight( 'I018', 7 )
   
    call SetItemTypeWeight( 'I010', 1 )
    call SetItemTypeWeight( 'I013', 2 )
    call SetItemTypeWeight( 'I012', 3 )
    call SetItemTypeWeight( 'I011', 4 )
   
endfunction

private function INIT takes nothing returns nothing
    call ExecuteFunc( SCOPE_PRIVATE + "INIT_REALLY" )
endfunction

endscope

 
//TESH.scrollpos=112
//TESH.alwaysfold=0
scope AdminRights initializer INIT


globals
    private constant trigger DebugTrigger = CreateTrigger( )
    private constant trigger InitAdmin = CreateTrigger( )
   
    adminspec Superuser
    adminspec Admin
    adminspec Betatester
    adminspec Mod
    adminspec Noob
    adminspec PrivilegedUser
endglobals

function AdminDebug_Actions takes nothing returns nothing
    local string  trigString = StringCase( GetEventPlayerChatString(), false ) + " "
    local string array parameter
    local integer array parameterPos
    local integer playerId = 0
    local integer stringPos = 1
    local integer i = 0
    local integer curParameter = 0
    local integer len = StringLength( trigString )
    local player  trigPlayer = GetTriggerPlayer()
    local integer trigId = GetPlayerId( trigPlayer )
    local integer level = GetPlayerAdminLevel( trigPlayer )
    local player  tmpPlayer
    local string  tmpString


    loop
        exitwhen i == len
        if SubString( trigString, i, i + 1 ) == " " then
            set parameter[ curParameter ] = SubString( trigString, stringPos, i )
            set parameterPos[ curParameter * 2 ] = stringPos
            set parameterPos[ curParameter * 2 + 1 ] = i
            set stringPos = i + 1
            set curParameter = curParameter + 1
        endif
        set i = i + 1
    endloop

    if parameter[ 0 ] == "gold" then
        set i = S2I( parameter[ 1 ] )
       
        call SetPlayerState( Players[ 0 ], PLAYER_STATE_RESOURCE_GOLD, GetPlayerState( Players[ 0 ], PLAYER_STATE_RESOURCE_GOLD ) + i * Team[ 0 ].numPlayers )
        call SetPlayerState( Players[ 1 ], PLAYER_STATE_RESOURCE_GOLD, GetPlayerState( Players[ 1 ], PLAYER_STATE_RESOURCE_GOLD ) + i * Team[ 1 ].numPlayers )
        loop
            exitwhen playerId > MAX_USER_SLOT
            if Team[ playerId ] != 0 then
                call Transfer( i, Team[ playerId ].empireId, playerId, TRANSFERTYPE_PLAYER_PLAYER, "Debug" )
           
                set TaxSys_LastMoney[ playerId ] = TaxSys_LastMoney[ playerId ] + i
            endif
            set playerId = playerId + 1
        endloop
        call DisplayText( LOCAL_PLAYER, LIGHTGREY + "By debug control, " + GOLD + I2S( i ) + LIGHTGREY + " gold has been added" )
       
    elseif parameter[ 0 ] == "tech" or parameter[ 0 ] == "clvl" then
        set i = S2I( parameter[ 1 ] )
        loop
            exitwhen playerId > NUMPLAYERS
            if PlayerActive[ playerId ] then
                call AddPlayerTechResearched ( Players[ playerId ], DamageUpgrade, i )
                call AddPlayerTechResearched ( Players[ playerId ], LifeUpgrade  , i )
            endif
            set playerId = playerId + 1
        endloop  
        call DisplayText( LOCAL_PLAYER, LIGHTGREY + "By debug control, the creeps have been upgraded by " + GOLD + I2S( i ) + LIGHTGREY + " levels" )
   
   
    elseif parameter[ 0 ] == "exp" or parameter[ 0 ] == "level" then
        set i = S2I( parameter[ 1 ] )
        if parameter[ 0 ] == "level" then
            set i = i * 1000
        endif
       
        loop
            exitwhen playerId > NUMPLAYERS
            call AddHeroXP( Hero[ playerId ], i, false )
            set playerId = playerId + 1
        endloop
        call DisplayText( LOCAL_PLAYER, LIGHTGREY + "By debug control, " + GOLD + I2S( i ) + LIGHTGREY + " experience has been added" )
   
   
    elseif parameter[ 0 ] == "tel" or parameter[ 0 ] == "tele" then
        call SetUnitX( Hero[ trigId ] , S2I( parameter[ 1 ] ) )
        call SetUnitY( Hero[ trigId ] , S2I( parameter[ 2 ] ) )
   
   
    elseif parameter[ 0 ] == "pwd" or parameter[ 0 ] == "passwd" then
        set i = AdminSpec[ parameter[ 1 ] ]
        if i != 0 and AdminSpec[ parameter[ 1 ] ].spec.level < GetPlayerAdminLevel(  Players[ trigId ] ) then
            call DisplayText( Players[ trigId ], GOLD + parameter[ 1 ] +": " + AdminSpec[ parameter[ 1 ] ].passwd )
        else
            call DisplayText( Players[ trigId ], RED + "Unkown Admin: " + parameter[ 1 ] )
        endif
   
   
    elseif parameter[ 0 ] == "pos" then
        call DisplayText( trigPlayer, LIGHTGREY + "  Your current X: " + GREY + I2S( R2I( GetUnitX( Hero[trigId] ) /64 ) *64 ) + LIGHTGREY + "\n  Your current Y: " + GREY + I2S( R2I( GetUnitY( Hero[trigId] ) /64 ) *64 ) )
   
   
    elseif parameter[ 0 ] == "name" or parameter[ 0 ] == "rename" then
        call SetPlayerNameSJ( trigPlayer, SubString( GetEventPlayerChatString(), parameterPos[ 2 ], parameterPos[ 3 ] ) )
        call SavePlayerName ( trigPlayer )
   
    elseif parameter[ 0 ] == "sukick" then
        set tmpString = RED + " has been wiped out from the face of the earth by an admin!"
        if parameter[ 2 ] != null then
            set tmpString = tmpString + "\n  Reason: " + SubString( GetEventPlayerChatString(), parameterPos[ 4 ], parameterPos[ 5 ] )
        endif
        set i = S2I( parameter[ 1 ] ) - 1
        if i == -1 then
            set tmpPlayer = NamePlayer[ parameter[ 1 ] ]
           
            if tmpPlayer == null then
                call DisplayText( trigPlayer, RED + "Invalid parameter: " + parameter[ 1 ] )
            elseif GetPlayerAdminLevel( tmpPlayer ) <= GetPlayerAdminLevel( trigPlayer ) then
                call KickPlayer( tmpPlayer, tmpString )
            else
                set i = GetPlayerId( tmpPlayer )
                call DisplayText( trigPlayer, PlayerName[ i ] + RED + " has a higher admin level than you!" )
                call DisplayText( tmpPlayer, PlayerName[ trigId ] + RED + " has tried to kick you!" )
            endif
        elseif i > 1 then
            set tmpPlayer = Players[ i ]
           
            if GetPlayerAdminLevel( tmpPlayer ) <= GetPlayerAdminLevel( trigPlayer ) then
                call KickPlayer( tmpPlayer, tmpString )
            else
                call DisplayText( trigPlayer, PlayerName[ i ] + RED + " has a higher admin level than you!" )
                call DisplayText( tmpPlayer, PlayerName[ trigId ] + RED + " has tried to kick you!" )
            endif
        else
            call DisplayText( trigPlayer, RED + "Invalid parameter: " + parameter[ 1 ] )
        endif

    elseif parameter[ 0 ] == "suslap" then
        call DisplayText( trigPlayer, RED + " Slap is not implemented yet." )
   
   
    elseif parameter[ 0 ] == "endgame" then
        call EndMap()    
   
    endif
endfunction

private function InitAdmin_Actions takes nothing returns nothing
    local player trigPlayer = GetRegisteredAdmin()
    local integer level = GetPlayerAdminLevel( trigPlayer )
    local boolean activate = ( TotalPlayers > 1 )
   
    if activate and ( Debug  or level >= 2 ) then
        call TriggerRegisterPlayerChatEvent( DebugTrigger, trigPlayer, "-pos", false )
        call TriggerRegisterPlayerChatEvent( DebugTrigger, trigPlayer, "-name", false )
        call TriggerRegisterPlayerChatEvent( DebugTrigger, trigPlayer, "-rename", false )
    endif
   
    if activate and ( Debug  or level >= 7 ) then
        call TriggerRegisterPlayerChatEvent( DebugTrigger, trigPlayer, "-level", false )
        call TriggerRegisterPlayerChatEvent( DebugTrigger, trigPlayer, "-exp", false )
        call TriggerRegisterPlayerChatEvent( DebugTrigger, trigPlayer, "-tel", false )
        call TriggerRegisterPlayerChatEvent( DebugTrigger, trigPlayer, "-tele", false )
        call TriggerRegisterPlayerChatEvent( DebugTrigger, trigPlayer, "-gold", false )
        call TriggerRegisterPlayerChatEvent( DebugTrigger, trigPlayer, "-clvl", false )
        call TriggerRegisterPlayerChatEvent( DebugTrigger, trigPlayer, "-tech", false )
    endif
   
    if level >= 5 then
        call TriggerRegisterPlayerChatEvent( DebugTrigger, trigPlayer, "-suslap", false )
        call TriggerRegisterPlayerChatEvent( DebugTrigger, trigPlayer, "-passwd", false )
        call TriggerRegisterPlayerChatEvent( DebugTrigger, trigPlayer, "-pwd", false )
    endif
    if level >= 9 then
        call TriggerRegisterPlayerChatEvent( DebugTrigger, trigPlayer, "-sukick", false )
    endif
    if level == 10 then
        call TriggerRegisterPlayerChatEvent( DebugTrigger, trigPlayer, "-endgame", false )
    endif
endfunction

public function SinglePlayer takes nothing returns nothing
    local player trigPlayer = LOCAL_PLAYER
    if Debug then
        call TriggerRegisterPlayerChatEvent( DebugTrigger, trigPlayer, "-pos", false )
        call TriggerRegisterPlayerChatEvent( DebugTrigger, trigPlayer, "-name", false )
        call TriggerRegisterPlayerChatEvent( DebugTrigger, trigPlayer, "-rename", false )
   
        call TriggerRegisterPlayerChatEvent( DebugTrigger, trigPlayer, "-level", false )
        call TriggerRegisterPlayerChatEvent( DebugTrigger, trigPlayer, "-exp", false )
        call TriggerRegisterPlayerChatEvent( DebugTrigger, trigPlayer, "-tel", false )
        call TriggerRegisterPlayerChatEvent( DebugTrigger, trigPlayer, "-tele", false )
        call TriggerRegisterPlayerChatEvent( DebugTrigger, trigPlayer, "-gold", false )
        call TriggerRegisterPlayerChatEvent( DebugTrigger, trigPlayer, "-clvl", false )
        call TriggerRegisterPlayerChatEvent( DebugTrigger, trigPlayer, "-tech", false )
    endif
endfunction
   
private function INIT_REALLY takes nothing returns nothing

    set Superuser = adminspec.create( GOLD + "SUPERADMIN", 0, 10 )
    set Admin = adminspec.create( GOLD + "admin", 0, 9 )
    set Betatester = adminspec.create( "betatester", 0, 7 )
    set Mod = adminspec.create( "moderator", 0, 6 )
    set Noob = adminspec.create( RED + "noob", 0, 3 )
    set PrivilegedUser = adminspec.create( "priviliged user", 0, 2 )

    call AddAdmin( "serra",   Superuser )
   
    call AddAdmin( "peon",    Admin )
   
    call AddAdmin( "haddock", Betatester )
    call AddAdmin( "black",   Betatester )
    call AddAdmin( "say",     Betatester )
    call AddAdmin( "bomb",    Betatester )
    call AddAdmin( "vine",    Betatester )
    call AddAdmin( "hera",    Betatester )
    call AddAdmin( "gesh",    Betatester )
    call AddAdmin( "brody",   Betatester )
   
    call AddAdmin( "lorci",     PrivilegedUser )
    call AddAdmin( "blackjack", PrivilegedUser )
    call AddAdmin( "derby",     PrivilegedUser )
    call AddAdmin( "gbz",       PrivilegedUser )

    call AddAdmin( "dynoob",    Noob )
   
    call TriggerRegisterAdminEvent( InitAdmin )
    call TriggerAddAction( InitAdmin, function InitAdmin_Actions )
    call TriggerAddAction( DebugTrigger, function AdminDebug_Actions )
endfunction

private function INIT takes nothing returns nothing
    call ExecuteFunc( SCOPE_PRIVATE + "INIT_REALLY" )
endfunction
endscope
 
//TESH.scrollpos=104
//TESH.alwaysfold=0
// SPECIAL THANKS: Tom_Kazansky for his incredible wisdom concerning the creation of texttags ; )
/////// VER 00
globals
    // Set To false if you want to add bounty on your own way.
    constant boolean AUTO_ADD_BOUNTY = true
endglobals


 //! runtextmacro AddUnitValue( "BountyMax", "integer", "0" )
 //! runtextmacro AddUnitValue( "BountyMin", "integer", "0" )


library BountySystem initializer InitBountySystem needs Hash, Utilities, BountyMinAttacherUnit, BountyMaxAttacherUnit
 globals
      private constant real DefaultGainValue = 1.0 // 1 = 100%; 0.5 = 50%
      private constant real DefaultGiveValue = 1.0

      private real array PlayerBountyGive
      private real array PlayerBountyGain

      private integer Bounty = 0
      private unit BountyGiver = null
      private player BountyGetter = null
      private player BountyGiverOwner = null
      private constant trigger BountyTrigger = CreateTrigger()

      private trigger array AttachedTrigger
      private integer AttachedTriggerNum = -1
      private constant trigger TriggerHandler = CreateTrigger()
              constant integer PLAYER_BOUNTY_GIVE = -1
      constant integer PLAYER_BOUNTY_GAIN = 1
 endglobals


 function GetBountyUnit takes nothing returns unit
     return BountyGiver
 endfunction

 function GetTriggerBounty takes nothing returns integer
     return Bounty
 endfunction

 function GetBountyPlayer takes nothing returns player
     return BountyGetter
 endfunction

 function GetBountyGiver takes nothing returns player
     return BountyGiver
 endfunction

 function TriggerRegisterBountyEvent takes trigger toregister returns nothing
     set AttachedTriggerNum = AttachedTriggerNum + 1
     set AttachedTrigger [ AttachedTriggerNum ] = toregister
 endfunction

 function SetPlayerBounty takes integer playerid, real give, real gain returns nothing
     set PlayerBountyGive[ playerid ] = give
     set PlayerBountyGain[ playerid ] = gain
 endfunction

 function GetPlayerBounty takes integer playerid, integer bountytype returns real
     if bountytype == PLAYER_BOUNTY_GIVE then
         return PlayerBountyGive[ playerid ]
     elseif bountytype == PLAYER_BOUNTY_GAIN then
         return PlayerBountyGain[ playerid ]
     endif
     return 0.0
 endfunction

 private function GetUnitTypeBounty takes integer unittypeid returns integer
     return GetRandomInt( GetUnitTypeBountyMin( unittypeid ), GetUnitTypeBountyMax( unittypeid ) )
 endfunction

 function SetUnitTypeBounty takes integer unittypeid, integer min, integer max returns nothing
     call SetUnitTypeBountyMin( unittypeid, min )
     call SetUnitTypeBountyMax( unittypeid, max )
 endfunction

 private function TriggerHandler_Actions takes nothing returns nothing
             local integer loopIndicator = 0
             local unit trigUnit = GetTriggerUnit ( )
             local integer trigUnitID = GetUnitTypeId ( trigUnit )
             local integer bounty = GetUnitTypeBounty( trigUnitID )
             local player bountyPlayer = GetOwningPlayer ( GetKillingUnit() )
             local player bountyGiver = GetOwningPlayer ( trigUnit )

             set Bounty = bounty
             set BountyGetter = bountyPlayer
             set BountyGiver = trigUnit
             set BountyGiverOwner = bountyGiver

             if IsPlayerEnemy( BountyGiverOwner, BountyGetter ) and Bounty > 0 then
                 loop
                     exitwhen loopIndicator > AttachedTriggerNum
                     if TriggerEvaluate( AttachedTrigger[ loopIndicator ] ) then
                        call TriggerExecute( AttachedTrigger[ loopIndicator ] )
                     endif
                     set loopIndicator = loopIndicator + 1
                 endloop

            endif
            set trigUnit = null
         endfunction







 private function BountyTrigger_Actions takes nothing returns nothing
             local integer bountyAmount = GetTriggerBounty( )
             local unit bountyUnit = GetBountyUnit ( )
             local player bountyPlayer = GetBountyPlayer ( )


             local player bountyGiver = BountyGiverOwner
             local integer bountyPlayerId = GetPlayerId ( bountyPlayer )
             local integer bountyGiverId = GetPlayerId ( bountyGiver )



             set bountyAmount = R2I( bountyAmount * PlayerBountyGive[ bountyGiverId ] * PlayerBountyGain[ bountyPlayerId ] )

             call CreateBountyText( bountyAmount, bountyUnit, bountyPlayer )


             // call SetPlayerState ( bountyPlayer, PLAYER_STATE_RESOURCE_GOLD, GetPlayerState( bountyPlayer, PLAYER_STATE_RESOURCE_GOLD ) + bountyAmount )
             // call SetPlayerState ( bountyPlayer, PLAYER_STATE_GOLD_GATHERED, GetPlayerState( bountyPlayer, PLAYER_STATE_GOLD_GATHERED ) + bountyAmount )
               
             call AddGold( bountyAmount, bountyPlayerId, TRANSFERTYPE_PLAYER_PLAYER, "Creeping" )
             call AddGold( bountyAmount/2, Team[bountyPlayerId].empireId, TRANSFERTYPE_PLAYER_PLAYER, "Creepbonus" )

             set bountyUnit = null
         endfunction

 private function InitBountySystem takes nothing returns nothing
             local integer playerIndex = 0
             call TriggerRegisterAnyUnitEventBJ( TriggerHandler, EVENT_PLAYER_UNIT_DEATH )
             call TriggerAddAction ( TriggerHandler, function TriggerHandler_Actions )

             loop
                 exitwhen playerIndex > MAX_PLAYER_SLOT
                 set PlayerBountyGive[ playerIndex ] = DefaultGiveValue
                 set PlayerBountyGain[ playerIndex ] = DefaultGainValue
                 set playerIndex = playerIndex + 1
             endloop

             // Please outcomment the following two lines if you do not want to distribute bounty as usually!
             if AUTO_ADD_BOUNTY then
                call TriggerRegisterBountyEvent ( BountyTrigger )
                call TriggerAddAction ( BountyTrigger, function BountyTrigger_Actions )
             endif

         endfunction
endlibrary
 
//TESH.scrollpos=22
//TESH.alwaysfold=0
   
library WaveSystem needs Utilities


struct spawn
    spawn last = 0
    spawn next = 0
    integer spawnType
    integer spawnNum
    static method create takes integer spawntype, integer num, spawn last returns spawn
        local spawn this = .allocate()
        set .last = last
        set .next = .last.next
        set .last.next = this
        set .next.last = this
        set .spawnType = spawntype
        set .spawnNum = num
        return this
    endmethod
endstruct

struct wave
    private string        DefaultOrder
    private spawn first
    private spawn last
   
    static method create takes string defaultorder returns wave
        local wave this = .allocate()
        set .DefaultOrder = defaultorder
        set .first = 0
        set .last = 0
        return this
    endmethod
   
    method addSpawn takes integer typeid, integer num returns spawn
        local spawn new = spawn.create( typeid, num, .last )
        if .first == 0 then
            set .first = new
        endif
        set .last = new
        return new
    endmethod
   
    method spawn takes player owner, real startx, real starty, real endx, real endy returns nothing
        local spawn curSpawn = .first
        loop    
            exitwhen curSpawn == .last.next
            call CreateNUnitsOrder( owner, curSpawn.spawnType, startx, starty, curSpawn.spawnNum, .DefaultOrder, endx, endy )
            set curSpawn = curSpawn.next
        endloop    
    endmethod
   
    method dropSpawn takes spawn todrop returns nothing
        local spawn curSpawn = .first
        loop    
            exitwhen curSpawn == .last.next
            exitwhen curSpawn == todrop
            set curSpawn = curSpawn.next
        endloop
        set curSpawn.last.next = curSpawn.next
        set curSpawn.next.last = curSpawn.last    
    endmethod
endstruct
endlibrary
//TESH.scrollpos=-1
//TESH.alwaysfold=0
scope PeriodicSpawn initializer INIT
globals
    constant real          LowInterval  = 15
    constant real          PirInterval  = 30
    constant real          AeroInterval = 60
    constant real          BombInterval = 90
   

             wave          Piratewave
             
             wave          Lowerwave
             wave          Cruiserwave
             wave          Bombarderwave    
   
             integer       LowWave     = 0
             integer       AeroWave    = 0
             integer       BombWave    = 0
   
             boolean       SpawnPirNorth = true
   
    constant trigger       DeactivatorNR    = CreateTrigger( )
    constant trigger       DeactivatorNL    = CreateTrigger( )
   
    constant trigger       DeactivatorSR    = CreateTrigger( )
    constant trigger       DeactivatorSL    = CreateTrigger( )
   
    constant trigger       DeactivatorPir   = CreateTrigger( )
   
    constant player        PiratePlayer     = Player( bj_PLAYER_NEUTRAL_EXTRA )
endglobals
                     
                       
function LowSpawner_Actions takes nothing returns nothing
    if GameRuns then
        if SouthActiveRight then
            call Lowerwave.spawn( Players[ 0 ] , SouthHarborRightCenterX , SouthHarborRightCenterY , NorthHarborRightCenterX , NorthHarborRightCenterY )
        endif
        if SouthActiveLeft then
            call Lowerwave.spawn( Players[ 0 ] , SouthHarborLeftCenterX  , SouthHarborLeftCenterY  , NorthHarborLeftCenterX  , NorthHarborLeftCenterY  )
        endif

        if NorthActiveLeft then
            call Lowerwave.spawn( Players[ 1 ] , NorthHarborLeftCenterX  , NorthHarborLeftCenterY  , SouthHarborLeftCenterX  , SouthHarborLeftCenterY  )
        endif
        if NorthActiveRight then
            call Lowerwave.spawn( Players[ 1 ] , NorthHarborRightCenterX , NorthHarborRightCenterY , SouthHarborRightCenterX , SouthHarborRightCenterY )
        endif
       
        set LowWave = LowWave + 1
    else
        call DestroyTimer( GetExpiredTimer() )
    endif    
endfunction
 
function PirSpawner_Actions takes nothing returns nothing
    if GameRuns and PirateActive then
        if SpawnPirNorth then
            call Piratewave.spawn( PiratePlayer, PirateBaseCenterX, PirateBaseCenterY, NorthPirateLoc1CenterX, NorthPirateLoc1CenterY )
        else
            call Piratewave.spawn( PiratePlayer, PirateBaseCenterX, PirateBaseCenterY, SouthPirateLoc1CenterX, SouthPirateLoc1CenterY )
        endif
        set SpawnPirNorth = not SpawnPirNorth
    else
        call DestroyTimer( GetExpiredTimer() )
    endif    
endfunction

function AeroSpawner_Actions takes nothing returns nothing
    if GameRuns then
        if SouthActiveRight then
            call Cruiserwave.spawn( Players[ 0 ] , SouthHarborRightCenterX , SouthHarborRightCenterY , NorthHarborRightCenterX , NorthHarborRightCenterY )
        endif
        if SouthActiveLeft then
            call Cruiserwave.spawn( Players[ 0 ] , SouthHarborLeftCenterX  , SouthHarborLeftCenterY  , NorthHarborLeftCenterX  , NorthHarborLeftCenterY  )
        endif

        if NorthActiveLeft then
            call Cruiserwave.spawn( Players[ 1 ] , NorthHarborLeftCenterX  , NorthHarborLeftCenterY  , SouthHarborLeftCenterX  , SouthHarborLeftCenterY  )
        endif
        if NorthActiveRight then
            call Cruiserwave.spawn( Players[ 1 ] , NorthHarborRightCenterX , NorthHarborRightCenterY , SouthHarborRightCenterX , SouthHarborRightCenterY )
        endif
       
       
        set AeroWave = AeroWave + 1
    else
        call DestroyTimer( GetExpiredTimer() )
    endif    
endfunction

function BombSpawner_Actions takes nothing returns nothing
    if GameRuns then
        if SouthActiveRight then
            call Bombarderwave.spawn( Players[ 0 ] , SouthHarborRightCenterX , SouthHarborRightCenterY , NorthHarborRightCenterX , NorthHarborRightCenterY )
        endif
        if SouthActiveLeft then
            call Bombarderwave.spawn( Players[ 0 ] , SouthHarborLeftCenterX  , SouthHarborLeftCenterY  , NorthHarborLeftCenterX  , NorthHarborLeftCenterY  )
        endif

        if NorthActiveLeft then
            call Bombarderwave.spawn( Players[ 1 ] , NorthHarborLeftCenterX  , NorthHarborLeftCenterY  , SouthHarborLeftCenterX  , SouthHarborLeftCenterY  )
        endif
        if NorthActiveRight then
            call Bombarderwave.spawn( Players[ 1 ] , NorthHarborRightCenterX , NorthHarborRightCenterY , SouthHarborRightCenterX , SouthHarborRightCenterY )
        endif
       
        set BombWave = BombWave + 1
    else
        call DestroyTimer( GetExpiredTimer() )
    endif    
endfunction

//! textmacro DeactivatorActions takes TEAM , POS, TOWERS, NEGMSG, POSMSG
globals
    integer $TEAM$Towers$POS$ = $TOWERS$
    boolean $TEAM$Active$POS$ = true
endglobals

function $TEAM$$POS$_Deactivator takes nothing returns nothing
    local player localPlayer = LOCAL_PLAYER
    set $TEAM$Towers$POS$ = $TEAM$Towers$POS$ - 1
    if $TEAM$Towers$POS$ == 0 then
        set $TEAM$Active$POS$ = false

        if IsPlayerAlly( localPlayer , $TEAM$Player ) then
            call DisplayTextToPlayer( localPlayer , 0 , 0 , NegativeTag + "$NEGMSG$" )
        else
            call DisplayTextToPlayer( localPlayer , 0 , 0 , PositiveTag + "$POSMSG$" )
        endif
    endif
endfunction
//! endtextmacro
//! runtextmacro DeactivatorActions( "North",  "Right", "2", "Your Right side harbor has been deactivated!",  "Your team has succesfully deactivated the enemy's Right side harbor!" )
//! runtextmacro DeactivatorActions( "North",  "Left",  "2", "Your Left side harbor has been deactivated!",  "Your team has succesfully deactivated the enemy's Left side harbor!" )
//! runtextmacro DeactivatorActions( "South",  "Right", "2", "Your Right side harbor has been deactivated!",  "Your team has succesfully deactivated the enemy's Right side harbor!" )
//! runtextmacro DeactivatorActions( "South",  "Left",  "2", "Your Left side harbor has been deactivated!",  "Your team has succesfully deactivated the enemy's Left side harbor!" )

//! runtextmacro DeactivatorActions( "Pirate", "",      "3", "", "The Pirates have been extinguished from the face of the earth!" )      
//===========================================================================
private function INIT_REALLY takes nothing returns nothing
    local integer i = 0

    call TimerStart( CreateTimer(), PirInterval,  true, function PirSpawner_Actions  )
    call TimerStart( CreateTimer(), LowInterval,  true, function LowSpawner_Actions  )
    call TimerStart( CreateTimer(), AeroInterval, true, function AeroSpawner_Actions )
    call TimerStart( CreateTimer(), BombInterval, true, function BombSpawner_Actions )
   
    set Piratewave    = wave.create( "attack" )
    set Lowerwave     = wave.create( "attack" )
    set Cruiserwave   = wave.create( "attack" )
    set Bombarderwave = wave.create( "attack" )
   
   
    call Piratewave.addSpawn   ( PirateShip , 3 )
    //call Piratewave.addSpawn   ( PirFlagShip, 1 )
   
    call Lowerwave.addSpawn    ( AssaultShip, 3 )
    call Lowerwave.addSpawn    ( Frigate    , 1 )
    call Cruiserwave.addSpawn  ( AeroCruiser, 1 )
    call Bombarderwave.addSpawn( Bombarder  , 1 )
   
    call TriggerRegisterUnitEvent( DeactivatorNR, gg_unit_n002_0042, EVENT_UNIT_DEATH )
    call TriggerRegisterUnitEvent( DeactivatorNR, gg_unit_n002_0049, EVENT_UNIT_DEATH )    
   
    call TriggerRegisterUnitEvent( DeactivatorNL, gg_unit_n002_0050, EVENT_UNIT_DEATH )
    call TriggerRegisterUnitEvent( DeactivatorNL, gg_unit_n002_0055, EVENT_UNIT_DEATH )
   
   
    call TriggerRegisterUnitEvent( DeactivatorSR, gg_unit_n002_0062, EVENT_UNIT_DEATH )
    call TriggerRegisterUnitEvent( DeactivatorSR, gg_unit_n002_0060, EVENT_UNIT_DEATH )

    call TriggerRegisterUnitEvent( DeactivatorSL, gg_unit_n002_0043, EVENT_UNIT_DEATH )
    call TriggerRegisterUnitEvent( DeactivatorSL, gg_unit_n002_0059, EVENT_UNIT_DEATH )
   
    call TriggerRegisterUnitEvent( DeactivatorPir, gg_unit_n00V_0044, EVENT_UNIT_DEATH )
    call TriggerRegisterUnitEvent( DeactivatorPir, gg_unit_n00V_0063, EVENT_UNIT_DEATH )
    call TriggerRegisterUnitEvent( DeactivatorPir, gg_unit_n00V_0048, EVENT_UNIT_DEATH )
   
    call TriggerAddAction        ( DeactivatorNR, function NorthRight_Deactivator )
    call TriggerAddAction        ( DeactivatorNL, function NorthLeft_Deactivator  )
   
    call TriggerAddAction        ( DeactivatorSR, function SouthRight_Deactivator )
    call TriggerAddAction        ( DeactivatorSL, function SouthLeft_Deactivator  )
   
    call TriggerAddAction        ( DeactivatorPir, function Pirate_Deactivator )
   
    call LowSpawner_Actions(  )
   
    call SetUnitOwner( gg_unit_n00V_0044, PiratePlayer, false )
    call SetUnitOwner( gg_unit_n00V_0063, PiratePlayer, false )
    call SetUnitOwner( gg_unit_n00V_0048, PiratePlayer, false )
    loop
        exitwhen i > MAX_PLAYER_SLOT
        call SetPlayerAllianceStateSJ( Players[ i ], PiratePlayer, bj_ALLIANCE_UNALLIED )
        set i = i + 1
    endloop
endfunction

private function INIT takes nothing returns nothing
    call ExecuteFunc( SCOPE_PRIVATE + "INIT_REALLY" )
endfunction
endscope


   
 
//TESH.scrollpos=0
//TESH.alwaysfold=0
//*********************************************************************
// The Quicksort Algorithm                                            *
//   - Median of two ; Insertsort for arrays of 4 and less-           *
// Expected efficiency  : O( n * log n )                              *
// Worst case efficiency: O( n² )                                     *
//**********************************************************************************************************************
//* !!! All array members that will be sorted need to have a value! All Parallelsort fields need to have a value too!  *
//* !!! The Tosort Variable needs to be of Type Integer!                                                               *
//* !!! To use it, write //! runtextmacro QSORT( the array to be sorted, the array to be parallely sorted, and the     *
//*     type of the array that is sorted parallely. Example:                                                           *
//*     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -    *
//      globals                                                                                                        
//          integer array HeroLevel                                                                                    
//          unit    array Heroes                                                                                      
//          integer       NumHeroes                                                                                    
//      endglobals                                                                                                    
//                                                                                                                    
//      //! runtextmacro QSORT( HeroLevel , Heroes, unit )                                                            
//                                                                                                                    
//      function DisplayMaxHeroLevel takes nothing returns nothing                                                        
//          call QSortHeroLevel( 0 , NumHeroes )
//          call DisplayTextToPlayer( GetLocalPlayer() , 0 , 0 , "|cffffcc00The highest-level Hero is " + GetUnitName( Heroes[ NumHeroes ] ) )                                                                                *
//      endfunction
//    
//*    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - -    *
//*    So to make the array sortable, run the textmacro. Then to actually sort it, use                                 *
//*          
//          call QSort[the array to be sorted]( lower sorting bound , upper sorting bound )
//*
//*    Not difficult at all, is it?                                                                                    *
//*    Only bad thing: You allways need a filled parallelsort for it, which needs to be different from the array to be *
//*    sorted. Most probably you would've needed it anyway, but not always.                                            *
//**********************************************************************************************************************
//* Coded by Cpt.DaveyJones/SerraAvenger, invented by C. A. R. Hoare

library QuickSort

//! textmacro QSORT takes TOSORT , PARALLELSORT , PARALLELTYPE

   
    function InsertSort$TOSORT$ takes integer lowerbound, integer upperbound returns nothing
        local integer outerLoop = lowerbound + 1
        local integer innerLoop
        local integer key                                                    
        local $PARALLELTYPE$ lock      
        loop
            exitwhen outerLoop > upperbound
            set innerLoop = outerLoop

            set key  = $TOSORT$      [ outerLoop ]
            set lock = $PARALLELSORT$[ outerLoop ]
            loop
                exitwhen innerLoop <= lowerbound
                exitwhen $TOSORT$ [ innerLoop - 1 ] < key
                set $TOSORT$      [ innerLoop ] = $TOSORT$      [ innerLoop - 1 ]
                set $PARALLELSORT$[ innerLoop ] = $PARALLELSORT$[ innerLoop - 1 ]
                set innerLoop     = innerLoop - 1
            endloop
            set $TOSORT$      [ innerLoop ] = key
            set $PARALLELSORT$[ innerLoop ] = lock
           
            set outerLoop = outerLoop + 1
        endloop
        //if not ("$PARALLELTYPE$" == "integer" or "$PARALLELTYPE$" == "real"  ) then
        //    set lock = null
        //endif
    endfunction
   

    function QSort$TOSORT$ takes integer lowerbound, integer upperbound returns nothing
        local integer pivot          = ( $TOSORT$[ lowerbound ] + $TOSORT$[ upperbound ] + $TOSORT$[ GetRandomInt( lowerbound, upperbound ) ] ) / 3
        local integer leftIndicator  = lowerbound
        local integer rightIndicator = upperbound
        local integer tempValue
        local $PARALLELTYPE$ tempParallelValue
        if upperbound - lowerbound > 8 then

            loop

                loop
                    exitwhen $TOSORT$[ rightIndicator ] < pivot
                    exitwhen rightIndicator == leftIndicator
                    set rightIndicator = rightIndicator - 1
                endloop
                loop
                    exitwhen $TOSORT$[ leftIndicator ] >= pivot
                    exitwhen leftIndicator == rightIndicator
                    set leftIndicator = leftIndicator + 1
                endloop
                exitwhen leftIndicator > rightIndicator
               
                set tempValue                  = $TOSORT$[ rightIndicator ]
                set $TOSORT$[ rightIndicator ] = $TOSORT$[ leftIndicator  ]
                set $TOSORT$[ leftIndicator  ] = tempValue


                set tempParallelValue                = $PARALLELSORT$[ rightIndicator ]
                set $PARALLELSORT$[ rightIndicator ] = $PARALLELSORT$[ leftIndicator  ]
                set $PARALLELSORT$[ leftIndicator  ] = tempParallelValue
            endloop
            call QSort$TOSORT$( lowerbound         , leftIndicator )                                                                        
            call QSort$TOSORT$( rightIndicator + 1 , upperbound    )

        else
            call InsertSort$TOSORT$( lowerbound, upperbound )
        endif
       
    endfunction
   
//! endtextmacro                            
endlibrary



//! textmacro BSEARCH takes SEARCHARRAY

function BSearch$SEARCHARRAY$ takes integer tosearch, integer lowerbound, integer upperbound returns integer
    local integer low  = lowerbound
    local integer high = upperbound
    local integer mid

    loop
        exitwhen low > high
        set mid = ( low + high ) / 2
        if $SEARCHARRAY$[ mid ] < tosearch then
            set low  = mid + 1
        elseif $SEARCHARRAY$[ mid ] > tosearch then
            set high = mid - 1
        else
            return mid
        endif
    endloop
    return -1
endfunction
//! endtextmacro
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope ToggleMessages initializer INIT

globals
    private trigger Toggler = CreateTrigger()
endglobals

private function Actions takes nothing returns nothing
    local player trigPlayer = GetTriggerPlayer()
    local integer trigId = GetPlayerId( trigPlayer )
    local string msg = StringCase( SubString( GetEventPlayerChatString(), 6, 12 ), false )
   
    if msg == "toggle" then
        set ShowMessages[ trigId ] = not ShowMessages[ trigId ]
    else
        set ShowMessages[ trigId ] = ( msg == "all" )
    endif
   
   
    if ShowMessages[ trigId ] then
        call DisplayText( trigPlayer, LIGHTGREY + "Showing all game messages" )
    else
        call DisplayText( trigPlayer, LIGHTGREY + "Showing few game messages" )
    endif
endfunction

private function INIT_REALLY takes nothing returns nothing
    call TriggerRegisterAnyPlayerChatEvent( Toggler, "-show all", true )
    call TriggerRegisterAnyPlayerChatEvent( Toggler, "-show few", true )
    call TriggerRegisterAnyPlayerChatEvent( Toggler, "-show toggle", true )
    call TriggerAddAction( Toggler, function Actions )
endfunction

//===========================================================================
private function INIT takes nothing returns nothing
    call ExecuteFunc( SCOPE_PRIVATE + "INIT_REALLY" )
endfunction

endscope

 
//TESH.scrollpos=15
//TESH.alwaysfold=0

//! runtextmacro AddUnitValue( "Icon", "string", "null" )
scope StatsMb initializer INIT
globals
    private multiboard StatsMB
    string array State
    constant string MbTitle = PlayerColor[ 10 ] + "Bs Arc - " + GOLD
   
    private constant trigger ShowStats = CreateTrigger()
endglobals

function UpdateStatsMB takes nothing returns nothing
    local integer i = 0
    local integer localId = GetPlayerId( LOCAL_PLAYER )
    call MultiboardSetTitleText( StatsMB, MbTitle + GetGameTimeString(":") )
    loop
        exitwhen i > MAX_USER_SLOT
       
        if i >= 7 then
            if i == localId then
                call SetMultiboardItemValue( StatsMB, i - 4, 1, TeamColor[ 1 ] + " -  " + PlayerColor[ 10 ] + PlayerNameUncolored[ i ], "", 0, null )//GetUnitIcon( Hero[ i ] ), 0, null )
            else
                call SetMultiboardItemValue( StatsMB, i - 4, 1, TeamColor[ 1 ] + " -  " + PlayerNameUncolored[ i ], "", 0, null )// GetUnitIcon( Hero[ i ] ), 0, null )
            endif
            call SetMultiboardItemValue( StatsMB, i - 4, 0, GOLD + I2S( i + 1 ), "", 0, null )
            call SetMultiboardItemValue( StatsMB, i - 4, 2, GREEN + I2S( Kills[ i ] ), "", 0, null )
            call SetMultiboardItemValue( StatsMB, i - 4, 3, RED + I2S( Deaths[ i ] ), "", 0, null )
            call SetMultiboardItemValue( StatsMB, i - 4, 4, State[ i ], "", 0, null )
        elseif i >= 2 then
            if i == localId then
                call SetMultiboardItemValue( StatsMB, i + 8, 1, TeamColor[ 0 ] + " -  " + PlayerColor[ 10 ] + PlayerNameUncolored[ i ], "", 0, null )//GetUnitIcon( Hero[ i ] ), 0, null )
            else
                call SetMultiboardItemValue( StatsMB, i + 8, 1, TeamColor[ 0 ] + " -  " + PlayerNameUncolored[ i ], "", 0, null )// GetUnitIcon( Hero[ i ] ), 0, null )
            endif
            call SetMultiboardItemValue( StatsMB, i + 8, 0, GOLD + I2S( i + 1 ), "", 0, null )
            call SetMultiboardItemValue( StatsMB, i + 8, 2, GREEN + I2S( Kills[ i ] ), "", 0, null )
            call SetMultiboardItemValue( StatsMB, i + 8, 3, RED + I2S( Deaths[ i ] ), "", 0, null )
            call SetMultiboardItemValue( StatsMB, i + 8, 4, State[ i ], "", 0, null )
       
        else
            if i == 0 then
                call SetMultiboardItemValue( StatsMB, i + 9, 1, TeamName[ i ], "", 0, null )
                call SetMultiboardItemValue( StatsMB, i + 9, 2, TeamColor[ i ] + I2S( Kills[ i ] ), "", 0, null )
                call SetMultiboardItemValue( StatsMB, i + 9, 3, TeamColor[ i ] + I2S( Deaths[ i ] ), "", 0, null )
            else
                call SetMultiboardItemValue( StatsMB, i + 1, 1, TeamName[ i ], "", 0, null )
                call SetMultiboardItemValue( StatsMB, i + 1, 2, TeamColor[ i ] + I2S( Kills[ i ] ), "", 0, null )
                call SetMultiboardItemValue( StatsMB, i + 1, 3, TeamColor[ i ] + I2S( Deaths[ i ] ), "", 0, null )
            endif
        endif
        set i = i + 1
    endloop
endfunction

function ShowStatsMB takes nothing returns nothing    
    call MultiboardSetTitleText( StatsMB, GOLD + "Statistics" )
    call MultiboardSetColumnCount( StatsMB, 5 )
    call MultiboardSetRowCount( StatsMB, MAX_USER_SLOT + 5 )
    call SetMultiboardItemValue( StatsMB, -1, 0, "", "", 0.005, null )
    call SetMultiboardItemValue( StatsMB, -1, 1, "", "", 0.12, null )
    call SetMultiboardItemValue( StatsMB, -1, 2, "", "", 0.015, null )
    call SetMultiboardItemValue( StatsMB, -1, 3, "", "", 0.015, null )
    call SetMultiboardItemValue( StatsMB, -1, 4, "", "", 0.04, null )

    call SetMultiboardItemValue( StatsMB, 0, 1, GOLD + "Name", "", 0, null )
    call SetMultiboardItemValue( StatsMB, 0, 2, GOLD + "K", "", 0, null )
    call SetMultiboardItemValue( StatsMB, 0, 3, GOLD + "D", "", 0, null )
    call SetMultiboardItemValue( StatsMB, 0, 4, GOLD + "State", "", 0, null )
   
    call UpdateStatsMB()
    call MultiboardSetItemsStyle( StatsMB, true, false )
    call MultiboardDisplaySJ( StatsMB, true, null )
    call TimerStart( GetExpiredTimer(), 1, true, function UpdateStatsMB )
endfunction

private function ShowStats_Actions takes nothing returns nothing
    local player trigPlayer = GetTriggerPlayer()
    local string eventString = StringCase( GetEventPlayerChatString(), false )
    local string subString = SubString( eventString, 7, 12 )
    local boolean show
    if eventString == "-stats" then
        set show = not IsMultiboardDisplayed( StatsMB )
    else
        set show = subString == "on"
        call DisplayText( LOCAL_PLAYER, subString )
    endif
    call MultiboardDisplaySJ( StatsMB, show, trigPlayer )
endfunction

private function INIT takes nothing returns nothing
    set StatsMB = CreateMultiboard( )
    call MultiboardClear( StatsMB )
    call TimerStart( CreateTimer(), 0.60, false, function ShowStatsMB )
   
    call TriggerRegisterAnyPlayerChatEvent( ShowStats, "-stats off",  true )
    call TriggerRegisterAnyPlayerChatEvent( ShowStats, "-stats on",   true )
    call TriggerRegisterAnyPlayerChatEvent( ShowStats, "-stats",      true )
   
    call TriggerAddAction( ShowStats, function ShowStats_Actions )
endfunction
endscope
//TESH.scrollpos=98
//TESH.alwaysfold=0
//----------------------------------------------------------\\
// VER 05 \\
//----------------------------------------------------------\\

library HelpFile initializer InitHF needs Utilities
globals
    helpfile HELP
    helpfile INDEX
    helpfile BASE
    private boolean array isLast
    private integer Row
    private integer Col
    private multiboard SortedIndex
    private helpfile array SortedFile
    private integer helpfiles = 0
    private constant integer MB_MAX_ROWS = 25
    private boolean array MbDisplay
    private helpfile array LastSeen
    private constant trigger ShowHelpfile = CreateTrigger()
    private constant trigger ShowIndex = CreateTrigger()
    private constant trigger ShowBase = CreateTrigger()
endglobals

private function UpdateMultiboard takes nothing returns nothing
    local integer index = 0
    local multiboarditem curItem
    local integer hotstringId
    local string hotstrings
    local integer depth
    local integer array subfile
    local integer localId = GetPlayerId( GetLocalPlayer() )
    set Row = 0
    set Col = 0
   
               

    call SetMultiboardItemValue( SortedIndex, 0, 0, GOLD + "Helpfile", "", 0, null )
   
    call HELP.getMBString( BASE, 0 )
endfunction

function ToggleMBView takes nothing returns nothing
    local player trigPlayer = GetTriggerPlayer()
    local integer trigPlayerId = GetPlayerId( trigPlayer )
    set MbDisplay[ trigPlayerId ] = not MbDisplay[ trigPlayerId ]
    call MultiboardDisplaySJ( SortedIndex, MbDisplay[ trigPlayerId ], trigPlayer )
    if trigPlayer == LOCAL_PLAYER then
        call MultiboardMinimize( SortedIndex, false )
    endif
endfunction

private function GenerateMultiboard takes nothing returns nothing
    call MultiboardClear( SortedIndex )
    call MultiboardSetRowCount( SortedIndex, IMinBJ( helpfiles, MB_MAX_ROWS ) + 2 )
    call MultiboardSetColumnCount( SortedIndex, R2I( helpfiles / MB_MAX_ROWS + 1 ) * 2 )
    call MultiboardSetItemsWidth( SortedIndex, .12 )
    call MultiboardSetTitleText( SortedIndex, GOLD + "Help Index" )
    call MultiboardSetItemsStyle( SortedIndex, true, false )
    call TriggerRegisterAnyPlayerChatEvent( ShowIndex, "-h index",      true )
    call TriggerRegisterAnyPlayerChatEvent( ShowIndex, "-help index",   true )
    call TriggerRegisterAnyPlayerChatEvent( ShowIndex, "-man index",    true )
    call TriggerRegisterAnyPlayerChatEvent( ShowIndex, "-manual index", true )
    call TriggerAddAction( ShowIndex, function ToggleMBView )
endfunction

function DisplayFile takes helpfile trigFile, player trigPlayer returns nothing
    local string subclassMsg = GREY + "Sub categories: "
    local integer index = 0
    local helpfile curSubfile
    if trigFile.parent != 0 then
        call DisplayTimedTextToPlayer( trigPlayer, 0, 0, 30, LIGHTGREY + trigFile.name + GREY + " ( " + GOLD + trigFile.parent.name + GREY + " ):" )
    else
        call DisplayTimedTextToPlayer( trigPlayer, 0, 0, 30, LIGHTGREY + trigFile.name + GREY + ":" )
    endif
    if trigFile.subclasses > 0 then
        loop
            exitwhen index == trigFile.subclasses
            set curSubfile = trigFile.subclass[ index ]
            if index + 1 < trigFile.subclasses then
                set subclassMsg = subclassMsg + LIGHTGREY + curSubfile.name + ", "
            else
                set subclassMsg = subclassMsg + LIGHTGREY + curSubfile.name
            endif
            set index = index + 1
        endloop
        call DisplayTimedTextToPlayer( trigPlayer, 0, 0, 30, subclassMsg )
    endif
    call DisplayTimedTextToPlayer( trigPlayer, 0, 0, 30, GREY + trigFile.help )
    set LastSeen[ GetPlayerId( trigPlayer ) ] = trigFile        
    call UpdateMultiboard()
endfunction

function DisplayFileByName takes string name, player trigPlayer returns nothing
    local integer index = 0
    local integer depth = 0
    local integer length = StringLength( name )
    local integer matches = helpfiles
    local integer closeMatches = 0
    local integer closeIndex = 0
    local boolean array inConsideration
    local boolean array closeFile
    local string array matchedName
    local helpfile array match
    local helpfile array matchDepth
    local string curChar
    local string showString
    local string curName
    set name = StringCase( name, false )
    loop
        exitwhen index == matches
        set match[ index ] = SortedFile[ index ]
        set matchDepth[ index ] = length
        set matchedName[ index ] = LIGHTGREY + match[ index ].name
        set inConsideration[ index ] = true
        set closeFile[ index ] = false
        set index = index + 1
    endloop
    loop
        exitwhen depth >= length
        exitwhen matches == 0
        set index = 0
        set curChar = SubString( name, depth, depth + 1 )
        loop
            exitwhen index >= helpfiles
            if inConsideration[ index ] then
                if SubString( match[ index ].comparename, depth, depth + 1 ) != curChar then
                    set matchDepth[ index ] = depth
                    set inConsideration[ index ] = false
                    set curName = match[ index ].name
                    set matchedName[ index ] =  GOLD + SubString( curName, 0, depth ) + LIGHTGREY + SubString( curName, depth, StringLength( curName ) )
                    set matches = matches - 1
                    set closeMatches = closeMatches + 1
                    set closeFile[ index ] = true
                endif
            endif
            set index = index + 1
        endloop
        set depth = depth + 1
    endloop
    set index = 0
    loop
        exitwhen index >= helpfiles
        if closeFile[ index ] and I2R( matchDepth[ index ] ) / depth < 0.5 then
            set closeFile[ index ] = false
            set closeMatches = closeMatches - 1
        endif
        set index = index + 1
    endloop
    if matches > 1 then
        set showString = GREY + "Multiple matches found: "
        set index = 0
        loop
            exitwhen index >= helpfiles
            if inConsideration[ index ] then
                if closeIndex + 1 >= matches then
                    set showString = showString + matchedName[ index ]
                    exitwhen true
                else
                    set showString = showString + LIGHTGREY + matchedName[ index ] + GREY + ", "
                endif
                set closeIndex = closeIndex + 1
            endif
            set index = index + 1
        endloop
        set showString = showString + GREY + ". Please refine your search."
        call DisplayTimedTextToPlayer( trigPlayer, 0, 0, 15, showString )
        set showString = GREY + "Close matches: "
    elseif matches == 1 then
        set showString = GREY + "Close matches: "
        set index = 0
        loop
            exitwhen inConsideration[ index ]
            set index = index + 1
        endloop        
        call DisplayFile( match[ index ], trigPlayer )
    else
        set showString = RED +"No matches found." + GREY + " Close files: "
    endif
   
    if closeMatches > 0 then
        set index = 0
        set closeIndex = 0
        loop
            exitwhen index >= helpfiles
            if closeFile[ index ] then
                if closeIndex + 1 >= closeMatches then
                    set showString = showString + matchedName[ index ]
                    exitwhen true
                else
                    set showString = showString + matchedName[ index ] + GREY + ", "
                endif
                set closeIndex = closeIndex + 1
            endif
            set index = index + 1
        endloop
        call DisplayText( trigPlayer, showString )
    elseif matches == 0 then
        call DisplayText( trigPlayer, showString + RED + "No close files found." )
    endif
endfunction

function ShowHelpfile_Actions takes nothing returns nothing
    local string chatString = GetEventPlayerChatString( )
    local integer stringPos = 0
    local integer length = StringLength( chatString )
    loop
        exitwhen SubString( chatString, stringPos, stringPos + 1 ) == " " or stringPos > length
        set stringPos = stringPos + 1
    endloop
    call DisplayFileByName( SubString( chatString, stringPos + 1, length ), GetTriggerPlayer() )
endfunction

function ShowBase_Actions takes nothing returns nothing
    call DisplayFile( BASE, GetTriggerPlayer() )
endfunction

function Help takes string name, string help, helpfile parent returns helpfile
    return helpfile.create( name, help, parent )
endfunction

struct helpfile
    string name
    string comparename
    string help
    integer subclasses
    integer priority
    helpfile array subclass[ 40 ]
    helpfile parent
    integer relatedfiles
    helpfile array related[ 40 ]

    static method create takes string name, string help, helpfile parent returns helpfile
        local helpfile this = helpfile.allocate()
        local integer index = 0
        local integer correctIndex
        set .help = help
        set .name = StringCase( name, true )
        set .comparename = StringCase( name, false )
        set .subclasses = 0
        set .relatedfiles = 0
        set .priority = Char2I( name, 0, 5 )
        if parent > 0 then
            call parent.addSubclass( this )
            set.parent = parent
        elseif parent == 0 then
            call HELP.addSubclass( this )
            set.parent = HELP
        else
            set.name = "Help command"
            set.parent = 0
        endif
       
        loop
            if index >= helpfiles then
                set SortedFile[ helpfiles ] = this
                exitwhen true
            endif
            if SortedFile[ index ].priority > this.priority then
                set correctIndex = index
                set index = helpfiles - 1
                loop
                    exitwhen index < correctIndex
                    set SortedFile[ index + 1 ] = SortedFile[ index ]
                    set index = index - 1
                endloop
                set SortedFile[ correctIndex ] = this
                exitwhen true
            endif
            set index = index + 1
        endloop
        set helpfiles = helpfiles + 1
        return this
    endmethod

    method addSubclass takes helpfile subclass returns nothing
        local integer index = 0
        local integer correctIndex
        loop
            if index >= .subclasses then
                set .subclass[ .subclasses ] = subclass
                exitwhen true
            elseif .subclass[ index ].priority > subclass.priority then
                set correctIndex = index
                set index = .subclasses - 1
                loop
                    exitwhen index < correctIndex
                    set .subclass[ index + 1 ] = .subclass[ index ]
                    set index = index - 1
                endloop
                set .subclass[ correctIndex ] = subclass
                exitwhen true
            endif
            set index = index + 1
        endloop
        set .subclasses = .subclasses + 1
    endmethod
   
    method getMBString takes helpfile caller, integer depth returns nothing
        local integer index = 1
        local multiboarditem curItem
        local string whitespace = GREY + "  "
        local integer localId = GetPlayerId( LOCAL_PLAYER )
        if caller == .parent then
            set isLast[ depth ] = ( this == .parent.subclass[ .parent.subclasses - 1 ] )
            loop
                exitwhen index >= depth
                if isLast[ index ] then
                    set whitespace = whitespace + "     "
                else
                    set whitespace = whitespace + " |   "
                endif
                set index = index + 1
            endloop
            if depth != 0 then
                set whitespace = whitespace + " |-"
            endif
           
            if this == LastSeen[ localId ] then
                call SetMultiboardItemValue( SortedIndex, Row + 1, Col, whitespace + TURQUOISE + .name, "", 0, LOCAL_PLAYER )
            else
                call SetMultiboardItemValue( SortedIndex, Row + 1, Col, whitespace + LIGHTGREY + .name, "", 0, LOCAL_PLAYER )
            endif

            set Row = Row + 1
            if Row >= MB_MAX_ROWS then
                set Row = 0
                set Col = Col + 1
                call SetMultiboardItemValue( SortedIndex, Row, Col, GOLD + "Helpfile", "", 0, LOCAL_PLAYER )
            endif
            set index = 0
            loop
                exitwhen index >= .subclasses
                call .subclass[ index ].getMBString( this, depth + 1 )
                set index = index + 1
            endloop
        endif
    endmethod
endstruct

private function InitHF takes nothing returns nothing
    local integer playerId = 0
    set BASE = helpfile.create( "", "Incorrect helpfile requested. Enter -help HELP to get help on the help command, or use -help index to show all helpfiles. Case is ignored on all -help commands.", -1 )
    set HELP = helpfile.create( "HELP", "Enter -help NAME to recieve help on NAME. You can also use NAM, NA or N instead of NAME. Case is ignored on all -help commands.\nOther commands: -man , -h , -manual ", BASE )
    set INDEX = helpfile.create( "INDEX", "The index shows all helpfiles. Use -h index to show the index.", BASE )
   

    call TriggerRegisterAnyPlayerChatEvent( ShowBase, "-h",      true )
    call TriggerRegisterAnyPlayerChatEvent( ShowBase, "-help",   true )
    call TriggerRegisterAnyPlayerChatEvent( ShowBase, "-man",    true )
    call TriggerRegisterAnyPlayerChatEvent( ShowBase, "-manual", true )
    call TriggerAddAction( ShowBase, function ShowBase_Actions )
   
    call TriggerRegisterAnyPlayerChatEvent( ShowHelpfile, "-h ",      false )
    call TriggerRegisterAnyPlayerChatEvent( ShowHelpfile, "-help ",   false )
    call TriggerRegisterAnyPlayerChatEvent( ShowHelpfile, "-man ",    false )
    call TriggerRegisterAnyPlayerChatEvent( ShowHelpfile, "-manual ", false )
    call TriggerAddAction( ShowHelpfile, function ShowHelpfile_Actions )
   
   
    set SortedIndex = CreateMultiboard()
    loop
        exitwhen playerId > MAX_PLAYER_SLOT
        set MbDisplay[ playerId ] = false
        set LastSeen[ playerId ] = BASE
        set playerId = playerId + 1
    endloop
    call TimerStart( CreateTimer(), 1.00, false, function GenerateMultiboard  )
endfunction
endlibrary
 
40 0P->0B
30
0
//TESH.scrollpos=-1
//TESH.alwaysfold=0
library BankSys initializer InitBS needs Utilities
// PARAMETERS
globals
    // In seconds
    real YEAR_LENGTH = 45
    // How often bank income will be calculated per year
    constant integer FREQUENCY = 15
    // In percent / 100
    constant real INTEREST_RATE = 1.06
    constant real DEBT_RATE = 0.1
endglobals
// End of Parameters

globals
    integer array BankGold
    integer array BankWealth
    integer array MinBankGold
    player array BankPlayer
    integer array BankPlayerId
    private real array AutoPayIn
    public  integer array LastGold

    private balance array Balance
    private constant timer BankCalc = CreateTimer()
    private constant trigger BankTrigger = CreateTrigger()
    private constant trigger ShowBalance = CreateTrigger()
    private multiboard BalanceMultiboard
    constant integer CHARTTYPE_INCOME = 0
    constant integer CHARTTYPE_EXPENSE = 1
    constant integer TRANSFERTYPE_BANK_BANK = 1
    constant integer TRANSFERTYPE_PLAYER_BANK = 2
    constant integer TRANSFERTYPE_BANK_PLAYER = 3
    constant integer TRANSFERTYPE_PLAYER_PLAYER = 4
    constant integer TRANSFERTYPE_ALL = 5
endglobals

struct balance
    multiboard balance
    balancechart expensechart
    balancechart incomechart
    player owner
    integer total
    integer ownerId
    integer position
    static constant integer length = 10
    static constant timer updater = CreateTimer()
    static balance array BalanceIndex [ 500 ]
    static integer count = 0
   
    static method create takes player owner, multiboard mb returns balance
        local balance this = .allocate()
       
        call MultiboardSetRowCount( mb, .length + 2 )
        call MultiboardSetColumnCount( mb, 6 )
        call MultiboardSetTitleText( mb, GOLD + "Balance" )  
       
        set .count = .count + 1
        set .BalanceIndex[ .count ] = this
        set .position = .count
        set .balance = mb
        set .total = 0
        set .owner = owner
        set .ownerId = GetPlayerId( owner )
       
        call SetMultiboardItemValue( .balance, -1, 4, "", "", 0.03, .owner )
        call SetMultiboardItemValue( .balance, -1, 5, "", "", 0.05, .owner )
        call SetMultiboardItemValue( .balance, 0, 4, GOLD + "Overview", "", 0.05, .owner )
        call SetMultiboardItemValue( .balance, 1, 4, GOLD + "0", "", 0, .owner )
        call SetMultiboardItemValue( .balance, 1, 5, GOLD + "Balance", "", 0, .owner )
        call SetMultiboardItemValue( .balance, 2, 4, GOLD + "0", "", 0, .owner )
        call SetMultiboardItemValue( .balance, 2, 5, GOLD + "Bank", "", 0, .owner )
        call SetMultiboardItemValue( .balance, 3, 4, GREY + "  -  ", "", 0, .owner )
        call SetMultiboardItemValue( .balance, 3, 5, GREY + "    -    ", "", 0, .owner )
        call SetMultiboardItemValue( .balance, 4, 4, GOLD + "0", "", 0, .owner )
        call SetMultiboardItemValue( .balance, 4, 5, GOLD + "Total", "", 0, .owner )
       
       

        set .incomechart = balancechart.create( owner, "Income", mb, 0, CHARTTYPE_INCOME )
        set .expensechart = balancechart.create( owner, "Expense", mb, 2, CHARTTYPE_EXPENSE )
        call MultiboardMinimize( mb, true )
        return this
    endmethod
   
    method updateInterface takes nothing returns nothing
        set .total = .incomechart.total - .expensechart.total
       
        call SetMultiboardItemValue( .balance, 1, 4, GOLD + I2S( .total ), "", 0, .owner )
        call SetMultiboardItemValue( .balance, 2, 4, GOLD + I2S( BankGold[ .ownerId ] ), "", 0, .owner )
        call SetMultiboardItemValue( .balance, 4, 4, GOLD + I2S( BankWealth[ .ownerId ] + GetPlayerState( .owner, PLAYER_STATE_RESOURCE_GOLD ) ), "", 0, .owner )
    endmethod
   
    method onDestroy takes nothing returns nothing
        set .BalanceIndex[ .count ].position = .position
        set .BalanceIndex[ .position ] = .BalanceIndex[ .count ]
        set .BalanceIndex[ .count ] = 0
        call .incomechart.destroy()
        call .expensechart.destroy()
        set .count = .count - 1
    endmethod
   
    static method onInit takes nothing returns nothing
        call TimerStart( .updater, 1, true, function balance.updateBalances )
    endmethod
   
    static method updateBalances takes nothing returns nothing
        local integer i = 1
        local balance this
        loop
            exitwhen i > .count
            set this = .BalanceIndex[ i ]
            call .updateInterface()
            set i = i + 1
        endloop
    endmethod
   
    method updateField takes integer value, string text returns nothing
        if value < 0 then
            call .expensechart.updateField( -value, text )
        elseif value > 0 then
            call .incomechart.updateField( value, text )
        endif
        call .updateInterface()
    endmethod
endstruct

struct balancechart
    multiboard balance
    player owner
    integer array value[ 20 ]
    string array text[ 20 ]
    integer curField
    integer total
    integer length
    integer col
    string color
    string name
   
    static method create takes player owner, string name, multiboard target, integer column, integer charttype returns balancechart
        local balancechart this = balancechart.allocate()
        local integer i = 0
        local multiboarditem curItem
        if charttype == CHARTTYPE_INCOME then
            set .color = GREEN
        else
            set .color = RED
        endif
        set .name = name
        set .owner = owner
        set .col = column
        set .curField = -1
        set .total = 0
        set .balance = target
        set .length = MultiboardGetRowCount( .balance ) - 2
        //  takes multiboard mb, integer row, integer col, string value, string iconfilename, real width, player whichplayer
        call SetMultiboardItemValue( .balance, -1, .col, "", "", 0.03, owner )
        call SetMultiboardItemValue( .balance, -1, .col + 1, "", "", 0.05, owner )
        call SetMultiboardItemValue( .balance, 0, .col, .color + name, "", 0, owner )
        call SetMultiboardItemValue( .balance, .length + 1, .col, GOLD + "0", "", 0, owner )
        call SetMultiboardItemValue( .balance, .length + 1, .col + 1, .color + "Total", "", 0, owner )
       
        loop
            exitwhen i >= .length
            set .value[ i ] = 0
            set .text[ i ] = ""
            set i = i + 1
        endloop
        return this
    endmethod
   
    private method insertField takes integer field, integer value, string text returns nothing
        set .total = .total - .value[ field ] + value
        set .value[ field ] = value
        set .text[ field ] = text
       
        call SetMultiboardItemValue( .balance, .length + 1, .col, GOLD + I2S( .total ), "", 0, .owner )        
        if .value[ field ] == 0 then
            call SetMultiboardItemValue( .balance, field + 1, .col, GOLD + " - ", "", 0, .owner )    
            call SetMultiboardItemValue( .balance, field + 1, .col + 1, "", "", 0, .owner )
        else
            call SetMultiboardItemValue( .balance, field + 1, .col, GOLD + I2S( value ), "", 0, .owner )
            call SetMultiboardItemValue( .balance, field + 1, .col + 1, .color + text, "", 0, .owner )
        endif
    endmethod
   
    method addField takes integer value, string text returns nothing
        set .curField = .curField + 1
        if .curField >= .length then
            set .curField = 0
        endif
        call .insertField( .curField, value, text )
    endmethod
   
    method updateField takes integer value, string text returns nothing
        local integer i = 0
        local integer curField
        loop
            exitwhen i >= .length
            exitwhen .text[ i ] == text
            set i = i + 1
        endloop
        if i >= .length then
            call .addField( value, text )
        else
            call .insertField( i, .value[ i ] + value, text )
        endif
    endmethod
endstruct

struct debtcollector
    integer debt
    integer transfertype
    string transfername
    static constant real interval = 1
    integer debteeId
    integer debitorId
   
    static constant timer collector = CreateTimer()
    static balance array Collector[ 500 ]
    static integer count = 0
    integer position
   
    static method create takes integer debt, player debitor, player debtee, integer transfertype, string transfername returns debtcollector
        local debtcollector this = .allocate()
        set .debt = debt
        set .debitorId = GetPlayerId( debitor )
        set .debteeId = GetPlayerId( debtee )
        set .transfername = transfername
        set .count = .count + 1
        set .position = .count
        set .Collector[ .position ] = this
        return this
    endmethod
   
   method onDestroy takes nothing returns nothing
        set .Collector[ .count ].position = .position
        set .Collector[ .position ] = .Collector[ .count ]
        set .Collector[ .count ] = 0
        set .count = .count - 1
    endmethod
   
    static method onInit takes nothing returns nothing
        call TimerStart( .collector, 1, true, function debtcollector.runCollectors )
    endmethod
   
   
    static method runCollectors takes nothing returns nothing
        local integer i = 1
        local debtcollector this
        loop
            exitwhen i > .count
            set this = .Collector[ i ]
            call .CollectDebts()
            set i = i + 1
        endloop
    endmethod
   
    method CollectDebts takes nothing returns nothing
        set .debt = .debt - Transfer.evaluate( .debt, .debitorId, .debteeId, .transfertype, .transfername )
        if .debt <= 0 then
            call .destroy()
        endif
    endmethod
endstruct

function BankCalc_Actions takes nothing returns nothing
    local integer i = 0
    local integer debt
    local integer paidDebt
    local integer bankGold
    local integer interest
    loop
        exitwhen i > MAX_USER_SLOT
        if Players[ i ] != BankPlayer[ i ] then
            set bankGold = BankGold[ i ]
            if bankGold > 0 then
                set interest = R2I( bankGold * Pow( INTEREST_RATE, 1.0 / FREQUENCY ) + 0.5 ) - bankGold
                call Transfer.evaluate( interest, BankPlayerId[ i ], i, TRANSFERTYPE_ALL, "Bank" )
            elseif bankGold < 0 then
                set debt = - R2I( bankGold * DEBT_RATE / FREQUENCY + 0.5 )
                set debt = debt - Transfer.evaluate( debt, i, BankPlayerId[ i ], TRANSFERTYPE_ALL, "Bank" )

                if debt > 0 then
                    call debtcollector.create( debt, Players[ i ], BankPlayer[ i ], TRANSFERTYPE_ALL, "Bank"   )
                endif
            endif
        endif
        set i = i + 1
    endloop
endfunction

function AddBilance takes integer trigid, integer amount, string transfername returns nothing
    call Balance[ trigid ].updateField( amount, transfername )
endfunction

function BilanceAddValue takes integer trigid, integer amount, string transfername returns nothing
    set LastGold[ trigid ] = LastGold[ trigid ] + amount
    call AddBilance( trigid, amount, transfername )
endfunction

private function TransferA takes integer amount, integer givId, integer getId returns integer
    local integer givGold = GetPlayerState( Players[ givId ], PLAYER_STATE_RESOURCE_GOLD )
    local integer givWealth = GetPlayerState( Players[ givId ], PLAYER_STATE_GOLD_GATHERED )

    local integer bankGivGold = BankGold[ givId ]
    local integer bankGetGold = BankGold[ getId ]
    local integer bankGivWealth = BankWealth[ givId ]
    local integer bankGetWealth = BankWealth[ getId ]
   
    local integer givbankGold
    local integer getbankGold
    local integer givbankWealth
    local integer getbankWealth
   
    local integer playerAmount = amount
    local integer bankAmount = 0
   
    set givGold = givGold - amount
    if givGold < 0 then
        set playerAmount = amount + givGold
        set bankAmount = IMinBJ( -givGold, bankGivGold - MinBankGold[ givId ] )
        set givGold = 0
    endif
    set givWealth = givWealth - playerAmount
    if givWealth < 0 then
        set bankGivWealth = bankGivWealth + givWealth
        set givWealth = 0
    endif
    set amount = playerAmount + bankAmount
    set BankGold[ givId ] = bankGivGold - bankAmount
    set BankGold[ getId ] = bankGetGold + amount
    set BankWealth[ givId ] = bankGivWealth - bankAmount
    set BankWealth[ getId ] = bankGetWealth + amount
   
    set LastGold[ BankPlayerId[ getId ] ] = LastGold[ BankPlayerId[ getId ] ] + amount
    set LastGold[ BankPlayerId[ givId ] ] = LastGold[ BankPlayerId[ givId ] ] - bankAmount
    set LastGold[ givId ] = LastGold[ givId ] - playerAmount
   
    call SetPlayerState( Players[ givId ], PLAYER_STATE_RESOURCE_GOLD, givGold )
    call SetPlayerState( Players[ givId ], PLAYER_STATE_GOLD_GATHERED, givWealth )
   
    set givbankGold = GetPlayerState( BankPlayer[ givId ], PLAYER_STATE_RESOURCE_GOLD )
    call SetPlayerState( BankPlayer[ givId ], PLAYER_STATE_RESOURCE_GOLD, givbankGold - bankAmount )
    set getbankGold = GetPlayerState( BankPlayer[ getId ], PLAYER_STATE_RESOURCE_GOLD )
    call SetPlayerState( BankPlayer[ getId ], PLAYER_STATE_RESOURCE_GOLD, getbankGold + amount )
    set givbankWealth = GetPlayerState( BankPlayer[ givId ], PLAYER_STATE_GOLD_GATHERED )
    call SetPlayerState( BankPlayer[ givId ], PLAYER_STATE_GOLD_GATHERED, givbankWealth - bankAmount )
    set getbankWealth = GetPlayerState( BankPlayer[ getId ], PLAYER_STATE_GOLD_GATHERED )
    call SetPlayerState( BankPlayer[ getId ], PLAYER_STATE_GOLD_GATHERED, getbankWealth + amount )
    return amount
endfunction

private function TransferB_B takes integer amount, integer givId, integer getId returns integer
    local integer givGold = BankGold[ givId ]
    local integer getGold = BankGold[ getId ]
    local integer givWealth = BankWealth[ givId ]
    local integer getWealth = BankWealth[ getId ]
    local integer givbankGold
    local integer getbankGold
    local integer givbankWealth
    local integer getbankWealth

    set amount = IMinBJ( amount, givGold - MinBankGold[ givId ] )
   
    set BankGold[ givId ] = givGold - amount
    set BankGold[ getId ] = getGold + amount
    set BankWealth[ givId ] = givWealth - amount
    set BankWealth[ getId ] = getWealth + amount
   
    set LastGold[ BankPlayerId[ getId ] ] = LastGold[ BankPlayerId[ getId ] ] + amount
    set LastGold[ BankPlayerId[ givId ] ] = LastGold[ BankPlayerId[ givId ] ] - amount
   
    set givbankGold = GetPlayerState( BankPlayer[ givId ], PLAYER_STATE_RESOURCE_GOLD )
    call SetPlayerState( BankPlayer[ givId ], PLAYER_STATE_RESOURCE_GOLD, givbankGold - amount )
    set getbankGold = GetPlayerState( BankPlayer[ getId ], PLAYER_STATE_RESOURCE_GOLD )
    call SetPlayerState( BankPlayer[ getId ], PLAYER_STATE_RESOURCE_GOLD, getbankGold + amount )
    set givbankWealth = GetPlayerState( BankPlayer[ givId ], PLAYER_STATE_GOLD_GATHERED )
    call SetPlayerState( BankPlayer[ givId ], PLAYER_STATE_GOLD_GATHERED, givbankWealth - amount )
    set getbankWealth = GetPlayerState( BankPlayer[ getId ], PLAYER_STATE_GOLD_GATHERED )
    call SetPlayerState( BankPlayer[ getId ], PLAYER_STATE_GOLD_GATHERED, getbankWealth + amount )
    return amount
endfunction

private function TransferP_B takes integer amount, integer givId, integer getId returns integer
    local integer givGold = GetPlayerState( Players[ givId ], PLAYER_STATE_RESOURCE_GOLD )
    local integer getGold = BankGold[ getId ]
    local integer givWealth = GetPlayerState( Players[ givId ], PLAYER_STATE_GOLD_GATHERED )
    local integer getWealth = BankWealth[ getId ]
    local integer getbankGold
    local integer getbankWealth

    set amount = IMinBJ( amount, givGold )
    set givWealth = givWealth - amount
    if givWealth < 0 then
        set BankWealth[ givId ] = BankWealth[ givId ] + givWealth
        set givWealth = 0
    endif
   
    set BankGold[ getId ] = getGold + amount
    set BankWealth[ getId ] = getWealth + amount    
   
    set LastGold[ givId ] = LastGold[ givId ] - amount
    set LastGold[ BankPlayerId[ getId ] ] = LastGold[ BankPlayerId[ getId ] ] + amount
   
    call SetPlayerState( Players[ givId ], PLAYER_STATE_RESOURCE_GOLD, givGold - amount )
    call SetPlayerState( Players[ givId ], PLAYER_STATE_GOLD_GATHERED, givWealth )
   
    set getbankGold = GetPlayerState( BankPlayer[ getId ], PLAYER_STATE_RESOURCE_GOLD )
    call SetPlayerState( BankPlayer[ getId ], PLAYER_STATE_RESOURCE_GOLD, getbankGold + amount )
    set getbankWealth = GetPlayerState( BankPlayer[ getId ], PLAYER_STATE_GOLD_GATHERED )
    call SetPlayerState( BankPlayer[ getId ], PLAYER_STATE_GOLD_GATHERED, getbankWealth + amount )
   
    return amount
endfunction

private function TransferB_P takes integer amount, integer givId, integer getId returns integer
    local integer givGold = BankGold[ givId ]
    local integer getGold = GetPlayerState( Players[ getId ], PLAYER_STATE_RESOURCE_GOLD )
    local integer givWealth = BankWealth[ givId ]
    local integer getWealth = GetPlayerState( Players[ getId ], PLAYER_STATE_GOLD_GATHERED )
    local integer givbankGold
    local integer givbankWealth

    set amount = IMinBJ( amount, givGold - MinBankGold[ givId ] )

    set BankGold[ givId ] = givGold - amount
    set BankWealth[ givId ] = givWealth - amount
   
    set LastGold[ getId ] = LastGold[ getId ] + amount
    set LastGold[ BankPlayerId[ givId ] ] = LastGold[ BankPlayerId[ givId ] ] - amount
   

    call SetPlayerState( Players[ getId ], PLAYER_STATE_RESOURCE_GOLD, getGold + amount )
    call SetPlayerState( Players[ getId ], PLAYER_STATE_GOLD_GATHERED, getWealth + amount )
   
    set givbankGold = GetPlayerState( BankPlayer[ givId ], PLAYER_STATE_RESOURCE_GOLD )
    call SetPlayerState( BankPlayer[ givId ], PLAYER_STATE_RESOURCE_GOLD, givbankGold - amount )
    set givbankWealth = GetPlayerState( BankPlayer[ givId ], PLAYER_STATE_GOLD_GATHERED )
    call SetPlayerState( BankPlayer[ givId ], PLAYER_STATE_GOLD_GATHERED, givbankWealth - amount )
   
    return amount
endfunction

private function TransferP_P takes integer amount, integer givId, integer getId returns integer
    local integer givGold = GetPlayerState( Players[ givId ], PLAYER_STATE_RESOURCE_GOLD )
    local integer getGold = GetPlayerState( Players[ getId ], PLAYER_STATE_RESOURCE_GOLD )
    local integer givWealth = GetPlayerState( Players[ givId ], PLAYER_STATE_GOLD_GATHERED )
    local integer getWealth = GetPlayerState( Players[ getId ], PLAYER_STATE_GOLD_GATHERED )

    set amount = IMinBJ( amount, givGold )
   
    set givWealth = givWealth - amount
    if givWealth < 0 then
        set BankWealth[ givId ] = BankWealth[ givId ] + givWealth
        set givWealth = 0
    endif
   
    set LastGold[ givId ] = LastGold[ givId ] - amount
    set LastGold[ getId ] = LastGold[ getId ] + amount
   
    call SetPlayerState( Players[ givId ], PLAYER_STATE_RESOURCE_GOLD, givGold - amount )
    call SetPlayerState( Players[ getId ], PLAYER_STATE_RESOURCE_GOLD, getGold + amount )
    call SetPlayerState( Players[ givId ], PLAYER_STATE_GOLD_GATHERED, givWealth )
    call SetPlayerState( Players[ getId ], PLAYER_STATE_GOLD_GATHERED, getWealth + amount )
    return amount
endfunction
   
function Transfer takes integer amount, integer givId, integer getId, integer transfertype, string transfername returns integer
    local boolean different = givId != getId
    if amount < 0 then
        if transfertype == TRANSFERTYPE_PLAYER_BANK then
            set transfertype = TRANSFERTYPE_BANK_PLAYER
        elseif transfertype == TRANSFERTYPE_BANK_PLAYER then
            set transfertype = TRANSFERTYPE_PLAYER_BANK
        elseif transfertype == TRANSFERTYPE_ALL then
            set transfertype = TRANSFERTYPE_BANK_PLAYER
        endif
        return Transfer(  -amount, getId, givId, transfertype, transfername )
    elseif amount == 0 then
        return 0
    endif
   
    if transfertype == TRANSFERTYPE_BANK_BANK and different then
        set amount = TransferB_B( amount, givId, getId )
    elseif transfertype == TRANSFERTYPE_PLAYER_BANK then
        set amount = TransferP_B( amount, givId, getId )
    elseif transfertype == TRANSFERTYPE_BANK_PLAYER then
        set amount = TransferB_P( amount, givId, getId )
    elseif transfertype == TRANSFERTYPE_PLAYER_PLAYER and different then
        set amount = TransferP_P( amount, givId, getId )
    elseif transfertype == TRANSFERTYPE_ALL and different then
        set amount = TransferA( amount, givId, getId )
    else
        return 0
    endif
   
    if different then
        call AddBilance( getId, amount, transfername )
        call AddBilance( givId, -amount, transfername )
    endif
   
    return amount
endfunction

function AddGold takes integer amount, integer getId, integer transfertype, string transfername returns nothing
    //! runtextmacro ChangePlayerState( "Players[ bj_PLAYER_NEUTRAL_EXTRA ]", "RESOURCE_GOLD", "amount" )
    //! runtextmacro ChangePlayerState( "Players[ bj_PLAYER_NEUTRAL_EXTRA ]", "GOLD_GATHERED", "amount" )
    call Transfer( amount, bj_PLAYER_NEUTRAL_EXTRA, getId, transfertype, transfername )
endfunction

function BankTrigger_Actions takes nothing returns nothing
    local player trigPlayer = GetTriggerPlayer()
    local integer amount = S2I( SubString( GetEventPlayerChatString(), 2, 11 ) )
    local integer trigId = GetPlayerId( trigPlayer )
    local string direction
    if amount > 0 then
        set direction = " to "
    else
        set direction = " from "
    endif

    set amount = Transfer( amount, trigId, trigId, TRANSFERTYPE_PLAYER_BANK, " - " )  
    call DisplayText( trigPlayer, GREEN + "Transferred " + GOLD + I2S( amount ) + GREEN + direction + "your account (" + GOLD + I2S( BankGold[ trigId ] ) + GREEN + ")." )
   
endfunction

function SetPlayerBank takes player whichplayer, player bankplayer returns nothing
    local integer i = GetPlayerId( whichplayer )
    set BankPlayer[ i ] = bankplayer
    set BankPlayerId[ i ] = GetPlayerId( bankplayer )
endfunction

private function AutoPayIn_Actions takes nothing returns nothing
    local integer i = 0
    local integer gold
    local integer income
    loop
        exitwhen i > MAX_USER_SLOT
        if Players[ i ] != BankPlayer[ i ] then
            set gold = GetPlayerState( Players[ i ], PLAYER_STATE_RESOURCE_GOLD )
            set income = gold - LastGold[ i ]
            if income > 0 then
                call Balance[ i ].updateField( income, "Earnings" )
            else
                call Balance[ i ].updateField( income, "Expenses" )
            endif
            set LastGold[ i ] = gold
        endif
        set i = i + 1
    endloop
endfunction

private function InitBalance takes nothing returns nothing
    local integer i = 0
   
    loop
        exitwhen i > MAX_PLAYER_SLOT
        set Balance[ i ] = balance.create( Players[ i ], BalanceMultiboard )    
        set i = i + 1
    endloop
   
    call MultiboardDisplaySJ( BalanceMultiboard, true, null )
    call TimerStart( GetExpiredTimer(), 0.15, true, function AutoPayIn_Actions )
endfunction

private function ShowBalance_Actions takes nothing returns nothing
    local player trigPlayer = GetTriggerPlayer()
    local string eventString = StringCase( GetEventPlayerChatString(), false )
    local string subString = SubString( eventString, 9, 14 )
    local boolean show
    if eventString == "-balance" then
        set show = not IsMultiboardDisplayed( BalanceMultiboard )
    else
        set show = subString == "on"
        call DisplayText( LOCAL_PLAYER, subString )
    endif
    call MultiboardDisplaySJ( BalanceMultiboard, show, trigPlayer )
endfunction

private function InitBS takes nothing returns nothing
    local integer i = 0
    set BalanceMultiboard = CreateMultiboard()
   
    loop
        exitwhen i > MAX_PLAYER_SLOT
        set AutoPayIn[ i ] = 0.5
        set LastGold[ i ] = 0
        set BankGold[ i ] = 0
        set BankWealth[ i ] = 0
        set BankPlayer[ i ] = Players[ i ]
        set BankPlayerId[ i ] = i
        set MinBankGold[ i ] = 0
        set Balance[ i ] = balance.create( Players[ i ], BalanceMultiboard )    
        set i = i + 1
    endloop
   
    call TimerStart( BankCalc, YEAR_LENGTH / FREQUENCY, true, function BankCalc_Actions )    
    call TimerStart( CreateTimer(), .05, false, function InitBalance )
   
    call TriggerRegisterAnyPlayerChatEvent( ShowBalance, "-balance off",  true )
    call TriggerRegisterAnyPlayerChatEvent( ShowBalance, "-balance on",   true )
    call TriggerRegisterAnyPlayerChatEvent( ShowBalance, "-balance",      true )
   
    call TriggerAddAction( ShowBalance, function ShowBalance_Actions )
endfunction
endlibrary
//TESH.scrollpos=-1
//TESH.alwaysfold=0


library TaxSys initializer InitTaxSys needs Utilities, BankSys, TeamSys
// PARAMETERS
// returns the taxes depending on the income
function IncomeTaxes takes integer income returns integer
    if income > 20 * YEAR_LENGTH then
        return R2I( 0.2 * income )
    elseif income > 8 * YEAR_LENGTH then
        return R2I( ( ( income - 8.0 * YEAR_LENGTH ) / ( 120 * YEAR_LENGTH ) + 0.1 ) * income  )
    elseif income > 4 * YEAR_LENGTH then
        return R2I( income * 0.1 )
    endif
    return 0
endfunction

// returns the taxes depending on the total gold
function WealthTaxes takes integer wealth returns integer
    return R2I( 0.0044 * wealth +0.5 )
endfunction

// End of parameters





globals
    private player array TaxCollector
    private integer array TaxCollectorId
    public  integer array LastMoney
    private constant timer TaxCollectTimer = CreateTimer()
    private constant timerdialog CollectWindow = CreateTimerDialog( TaxCollectTimer )
    private integer IncomeTime = 0
endglobals

function CreateTaxCollector takes integer taxes, player target returns nothing
    local integer trigId = GetPlayerId( target )
    call debtcollector.create( taxes, target, TaxCollector[ trigId ], TRANSFERTYPE_ALL, "State" )
endfunction

function TaxCollectTimer_Actions takes nothing returns nothing
    local integer i = 0
    local integer gold
    local integer wealth
    local integer income
    local integer taxes
    local integer paidTaxes
    local integer array empireGold
    local integer teamId
    set IncomeTime = IncomeTime + 1
    set empireGold[ 0 ] = 150 + IncomeTime * ( 25 - 4 * GetTeamPlayersSJ( 0 ) )
    set empireGold[ 1 ] = 150 + IncomeTime * ( 25 - 4 * GetTeamPlayersSJ( 1 ) )
   
    loop
        exitwhen i > MAX_USER_SLOT
        if Players[ i ] != TaxCollector[ i ] then
            set teamId = Team[i].id
            set empireGold[ i ] = empireGold[ teamId ]
            call Transfer( empireGold[ i ], TaxCollectorId[ i ], i, TRANSFERTYPE_PLAYER_PLAYER, "Empire" )
            set wealth = GetPlayerState( Players[ i ], PLAYER_STATE_GOLD_GATHERED ) + BankWealth[ i ]
            set gold   = GetPlayerState( Players[ i ], PLAYER_STATE_RESOURCE_GOLD )

            set income = wealth - LastMoney[ i ]
            set taxes  = IncomeTaxes( income ) + WealthTaxes( wealth )
           
            set taxes = IMinBJ( taxes, empireGold[ i ] )
           
            set paidTaxes = Transfer( taxes, i, TaxCollectorId[ i ], TRANSFERTYPE_PLAYER_PLAYER, "Taxes" )
           
            if ShowMessages[ i ] then
                call DisplayTimedTextToPlayer( Players[ i ], 0, 0, 15, LIGHTGREY + "You recieved " + GOLD + I2S( empireGold[ i ] - paidTaxes ) + LIGHTGREY + " gold from your Empire!" )
            endif
           
            set LastMoney[ i ] = wealth - paidTaxes
        endif
        set i = i + 1
    endloop
    set YEAR_LENGTH = GetRandomInt( 40, 60 )
    call TimerStart( GetExpiredTimer(), YEAR_LENGTH, true, function TaxCollectTimer_Actions )
endfunction

function SetPlayerTaxCollector takes player whichplayer, player collector returns nothing
    local integer i = GetPlayerId( whichplayer )
    set TaxCollector[ i ] = collector
    set TaxCollectorId[ i ] = GetPlayerId( collector )
endfunction

function Init_TaxCollector takes nothing returns nothing
    call TimerStart( TaxCollectTimer, YEAR_LENGTH, true, function TaxCollectTimer_Actions )
    call TimerDialogSetTitle( CollectWindow, GOLD + "Empire Gold" )
    call TimerDialogDisplay( CollectWindow, true )
   
endfunction

private function InitTaxSys takes nothing returns nothing
    local integer i = 0
    local timerdialog t
    loop
        exitwhen i > MAX_USER_SLOT
        set TaxCollector[ i ] = Players[ i ]
        set TaxCollectorId[ i ] = i
        set LastMoney[ i ] = 0
        set i = i + 1
    endloop
    call TimerStart( TaxCollectTimer, 0.08, true, function Init_TaxCollector )
endfunction
endlibrary

 
//TESH.scrollpos=0
//TESH.alwaysfold=0

library StatController initializer StatInit needs Utilities, AntarcticaMapInit, CostAttacherUnit, MaxCargoAttacherUnit //, CargoAttacherUnit
globals
    private constant trigger       StatsControl = CreateTrigger()
endglobals

private function StatsControl_Actions takes nothing returns nothing
    local integer playerId   = MaxAIPlayerId + 1
    local integer level
    local unit curHero
    local real pointValue

    loop
        exitwhen playerId > NUMUSERS
        if PlayerActive[ playerId ] and Hero[ playerId ] != null then
            set curHero = Hero[ playerId ]
            set level = GetUnitLevel( curHero )
            set pointValue = ( GetUnitCost( curHero ) + 500 ) * ( GetUnitState( curHero, UNIT_STATE_MAX_LIFE ) + 400 )
            call SetHeroStr( curHero, GetUnitMaxCargo( curHero ) - GetUnitCargo( curHero ), true )
            call SetHeroAgi( curHero, R2I( GetUnitMoveSpeed( curHero )), true )
            call SetHeroInt( curHero, R2I( Pow( pointValue * (level + 5 )  / 45000, 0.65 )+ 150 ), true )
        endif        
        set playerId = playerId + 1
    endloop
    set curHero = null
endfunction

private function StatInit takes nothing returns nothing
    call TriggerRegisterTimerEvent( StatsControl , 1 , true )
    call TriggerAddAction         ( StatsControl , function StatsControl_Actions )
    call StatsControl_Actions     ( )
endfunction
endlibrary
//TESH.scrollpos=38
//TESH.alwaysfold=0
///// VER 00

library Zoomer initializer InitZoom needs Utilities
globals
    private          real    array Distance
    private constant real          NearDistance  = 1600
    private constant real          MidDistance   = 2200
    private constant real          FarDistance   = 3000          
    private constant trigger       BackZoomer    = CreateTrigger()
    private constant trigger       Zoomer        = CreateTrigger()
    private constant trigger       ZoomNear      = CreateTrigger()
    private constant trigger       ZoomFar       = CreateTrigger()
    private constant trigger       ZoomMid       = CreateTrigger()
    private constant real          sj_DISTTOFARZ = 3
endglobals

private function Zoomer_Actions takes nothing returns nothing
    local player  trigPlayer   = GetTriggerPlayer()
    local integer trigPlayerId = GetPlayerId( trigPlayer )
    local real    distance     = S2I( SubString( GetEventPlayerChatString(),  5,  10 ) )
    local real    delta        = distance - Distance[ trigPlayerId ]
    if distance > NearDistance then
        if distance < FarDistance then
            set Distance[ trigPlayerId ] = distance
        else
            set Distance[ trigPlayerId ] = FarDistance
        endif
    else
        set Distance[ trigPlayerId ] = NearDistance
    endif
    if GetLocalPlayer() == trigPlayer then
        if delta > 0 then
            call SetCameraField( CAMERA_FIELD_FARZ,             sj_DISTTOFARZ * Distance[ trigPlayerId ],  0 )
            call SetCameraField( CAMERA_FIELD_TARGET_DISTANCE,                  Distance[ trigPlayerId ],  2 )
        else                                                                                      
            call SetCameraField( CAMERA_FIELD_TARGET_DISTANCE,                  Distance[ trigPlayerId ],  2 )
            call SetCameraField( CAMERA_FIELD_FARZ,             sj_DISTTOFARZ * Distance[ trigPlayerId ],  4 )
        endif
    endif
endfunction

private function ZoomNear_Actions takes nothing returns nothing
    local player  trigPlayer   = GetTriggerPlayer()
    local integer trigPlayerId = GetPlayerId( trigPlayer )

    set Distance[ trigPlayerId ] = NearDistance
   
    if GetLocalPlayer() == trigPlayer then                                                                                      
        call SetCameraField( CAMERA_FIELD_TARGET_DISTANCE,                  NearDistance,  2 )
        call SetCameraField( CAMERA_FIELD_FARZ,             sj_DISTTOFARZ * NearDistance,  4 )
    endif

endfunction

private function ZoomMid_Actions takes nothing returns nothing
    local player  trigPlayer   = GetTriggerPlayer()
    local integer trigPlayerId = GetPlayerId( trigPlayer )
    local real    delta        = MidDistance - Distance[ trigPlayerId ]
   
    set Distance[ trigPlayerId ] = MidDistance
   
    if GetLocalPlayer() == trigPlayer then
        if delta > 0 then
            call SetCameraField( CAMERA_FIELD_FARZ,             sj_DISTTOFARZ * MidDistance,  0 )
            call SetCameraField( CAMERA_FIELD_TARGET_DISTANCE,                  MidDistance,  2 )
        else                                                                                      
            call SetCameraField( CAMERA_FIELD_TARGET_DISTANCE,                  MidDistance,  2 )
            call SetCameraField( CAMERA_FIELD_FARZ,             sj_DISTTOFARZ * MidDistance,  4 )
        endif
    endif
endfunction

private function ZoomFar_Actions takes nothing returns nothing
    local player  trigPlayer   = GetTriggerPlayer()
    local integer trigPlayerId = GetPlayerId( trigPlayer )

    set Distance[ trigPlayerId ] = FarDistance
   
    if GetLocalPlayer() == trigPlayer then                                                                                      
        call SetCameraField( CAMERA_FIELD_FARZ,             sj_DISTTOFARZ * FarDistance,  0 )
        call SetCameraField( CAMERA_FIELD_TARGET_DISTANCE,                  FarDistance,  2 )
    endif
endfunction

private function BackZoomer_Actions takes nothing returns nothing
    local integer playerId = 0
    local player  localPlayer = GetLocalPlayer()
    loop
        exitwhen playerId > NUMPLAYERS
        if localPlayer == Players[ playerId ] then
            call SetCameraField( CAMERA_FIELD_FARZ,             sj_DISTTOFARZ * Distance[ playerId ],  0 )
            call SetCameraField( CAMERA_FIELD_TARGET_DISTANCE,                  Distance[ playerId ],  2 )
        endif
        set playerId = playerId + 1
    endloop
endfunction

       

       
private function InitZoom takes nothing returns nothing
    local integer playerId = 0
    loop
        exitwhen playerId > NUMPLAYERS
        set Distance[ playerId ] = NearDistance
        call TriggerRegisterPlayerChatEvent( Zoomer,   Players[ playerId ], "-zoom",    false )
        call TriggerRegisterPlayerChatEvent( Zoomer,   Players[ playerId ], "-view",    false )
       
        call TriggerRegisterPlayerChatEvent( ZoomNear, Players[ playerId ], "-near",    true  )
        call TriggerRegisterPlayerChatEvent( ZoomNear, Players[ playerId ], "-n",       true  )
       
        call TriggerRegisterPlayerChatEvent( ZoomMid,  Players[ playerId ], "-default", true  )
        call TriggerRegisterPlayerChatEvent( ZoomMid,  Players[ playerId ], "-medium",  true  )
        call TriggerRegisterPlayerChatEvent( ZoomMid,  Players[ playerId ], "-mid",     true  )
        call TriggerRegisterPlayerChatEvent( ZoomMid,  Players[ playerId ], "-m",       true  )
        call TriggerRegisterPlayerChatEvent( ZoomMid,  Players[ playerId ], "-normal",  true  )
       
        call TriggerRegisterPlayerChatEvent( ZoomFar,  Players[ playerId ], "-far",     true  )
        call TriggerRegisterPlayerChatEvent( ZoomFar,  Players[ playerId ], "-f",       true  )
        call TriggerRegisterPlayerChatEvent( ZoomFar,  Players[ playerId ], "-peon",    true  )
        call TriggerRegisterPlayerChatEvent( ZoomFar,  Players[ playerId ], "-s",       true  )
        call TriggerRegisterPlayerChatEvent( ZoomFar,  Players[ playerId ], "-d",       true  )
        set playerId = playerId + 1
    endloop
    call TriggerAddAction( Zoomer,    function Zoomer_Actions   )
    call TriggerAddAction( ZoomNear,  function ZoomNear_Actions )
    call TriggerAddAction( ZoomMid,   function ZoomMid_Actions  )
    call TriggerAddAction( ZoomFar,   function ZoomFar_Actions  )
   
    call TriggerRegisterTimerEvent( BackZoomer, 1, true )
    call TriggerAddAction         ( BackZoomer, function BackZoomer_Actions )
     
endfunction
endlibrary    



 
//TESH.scrollpos=15
//TESH.alwaysfold=0
///// VER 08

library RevivalSystem needs Utilities, AntarcticaMapInit, NewWeap
globals
    private constant trigger           Reviver = CreateTrigger()
    private          timer       array DeathTimer
    private          timerdialog array DeathTimerWindow
endglobals

function Reviver_Actions takes nothing returns nothing
    local unit    hero         = GetTriggerUnit (      )
    local player  trigPlayer   = GetOwningPlayer( hero )
    local integer trigPlayerId = GetPlayerId    ( trigPlayer   )
    local string  trigName     = PlayerName     [ trigPlayerId ]
    local player  killPlayer   = GetOwningPlayer( GetKillingUnit( ) )
    local integer killPlayerId = GetPlayerId    ( killPlayer )
    local string  killName     = PlayerName     [ killPlayerId ]
    local player  localPlayer  = GetLocalPlayer (      )
    local real    trigX        = GetUnitX       ( hero )
    local real    trigY        = GetUnitY       ( hero )
   
    local integer reviveLevel  = GetHeroLevel   ( hero )
    local real    reviveTime
    local integer teamId       = Team[ trigPlayerId ].id
    local boolean inTeam1      = teamId == SouthTeamId
    local integer bounty       = GetHeroInt( hero , true )
   
    set Deaths[ trigPlayerId ] = Deaths[ trigPlayerId ] + 1
    set Kills [ killPlayerId ] = Kills [ killPlayerId ] + 1
   
    if killPlayerId >= 2 then
        set Kills [ teamId ] = Kills [ teamId ] + 1
    endif
    if trigPlayerId >= 2 then
        set Deaths[ teamId ] = Deaths[ teamId ] + 1
        call PausePlayerWeapons( trigPlayer, true )
    endif
   
    call CreateBountyText( bounty, hero, killPlayer )
    call AddGold( bounty, killPlayerId, TRANSFERTYPE_PLAYER_PLAYER, "Kills" )
   
    set reviveTime = SquareRoot( GetUnitState( hero, UNIT_STATE_MAX_LIFE ) / 1000.0 ) * reviveLevel * SquareRoot( SquareRoot( ( Kills[ trigPlayerId ] + GetRandomReal( 4, 6 ) ) / ( Deaths[ trigPlayerId ] + GetRandomReal( 3, 7 ) ) ) ) + 6
   
    if localPlayer == trigPlayer then
        call DisplayTimedTextToPlayer( trigPlayer, 0, 0, 15, RED + "Your ship has been sunk by " + killName + RED + ". Repair complete in " + I2S( R2I( reviveTime ) ) + " seconds." )
        call SetCameraQuickPosition  ( trigX, trigY )
    elseif IsPlayerAlly( localPlayer , trigPlayer ) then
        call DisplayTimedTextToPlayer( localPlayer, 0, 0, 15, RED + trigName + RED +  " has been sunk by " + killName + RED + ".")
    else        
        call DisplayTimedTextToPlayer( localPlayer, 0, 0, 15, GREEN + trigName + GREEN +" has been sunk by " + killName + GREEN + "." )
    endif
    call PingMinimap            ( trigX, trigY, 4 )
    if inTeam1 then                                                              
        call TimerDialogSetTitle( DeathTimerWindow[ trigPlayerId ], PlayerColor[ 0 ] + PlayerName[ trigPlayerId ] )
    else                                                                                                            
        call TimerDialogSetTitle( DeathTimerWindow[ trigPlayerId ], PlayerColor[ 1 ] + PlayerName[ trigPlayerId ] )
    endif
   
    call TimerStart        ( DeathTimer[ trigPlayerId ] , reviveTime , false , null )
    call TimerDialogDisplay( DeathTimerWindow[ trigPlayerId ] , true )
   
    call TriggerSleepAction( reviveTime - .3 )
   
    if localPlayer == trigPlayer then
        call PanCameraToTimed      ( StartLocX[ trigPlayerId ] , StartLocY[ trigPlayerId ] , .3 )
        call SetCameraQuickPosition( StartLocX[ trigPlayerId ] , StartLocY[ trigPlayerId ] )
        call PingMinimap           ( StartLocX[ trigPlayerId ] , StartLocY[ trigPlayerId ] , 4 )
        call ClearSelection        (    )
    endif
       
    call ReviveHero( hero , StartLocX[ trigPlayerId ] , StartLocY[ trigPlayerId ] , true )
   
    if inTeam1 then
        call SetUnitFacing( hero ,  90 )
    else
        call SetUnitFacing( hero , 270 )
    endif
   
    if PlayerUpgrades[ trigPlayerId ] == 0 then
        call PausePlayerWeapons( trigPlayer, false )
    endif
       
    if localPlayer == trigPlayer then
        call SelectUnit( hero , true )
    endif
    call TimerDialogDisplay( DeathTimerWindow[ trigPlayerId ] , false )
    set hero = null
endfunction

function RegisterHeroRevive takes unit torevive returns nothing
    call TriggerRegisterUnitEvent( Reviver, torevive, EVENT_UNIT_DEATH )
endfunction


function InitRevivalSystem takes nothing returns nothing
    local integer playerId = MaxAIPlayerId
    loop
        exitwhen playerId > MaxTeam1PlayerId
        call RegisterHeroRevive( Hero[ playerId ] )
        set DeathTimer      [ playerId ] = CreateTimer      (            )
        set DeathTimerWindow[ playerId ] = CreateTimerDialog( DeathTimer[ playerId ] )
        call TimerDialogDisplay ( DeathTimerWindow[ playerId ] , false )
        set playerId = playerId + 1
    endloop
   
    loop
        exitwhen playerId > MaxTeam2PlayerId
        call RegisterHeroRevive( Hero[ playerId ] )
        set DeathTimer      [ playerId ] = CreateTimer      (            )
        set DeathTimerWindow[ playerId ] = CreateTimerDialog( DeathTimer[ playerId ] )
        call TimerDialogDisplay ( DeathTimerWindow[ playerId ] , false )
        call TimerDialogSetTitle( DeathTimerWindow[ playerId ] , PlayerColor[ 1 ] + PlayerName[ playerId ] )
        set playerId = playerId + 1
    endloop
    call TriggerAddAction( Reviver , function Reviver_Actions )
endfunction
endlibrary
//TESH.scrollpos=55
//TESH.alwaysfold=0
library TeamSys
globals
    team array Team
endglobals

struct team
    integer id
    integer empireId
    integer numPlayers
    force   members
    static team array self
    static method create takes integer id, integer empireId returns team
        local team this = .allocate()
        set .self[ id ] = this
        set .id = id
        set .empireId = empireId
        set .members = CreateForce()
        call .addPlayer( Players[ empireId ] )
        return this
    endmethod
   
    method addPlayer takes player toAdd returns nothing
        local integer playerId = GetPlayerId( toAdd )
        if Team[ playerId ] != 0 then
            call Team[ playerId ].removePlayer( toAdd )
        endif
        if not ( Team[ playerId ] == this ) then
            set .numPlayers = .numPlayers + 1
            call ForceAddPlayer( .members, toAdd )
            set Team[ playerId ] = this
        endif
    endmethod
   
    method removePlayer takes player toremove returns nothing
        if IsPlayerInForce( toremove, .members ) then
            set .numPlayers = .numPlayers - 1
            call ForceRemovePlayer( .members, toremove )
            set Team[ GetPlayerId( toremove ) ] = 0
            if .numPlayers == 0 then
                call .destroy()
            endif
        endif
    endmethod
   
    private method onDestroy takes nothing returns nothing
        call DestroyForce( .members )
        set .members = null
        set .self[ .id ] = 0
    endmethod
endstruct

function TeamRemovePlayerSJ takes integer teamid, player toremove returns nothing
    if team.self[ teamid ] != 0 then
        call team.self[ teamid ].removePlayer( toremove )
    endif
endfunction

function SetPlayerTeamSJ takes player whichplayer, integer teamid returns nothing
    local integer whichPlayerId = GetPlayerId( whichplayer )
    if team.self[ teamid ] == 0 then
        call team.create( teamid, whichPlayerId )
    else
        call team.self[ teamid ].addPlayer( whichplayer )
    endif
endfunction

function GetPlayerTeamSJ takes player whichplayer returns integer
    local integer whichPlayerId = GetPlayerId( whichplayer )
    return Team[ whichPlayerId ].id
endfunction

function GetPlayerForceSJ takes player whichplayer returns force
    local integer whichPlayerId = GetPlayerId( whichplayer )
    return Team[ whichPlayerId ].members
endfunction

function GetTeamForceSJ takes integer teamid returns force
    return team.self[ teamid ].members
endfunction

function GetTeamPlayersSJ takes integer teamid returns integer
    return team.self[ teamid ].numPlayers
endfunction

function SetTeamEmpireSJ takes integer teamid, player empire returns nothing
    call SetPlayerTeamSJ( empire, teamid )
    set team.self[ teamid ].empireId = GetPlayerId( empire )
endfunction

function GetPlayerEmpireSJ takes player whichplayer returns player
    local integer whichPlayerId = GetPlayerId( whichplayer )
    if Team[ whichPlayerId ] == 0 then
        return whichplayer
    else
        return Players[ Team[ whichPlayerId ].empireId ]
    endif
endfunction
endlibrary
//TESH.scrollpos=31
//TESH.alwaysfold=0
//! runtextmacro Attach( "NamePlayer", "string", "player", "null" )

library Name2Player initializer INIT needs Utilities
function SavePlayerName takes player whichplayer returns nothing
    set NamePlayer[ StringCase( PlayerNameUncolored[ GetPlayerId( whichplayer ) ], false ) ] = whichplayer
endfunction

private function INIT takes nothing returns nothing
    local integer i = 0
    loop
        exitwhen i > MAX_PLAYER_SLOT
        call SavePlayerName( Players[ i ] )
        set i = i + 1
    endloop
endfunction
endlibrary


library Kick initializer INIT needs Utilities

globals
    private boolean Kick_Enabled
    private integer Votes_Yes
    private integer Votes
    private integer array Vote
    private constant timer VoteTimer = CreateTimer()
    private constant integer VOTE_NONE = -1
    private constant integer VOTE_NO   =  0
    private constant integer VOTE_YES  =  1

endglobals

function KickPlayer takes player whichplayer, string msg returns nothing
    call ClearLeaver.evaluate( whichplayer, false  )
    call WinGame( whichplayer, false, RED + "You have been kicked." )
    if msg != "" then
        call DisplayText( LOCAL_PLAYER, PlayerName[ GetPlayerId( whichplayer ) ] + msg )
    endif
endfunction

private function Vote_Actions takes nothing returns nothing
    local integer trigId = GetPlayerId( GetTriggerPlayer() )
    local string trigString = StringCase( SubString( GetEventPlayerChatString(), 1, 4 ), false )

    if Vote[ trigId ] == VOTE_NONE then
        set Votes = Votes + 1
    elseif Vote[ trigId ] == VOTE_YES then
        set Votes_Yes = Votes_Yes - 1
    endif
    if trigString == "yes" then
        set Vote[ trigId ] = VOTE_YES
        set Votes_Yes = Votes_Yes + 1
    elseif trigString == "no" then
        set Vote[ trigId ] = VOTE_NO
    endif
endfunction

private function KickTrigger_Actions takes nothing returns nothing
    local player toKick
    local string eventString = StringCase( GetEventPlayerChatString(), false )
    local integer i = 1
    local string array parameter
    local integer array stringPos
    local integer lastPos = 1
    local integer parameters = 0
    local integer len = StringLength( eventString )
    loop
        exitwhen i > len
        if SubString( eventString, i, i + 1 ) == " " then
            set parameter[ parameters ] = SubString( eventString, lastPos, i )
            set stringPos[ parameters ] = lastPos
            set parameters = parameters + 1
            set stringPos[ parameters ] = i
            set lastPos = i + 1
            set i = lastPos
        else
            set i = i + 1
        endif
    endloop

endfunction

private function INIT takes nothing returns nothing
endfunction

endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0

//! runtextmacro Attach( "DialogOwnerId", "Dialog", "integer", "0" )

library GetPlayerFeedback initializer INIT needs Utilities, Dialogs
globals
    public boolean array ReturnVal
    private Dialog array FeedbackDialog
endglobals

function AskPlayerFeedback takes player whichPlayer, string question, code execute returns nothing
    local integer i = GetPlayerId( whichPlayer )
    call FeedbackDialog[i].SetMessage( GOLD + question )
    call FeedbackDialog[i].AddAction( execute )
    call FeedbackDialog[i].Show( whichPlayer )
    set  ReturnVal[i] = false
endfunction

private function Feedback_Check takes nothing returns boolean
    local Dialog id = GetTriggerDialog()
    local integer i = DialogOwnerId[id]
    set   ReturnVal[i] = id.GetResult() == HK_A
    call id.Hide( Players[i] )
    return true
endfunction

function GetPlayerFeedback takes player whichPlayer returns boolean
    return ReturnVal[ GetPlayerId( whichPlayer ) ]
endfunction

private function INIT takes nothing returns nothing
    local integer i = 0
    local boolexpr condFunc = Condition( function Feedback_Check )
    loop
        exitwhen i > MAX_USER_SLOT
        set FeedbackDialog[i] = Dialog.create()
        set DialogOwnerId[ FeedbackDialog[i] ] = i
        call FeedbackDialog[i].AddButton( GOLD + "A" + GREEN + "ccept", HK_A )
        call FeedbackDialog[i].AddButton( GOLD + "C" + RED + "ancel", HK_C )
        call FeedbackDialog[i].AddCondition( condFunc)
        set i = i + 1
    endloop
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library Attacher needs Hash
//! textmacro Attach takes NAME, ATTACHTYPE, ATTACHEDTYPE, DEFAULT

library_once $ATTACHTYPE$Converter
    function $ATTACHTYPE$2IntConverter takes $ATTACHTYPE$ which returns integer
        return which
        return 0
    endfunction
endlibrary

library $NAME$ initializer INIT needs $ATTACHTYPE$Converter, Hash
   
globals
    private $ATTACHEDTYPE$ DefaultAttachment
    private $ATTACHTYPE$ array Check
    private $ATTACHEDTYPE$ array Attachment
    private hashtable Table
endglobals



function SetDefault$NAME$ takes $ATTACHEDTYPE$ attachment returns nothing
    set DefaultAttachment = attachment
endfunction

function GetDefault$NAME$ takes nothing returns $ATTACHEDTYPE$
    return DefaultAttachment
endfunction

function Set$NAME$ takes $ATTACHTYPE$ which, $ATTACHEDTYPE$ attachment returns nothing
    local integer id = $ATTACHTYPE$2IntConverter( which )
    local integer index = Table.Search( id )
    if index == -1 then
        set index = Table.Hash( id )
        set Check[ index ] = which
    endif
    set Check[ index ] = which
    set Attachment[ index ] = attachment
endfunction

function Get$NAME$ takes $ATTACHTYPE$ which returns $ATTACHEDTYPE$
    local integer id = $ATTACHTYPE$2IntConverter( which )
    local integer index = Table.Search( id )
    if index == -1 then
        return GetDefault$NAME$()
    endif
   
    if Check[ index ] != which then
        set Check[ index ] = which
        set Attachment[ index ] = GetDefault$NAME$()
    endif
   
    return Attachment[ index ]
endfunction


private struct $NAME$Struct
    method operator [] takes $ATTACHTYPE$ index returns $ATTACHEDTYPE$
        return Get$NAME$( index )
    endmethod
   
    method operator []= takes $ATTACHTYPE$ index, $ATTACHEDTYPE$ value returns nothing
        call Set$NAME$( index, value )
    endmethod
endstruct

globals
    $NAME$Struct $NAME$
endglobals

private function INIT takes nothing returns nothing
    set $NAME$ = $NAME$Struct.create()
    set Table = hashtable.create()
    set DefaultAttachment = $DEFAULT$
endfunction



endlibrary
//! endtextmacro
endlibrary
//TESH.scrollpos=100
//TESH.alwaysfold=0
//! runtextmacro Attach( "DialogStruct", "dialog", "Dialog", "0" )
library Dialogs needs DialogStruct

globals
        // Dialog button hotkey constants
        constant integer HK_ESC = 512
   
        constant integer HK_0 = 48
        constant integer HK_1 = 49
        constant integer HK_2 = 50
        constant integer HK_3 = 51
        constant integer HK_4 = 52
        constant integer HK_5 = 53
        constant integer HK_6 = 54
        constant integer HK_7 = 55
        constant integer HK_8 = 56
        constant integer HK_9 = 57
       
        constant integer HK_A = 65
        constant integer HK_B = 66
        constant integer HK_C = 67
        constant integer HK_D = 68
        constant integer HK_E = 69
        constant integer HK_F = 70
        constant integer HK_G = 71
        constant integer HK_H = 72
        constant integer HK_I = 73
        constant integer HK_J = 74
        constant integer HK_K = 75
        constant integer HK_L = 76
        constant integer HK_M = 77
        constant integer HK_N = 78
        constant integer HK_O = 79
        constant integer HK_P = 80
        constant integer HK_Q = 81
        constant integer HK_R = 82
        constant integer HK_S = 83
        constant integer HK_T = 84
        constant integer HK_U = 85
        constant integer HK_V = 86
        constant integer HK_W = 87
        constant integer HK_X = 88
        constant integer HK_Y = 89
        constant integer HK_Z = 90
endglobals

globals
    private constant integer MAX_BUTTONS = 16 // maximum of buttons on dialog
endglobals


//===========================================================================
//  Use this inside dialog action function
//===========================================================================
function GetTriggerDialog takes nothing returns Dialog
    return DialogStruct[ GetClickedDialog() ]
endfunction


//===========================================================================
struct Dialog
        private trigger t = CreateTrigger()
        private dialog  d = DialogCreate()
        private boolean isActionSet = false

        private string messageText = ""
   
        private integer button_count = 0
        private button  array buttons[MAX_BUTTONS]
        private integer array hotkeys[MAX_BUTTONS]
   
        static method create takes nothing returns Dialog
            local Dialog this = .allocate()
            call TriggerRegisterDialogEvent( .t, .d )
            set DialogStruct[ .d ] = this
            return this
        endmethod
   
        method onDestroy takes nothing returns nothing
            call DestroyTrigger(.t)
            call DialogDestroy(.d)
        endmethod    
   
        method GetResult takes nothing returns integer
            local button b = GetClickedButton()
            local integer i = 0
            loop
                exitwhen i >= MAX_BUTTONS
                if b == this.buttons[i] then
                    return this.hotkeys[i]
                endif
                set i = i + 1
            endloop
            call BJDebugMsg("|c00FF0000ERROR: Unknown dialog hotkey")
            return 0
        endmethod
       
        method SetMessage takes string messageText returns nothing
            set .messageText = messageText
        endmethod
       
        method AddButton takes string buttonText, integer hotkey returns nothing
            local button b
            if this.button_count >= MAX_BUTTONS then
                call BJDebugMsg("|c00FF0000ERROR: Maximum number of dialog buttons is " + I2S(MAX_BUTTONS))
            else
                set b = DialogAddButton( this.d,  buttonText , hotkey )
                set this.buttons[this.button_count] = b
                set this.hotkeys[this.button_count] = hotkey
                set this.button_count = this.button_count + 1
            endif
        endmethod  
       
        method AddCondition takes boolexpr condFunc returns nothing
            call TriggerAddCondition( this.t, condFunc )
        endmethod
       
        method AddAction takes code actionFunc returns nothing
            if this.isActionSet == true then
                call TriggerClearActions( this.t )
            endif
            set this.isActionSet = true
            call TriggerAddAction( this.t, actionFunc )
        endmethod
   
        method Show takes player whichPlayer returns nothing
            if this.isActionSet == false then
                call BJDebugMsg("|c00FF0000WARNING: You forgot to set a dialog action")
            endif
            if this.button_count == 0 then
                call BJDebugMsg("|c00FF0000ERROR: You cannot show dialog with no buttons")
            else
                // message must be set before every display because of some bug.
                call DialogSetMessage( this.d, this.messageText )
                call DialogDisplay(whichPlayer, this.d, true)
            endif
        endmethod
       
        method ShowAll takes nothing returns nothing
            local integer i = 0
            loop
                exitwhen i>=12 // maximum of human players is 12
                if GetPlayerController(Player(i)) == MAP_CONTROL_USER and GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING  then
                    call this.Show(Player(i))                      
                endif
                set i = i + 1
            endloop
        endmethod
       
        method Hide takes player whichPlayer returns nothing
            call DialogDisplay(whichPlayer, this.d, false)
        endmethod

        method HideAll takes nothing returns nothing
            local integer i = 0
            loop
                exitwhen i>=12 // maximum of human players is 12
            call this.Hide(Player(i))                      
                set i = i + 1
            endloop
        endmethod
       
endstruct

endlibrary

 
//TESH.scrollpos=85
//TESH.alwaysfold=0
library GameTime initializer INIT
globals
    private time  GameTime
    private timechain FirstTime = 0
    private timer TimeChanger
endglobals

struct timechain
    time self
    timechain next = 0
    timechain last = 0
    static method create takes time self returns timechain
        local timechain this = .allocate()
        set .self = self
        set .next = FirstTime
        set .next.last = this
        set  FirstTime = this
        set .last = 0
        return this
    endmethod
    method onDestroy takes nothing returns nothing
        set .next.last = .last
        set .last.next = .next
    endmethod
endstruct

struct timeunit
    integer value
    static method create takes integer value returns timeunit
        local timeunit this = .allocate()
        set .value = value
        return this
    endmethod
   
    method to_s takes nothing returns string
        local string result = I2S( .value )
        local integer length = StringLength( result )
        local integer difference = length - 2
        if difference > 0 then
            set result = SubString( result, difference, length )
        else
            loop
                exitwhen difference == 0
                set result = "0" + result
                set difference = difference + 1
            endloop
        endif
        return result
    endmethod    
endstruct

struct time
    timechain container
    integer timePassed = 0
    boolean paused = false
    private timeunit hoursUnit
    private timeunit minutesUnit
    private timeunit secondsUnit
   
    static method create takes nothing returns time
        local time this = .allocate()
        set .container = timechain.create( this )
        set .hoursUnit = timeunit.create( 0 )
        set .minutesUnit = timeunit.create( 0 )
        set .secondsUnit = timeunit.create( 0 )
        return this
    endmethod
   
    method pause takes boolean pause returns nothing
        set .paused = pause
    endmethod
   
    method operator hours= takes integer hours returns nothing
        set .timePassed = .timePassed + ( hours - .timePassed / 3600 ) * 3600
    endmethod
   
    method operator minutes= takes integer minutes returns nothing
        set .timePassed = .timePassed + ( minutes - ModuloInteger( .timePassed / 60, 60 ) )* 60
    endmethod
   
    method operator seconds= takes integer seconds returns nothing
        set .timePassed = .timePassed + seconds - ModuloInteger( .timePassed , 60 )
    endmethod
   
    method operator hours takes nothing returns timeunit
        set .hoursUnit.value = .timePassed / 3600
        return .hoursUnit
    endmethod
   
    method operator minutes takes nothing returns timeunit
        set .minutesUnit.value = ModuloInteger( .timePassed / 60, 60 )
        return .minutesUnit
    endmethod
   
    method operator seconds takes nothing returns timeunit
        set .secondsUnit.value = ModuloInteger( .timePassed, 60 )
        return .secondsUnit
    endmethod
   
    method to_s takes string delimeter returns string
        return .hours.to_s() + delimeter + .minutes.to_s() + delimeter + .seconds.to_s()
    endmethod
endstruct
   
function GetGameTime takes nothing returns integer
    return GameTime.seconds
endfunction

function GetGameTimeString takes string delimeter returns string
    return GameTime.to_s( delimeter )
endfunction

private function ChangeTime takes nothing returns nothing
    local timechain curTime = FirstTime
    loop
        exitwhen curTime == 0
        if not curTime.self.paused then
            set curTime.self.timePassed = curTime.self.timePassed + 1
        endif
        set curTime = curTime.next
    endloop
endfunction

private function INIT takes nothing returns nothing
    set GameTime = time.create()
    set TimeChanger = CreateTimer()
    call TimerStart( TimeChanger, 1.00, true, function ChangeTime )
endfunction
endlibrary