//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
//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
//TESH.scrollpos=141
//TESH.alwaysfold=0
library Hash
// What it does
// The Hash system maps integers to slots in an array. This is extremely useful
// when you are trying to attach something to integers that are greater than 8192.
// How To Use
// First you need to create a Hash Table. At most 25 HashTables can be created!
// local hashtable Table = hashtable.create()
// Now you can attach integers to that hashtable with the Hash method.
// The Hash function will return an integer. Use that integer as array-index when attaching the things to an integer.
// When you need the integer again, just use the Search method. It will return -1 if the item is not found, or the
// right index elsewise.
// If the key is no longer needed, you can free it by using hashtable.Remove( key ).
// ---- EXAMPLE ----: This saves the Gold Costs of an Item.
//// library WeaponPrice initializer InitPrices needs Hash
//// globals
//// hashtable WeaponData
//// integer array Price
//// endglobals
////
//// function InitPrices takes nothing returns nothing
//// set WeaponData = hashtable.create()
//// endfunction
////
//// function SetItemPrice takes integer itemtypeid, integer price returns nothing
//// local integer index = WeaponData.Hash( itemtypeid )
//// set Price[ index ] = price
//// endfunction
//// function GetItemPrice takes integer itemtypeid returns integer
//// local integer index = WeaponData.Search( itemtypeid )
//// if index == -1 then
//// return Price[ index ]
//// endif
//// return 0 // Return 0 if the item cannot be found
//// endfunction
//// endlibrary
//// ---- API ----
// 1. create
// 2. Hash / HashEx
// 3. Search
// 4. Remove
// 5. Refresh
// 6. HashSize
// 1. --- method --- hashtable.create( nothing ) returns hashtable
// Creates a new Hashtable.
// Can be used to hash huge integers to a much smaller Universe.
// Useful for hashing ability codes to a normal JASS array.
// 2. --- method --- hashtable.Hash ( key ) returns integer
// --- method --- hashtable.HashEx( key, target ) returns nothing
// Hashes a key to a slot.
// The standard Hash function will return a unique index for each unique key.
// The returned slot will stay the same during one game, but may differ from
// game to game.
// The Extended Hash function ( HashEx ) will allways map the key to the target slot.
// Thus you can specify the
// 3. --- method --- hashtable.Search( key ) returns integer
// Returns the slot previously mapped to the key.
// If the key was not hashed yet, -1 will be returned.
// Example:
//// function TestSearch takes nothing returns boolean
//// local integer indexA = Data.Hash ( 5023 )
//// local integer indexB = Data.Search( 5023 )
//// return indexA == indexB // <---- TRUE
//// endfunction
//// function TestFalseSearch takes nothing returns boolean
//// local integer indexA = Data.Hash ( 5023 )
//// local integer indexB = Data.Search( 5774 )
//// return indexA == indexB // <---- FALSE, as indexB is -1
//// endfunction
// 4. --- method --- hashtable.Remove( key ) returns hashtable
// Recycles a key from the hashtable when no longer needed.
// Used to free slots in the hashtable to allow for more keys to be hashed.
// Recycled slots do not increase the search performance!
// Automatically applies Refresh ( see point 5 )
// when more than 1/3rd of the Hashtable was recycled.
// Please allways change your hashtable variable to the returned hashtable
// to prevent data loss.
// Example:
////
//// function Test2 takes nothing returns boolean
//// set Data = Data.Remove( 5023 ) // Needs to be done. If Data would not be set to the new one,
// the table might be refreshed resulting in a complete data loss!
//// return Data.Search( 5023 ) == - 1 // <--- TRUE
//// endfunction
// 5. --- method --- hashtable.Refresh( nothing ) returns hashtable
// Creates a new Hashtable and hashes all values from the old one to the new one.
// During this process, the old Hashtalble is destroyed.
// Accomplishes the performance loss when there were too many key deletions.
// Automatically applied when more than 1/3rd of the Hashtable was recycled.
// Please allways change your hashtable variable to the returned hashtable
// to prevent data loss.
// 6. --- constant --- HashSize is integer
// The maximum number of keys that can be saved to a HashTable.
// A high number allows for more slots and makes the Table faster,
// but can also result in weak memory usage.
// Primes work best as Hashsizes.
globals
// settings
constant integer HashSize = 413 // Please enter a prime here that is as close to the number of slots you need as possible.
// End of settings. Please do not apply changes to the following variables.
constant real Multiplicator = ( SquareRoot( 5 ) - 1 ) / 2
constant integer HashSlots = 65000
endglobals
private function KeyHash takes integer key returns integer
local real product = key * Multiplicator
return R2I( HashSize * ( product - R2I( product ) ) )
endfunction
private function SlotHash takes integer key returns integer
return ModuloInteger( key * 2, HashSize - 1 ) + 1
endfunction
struct hashtable[ HashSlots ]
integer array Key [ HashSize ]
integer array Slot[ HashSize ]
integer array Base [ HashSize ]
integer array BaseId[ HashSize ]
integer keys
integer recycled = 0
static method create takes nothing returns hashtable
local hashtable new = hashtable.allocate()
local integer index = 0
set new.keys = 0
loop
exitwhen index > HashSize
set new.Key[ index ] = -1
set index = index + 1
endloop
return new
endmethod
method Hash takes integer key returns integer
local integer loopId = 0
local integer keyhash = KeyHash ( key )
local integer slothash = SlotHash( key )
local integer slot = keyhash
loop
exitwhen .Key[ slot ] == -1
exitwhen .Key[ slot ] == 0
if .Key[ slot ] == key then
return slot
elseif loopId > 10 then
return -1
endif
set loopId = loopId + 1
set slot = ModuloInteger( keyhash + loopId * slothash, HashSize )
endloop
set .Key [ slot ] = key
set .Slot[ slot ] = slot
set .BaseId[ slot ] = .keys
set .Base [ .keys ] = key
set .keys = .keys + 1
return slot
endmethod
method HashEx takes integer key, integer target returns nothing
local integer loopId = 0
local integer keyhash = KeyHash ( key )
local integer slothash = SlotHash( key )
local integer slot = keyhash
loop
exitwhen .Key[ slot ] == -1
exitwhen .Key[ slot ] == 0
if .Key[ slot ] == key then
return
elseif loopId > 10 then
return
endif
set loopId = loopId + 1
set slot = ModuloInteger( keyhash + loopId * slothash, HashSize )
endloop
set .Key [ slot ] = key
set .Slot[ slot ] = target
set .BaseId[ slot ] = .keys
set .Base [ .keys ] = key
set .keys = .keys + 1
endmethod
method Search takes integer key returns integer
local integer loopId = 0
local integer keyhash = KeyHash ( key )
local integer slothash = SlotHash( key )
local integer slot = keyhash
loop
exitwhen .Key[ slot ] == key
if .Key[ slot ] == -1 then
return -1
elseif loopId > 10 then
return -1
endif
set loopId = loopId + 1
set slot = ModuloInteger( keyhash + loopId * slothash, HashSize )
endloop
return .Slot[ slot ]
endmethod
method Refresh takes nothing returns hashtable
local hashtable new = hashtable.create()
local integer keyIndex = 0
local integer newSlot
local integer oldSlot
local integer curKey
loop
exitwhen keyIndex > .keys
set curKey = .Base [ keyIndex ]
set newSlot = new.Hash ( curKey )
set oldSlot = .Search( curKey )
set new.Slot[ newSlot ] = oldSlot
set keyIndex = keyIndex + 1
endloop
call .destroy()
return new
endmethod
method Remove takes integer key returns hashtable
local integer slot = .Search( key )
set .Key [ slot ] = 0
set .Slot[ slot ] = -1
set .Base [ .BaseId[ slot ] ] = .Base[ .keys ]
set .BaseId[ slot ] = .BaseId[ .keys ]
set .Base [ .BaseId[ .keys ] ] = -1
set .BaseId[ .keys ] = -1
set .keys = .keys - 1
set .recycled = .recycled + 1
if .recycled > HashSize / 3 then
return .Refresh()
endif
return this
endmethod
endstruct
endlibrary
//TESH.scrollpos=-1
//TESH.alwaysfold=0
///// VER 01 09 - ItemAttacher
//! textmacro AddItemValue takes NAME, TYPE, DEFAULT
library_once $NAME$AttacherItem initializer Init$NAME$ needs Hash
globals
private hashtable IdHash
private $TYPE$ array $NAME$
private $TYPE$ Default$NAME$ = $DEFAULT$
endglobals
private function Init$NAME$ takes nothing returns nothing
set IdHash = hashtable.create()
endfunction
public function GetItemTypeIndex takes integer itemtypeid returns integer
return IdHash.Search( itemtypeid )
endfunction
public function SetDefault$NAME$ takes $TYPE$ value returns nothing
set Default$NAME$ = value
endfunction
public function GetDefault$NAME$ takes nothing returns $TYPE$
return Default$NAME$
endfunction
function SetItemType$NAME$ takes integer itemtypeid, $TYPE$ value returns nothing
local integer index = IdHash.Search( itemtypeid )
if index == -1 then
set index = IdHash.Hash( itemtypeid )
endif
if value == Default$NAME$ then
set IdHash = IdHash.Remove( itemtypeid )
else
set $NAME$[ index ] = value
endif
endfunction
function GetItemType$NAME$ takes integer itemtypeid returns $TYPE$
local integer index = GetItemTypeIndex( itemtypeid )
if index == -1 then
return Default$NAME$
endif
return $NAME$[ index ]
endfunction
function GetItem$NAME$ takes item whichitem returns $TYPE$
local integer index = GetItemTypeIndex( GetItemTypeId( whichitem ) )
if index == -1 then
return $DEFAULT$
endif
return $NAME$[ index ]
endfunction
endlibrary
//! endtextmacro
//TESH.scrollpos=-1
//TESH.alwaysfold=0
//==============================================================================
// PUI -- Perfect Unit Indexing by Cohadar -- v5.1
//==============================================================================
//
// PURPOUSE:
// * Extending UnitUserData()
// * This is basically perfect hashing algorithm for units
//
// HOW TO USE:
// * You have only one function at your disposal GetUnitIndex(unit)
// It will return a unique index for each unit in range 1..8190
//
// * What you will do with that index is all up to you
// Of course using global arrays is the most obvious choice
// Advanced jassers will think of a couple of more clever ones ofc.
//
// * There are also 2 textmacros available at the end of library code
// They can be used for easier attaching to units
// PUI for structs
// PUI_PROPERTY for unit, integer, real, boolean and string variables
//
// PROS:
// * You can use any number of systems that previously could not work together
// because they all required exclusive access of UnitUserData()
//
// * You can also use this to attach spell data structs to casters
//
// * There are no SetUnitIndex() or ClearUnitIndex() functions here
// Each unit gets assigned one index that cannot be changed
// That index will be automatically recycled when unit is removed from the game.
//
// CONS:
// * This system uses UnitUserData() itself
// That means that if you want to use PUI you must recode
// any other system that uses UnitUserData() to use GetUnitIndex() instead
//
// * If you use UnitIndex for arrays of non-native types (timers, effects and similar)
// you must check if timer on that index already exists before you create a new one.
// This can happen if GetUnitIndex() assigns a recycled index (index of some dead and removed unit)
// to the newly created unit for which you intended to use timer for
//
// * All in all this is not a sys for newbies, it gives great power,
// but it requires knowledge and carefull handling
//
// DETAILS:
// * System is using unit array to keep track of all units with an index.
// Array is periodically checked for removed units,
// when removed unit is found, index is recycled.
// Indexes have "decay time" to prevent bugs
// caused by attaching to "Can't Raise, Does not decay" type units,
// or by using RemoveUnit() function
//
// SYSTEM COMMANDS: (debug mode only, red player only)
//
// * type -pui to display indexes of currently selected units
// * type -puistats to display some stats
//
// THANKS TO:
// * Vexorian - for his help with PUI textmacro
//
// HOW TO IMPORT:
// * Just create a trigger named PUI
// * convert it to text and replace the whole trigger text with this one
//
//==============================================================================
library PUI initializer Init
//==============================================================================
globals
//-----------------------------------------------
private constant real INDEX_DECAY_TIME = 5. // seconds
//-----------------------------------------------
private constant real PERIOD = 0.03125 // 32 fps
//-----------------------------------------------
private constant integer DECAY_TICKS = R2I(INDEX_DECAY_TIME/PERIOD)
//-----------------------------------------------
private integer array Indexz
private unit array Unitz
private integer array Decayz
private integer array Tickz
private integer maxindex = 0
private integer topindex = 0
private integer decayindex = 0
private integer checker = 0
private integer decayer = 0
private integer tick = 0
string CurPUI
endglobals
//==============================================================================
private function PeriodicRecycler takes nothing returns boolean
local integer temp
set tick = tick + 1
if topindex > decayindex then
set checker = checker + 1
if checker > topindex then
set checker = decayindex + 1
endif
if (GetUnitUserData(Unitz[checker])==0) then
set decayindex = decayindex + 1
set Unitz[checker] = Unitz[decayindex]
// swap(checker, decayindex)
set temp = Indexz[checker]
set Indexz[checker] = Indexz[decayindex]
set Indexz[decayindex] = temp
set Decayz[decayindex] = DECAY_TICKS
set Tickz[decayindex] = tick
endif
endif
if decayindex > 0 then
set decayer = decayer + 1
if decayer > decayindex then
set decayer = 1
endif
set Decayz[decayer] = Decayz[decayer] - (tick-Tickz[decayer])
if Decayz[decayer] > 0 then
set Tickz[decayer] = tick
else
// swap(decayer, decayindex)
set temp = Indexz[decayer]
set Indexz[decayer] = Indexz[decayindex]
set Indexz[decayindex] = temp
set Unitz[decayindex] = Unitz[topindex]
// swap(decayindex, topindex)
set temp = Indexz[decayindex]
set Indexz[decayindex] = Indexz[topindex]
set Indexz[topindex] = temp
set decayindex = decayindex - 1
set topindex = topindex - 1
endif
endif
return false
endfunction
//==============================================================================
// Main and only function exported by this library
//==============================================================================
function GetUnitIndex takes unit whichUnit returns integer
local integer index
debug if whichUnit == null then
debug call BJDebugMsg("|c00FF0000ERROR: PUI - Index requested for null unit (" +CurPUI+")")
debug return 0
debug endif
set index = GetUnitUserData(whichUnit)
if index == 0 then
set topindex = topindex + 1
if topindex > maxindex then
set maxindex = topindex
set Indexz[topindex] = topindex
endif
set index = Indexz[topindex]
set Unitz[topindex] = whichUnit
call SetUnitUserData(whichUnit, index)
set index = GetUnitUserData(whichUnit)
// this happens when requesting unit index for removed unit
debug if index == 0 then
debug call BJDebugMsg("|c00FFCC00WARNING: PUI - Bad unit handle")
debug endif
//debug call BJDebugMsg("|c00FFCC00PUI: Index assigned #" + I2S(index))
endif
return index
endfunction
//==============================================================================
private function DisplayStats takes nothing returns nothing
call BJDebugMsg("=============================================")
call BJDebugMsg("Biggest index ever = " + I2S(maxindex))
call BJDebugMsg("Indexes in use = " + I2S(topindex-decayindex))
call BJDebugMsg("Decaying indexes = " + I2S(decayindex))
call BJDebugMsg("Released indexes = " + I2S(maxindex-topindex))
call BJDebugMsg("=============================================")
endfunction
//===========================================================================
private function DisplaySelectedEnum takes nothing returns nothing
call BJDebugMsg( "PUI(" + ( GetUnitName(GetEnumUnit()) + ( ") = " + I2S(GetUnitUserData(GetEnumUnit())) ) ) )
endfunction
//===========================================================================
private function DisplaySelected takes nothing returns nothing
local group g = CreateGroup()
call SyncSelections()
call GroupEnumUnitsSelected(g, Player(0), null)
call ForGroup(g, function DisplaySelectedEnum)
call DestroyGroup(g)
set g = null
endfunction
//==============================================================================
private function Init takes nothing returns nothing
local trigger trig
set trig = CreateTrigger()
call TriggerRegisterTimerEvent( trig, PERIOD, true )
call TriggerAddCondition( trig, Condition(function PeriodicRecycler) )
debug set trig = CreateTrigger()
debug call TriggerRegisterPlayerChatEvent( trig, Player(0), "-pui", true )
debug call TriggerAddAction( trig, function DisplaySelected )
debug set trig = CreateTrigger()
debug call TriggerRegisterPlayerChatEvent( trig, Player(0), "-puistats", true )
debug call TriggerAddAction( trig, function DisplayStats )
endfunction
endlibrary
//===========================================================================
// Allowed PUI_PROPERTY TYPES are: unit, integer, real, boolean, string
// Do NOT put handles that need to be destroyed here (timer, trigger, ...)
// Instead put them in a struct and use PUI textmacro
//===========================================================================
//! textmacro PUI_PROPERTY takes VISIBILITY, TYPE, NAME, DEFAULT
$VISIBILITY$ struct $NAME$
private static unit array pui_unit
private static $TYPE$ array pui_data
//-----------------------------------------------------------------------
// Returns default value when first time used
//-----------------------------------------------------------------------
static method operator[] takes unit whichUnit returns $TYPE$
local integer pui
set CurPUI = "$NAME$"
set pui = GetUnitIndex(whichUnit)
if .pui_unit[pui] != whichUnit then
set .pui_unit[pui] = whichUnit
set .pui_data[pui] = $DEFAULT$
endif
return .pui_data[pui]
endmethod
//-----------------------------------------------------------------------
static method operator[]= takes unit whichUnit, $TYPE$ whichData returns nothing
local integer pui
set CurPUI = "$NAME$"
set pui = GetUnitIndex(whichUnit)
set .pui_unit[pui] = whichUnit
set .pui_data[pui] = whichData
endmethod
endstruct
//! endtextmacro
//===========================================================================
// Never destroy PUI structs directly.
// Use .release() instead, will call .destroy()
//===========================================================================
//! textmacro PUI
private static unit array pui_unit
private static integer array pui_data
private static integer array pui_id
//-----------------------------------------------------------------------
// Returns zero if no struct is attached to unit
//-----------------------------------------------------------------------
static method operator[] takes unit whichUnit returns integer
local integer pui = GetUnitIndex(whichUnit)
if .pui_data[pui] != 0 then
if .pui_unit[pui] != whichUnit then
// recycled handle detected
call .destroy(.pui_data[pui])
set .pui_unit[pui] = null
set .pui_data[pui] = 0
endif
endif
return .pui_data[pui]
endmethod
//-----------------------------------------------------------------------
// This will overwrite already attached struct if any
//-----------------------------------------------------------------------
static method operator[]= takes unit whichUnit, integer whichData returns nothing
local integer pui = GetUnitIndex(whichUnit)
if .pui_data[pui] != 0 then
call .destroy(.pui_data[pui])
endif
set .pui_unit[pui] = whichUnit
set .pui_data[pui] = whichData
set .pui_id[whichData] = pui
endmethod
//-----------------------------------------------------------------------
// If you do not call release struct will be destroyed when unit handle gets recycled
//-----------------------------------------------------------------------
method release takes nothing returns nothing
local integer pui= .pui_id[integer(this)]
call .destroy()
set .pui_unit[pui] = null
set .pui_data[pui] = 0
endmethod
//! endtextmacro
//TESH.scrollpos=0
//TESH.alwaysfold=0
//! textmacro RandomSet takes NAME, TYPE, ELEMENTS, DEFAULT
private struct $NAME$
$TYPE$ array random [ $ELEMENTS$ ]
$TYPE$ array random_left[ $ELEMENTS$ ]
integer randoms_left = 0
integer randoms = 0
static method create takes nothing returns $NAME$
return .allocate()
endmethod
method get takes nothing returns $TYPE$
local integer index
local $TYPE$ result
if .randoms_left > 0 then
set .randoms_left = .randoms_left - 1
set index = GetRandomInt( 0, .randoms_left )
set result = .random_left[ index ]
set .random_left[ index ] = .random_left[ .randoms_left ]
return result
endif
return $DEFAULT$
endmethod
method reset takes nothing returns nothing
local integer i = 0
loop
exitwhen i > .randoms
set .random_left[ i ] = .random[ i ]
set i = i + 1
endloop
set .randoms_left = .randoms
endmethod
method append takes $TYPE$ toappend returns nothing
set .random[ .randoms ] = toappend
set .randoms = .randoms + 1
set .random_left[ .randoms_left ] = toappend
set .randoms_left = .randoms_left + 1
endmethod
endstruct
//! endtextmacro
//TESH.scrollpos=0
//TESH.alwaysfold=0
library RectTools
//! textmacro GetBound takes RECT , BOUND
library_once Rect$RECT$ToolsBounds initializer Init$RECT$ToolsBounds
globals
real $RECT$CenterX
real $RECT$CenterY
real $RECT$MaxX
real $RECT$MaxY
real $RECT$MinX
real $RECT$MinY
endglobals
private function Init$RECT$ToolsBounds takes nothing returns nothing
set $RECT$CenterX = GetRectCenterX( $RECT$ )
set $RECT$CenterY = GetRectCenterY( $RECT$ )
set $RECT$MaxX = GetRectMaxX ( $RECT$ )
set $RECT$MaxY = GetRectMaxY ( $RECT$ )
set $RECT$MinX = GetRectMinX ( $RECT$ )
set $RECT$MinY = GetRectMinY ( $RECT$ )
endfunction
endlibrary
function Get$RECT$$BOUND$ takes nothing returns real
return $RECT$$BOUND$
endfunction
//! endtextmacro
//! textmacro IsWithinBounds takes RECT
library_once Rect$RECT$ToolsBounds initializer Init$RECT$ToolsBounds
globals
real $RECT$CenterX
real $RECT$CenterY
real $RECT$MaxX
real $RECT$MaxY
real $RECT$MinX
real $RECT$MinY
endglobals
private function Init$RECT$ToolsBounds takes nothing returns nothing
set $RECT$CenterX = GetRectCenterX( $RECT$ )
set $RECT$CenterY = GetRectCenterY( $RECT$ )
set $RECT$MaxX = GetRectMaxX ( $RECT$ )
set $RECT$MaxY = GetRectMaxY ( $RECT$ )
set $RECT$MinX = GetRectMinX ( $RECT$ )
set $RECT$MinY = GetRectMinY ( $RECT$ )
endfunction
endlibrary
function IsLocIn$RECT$ takes real x , real y returns boolean
return ( x < $RECT$MaxX ) and ( y < $RECT$MaxY ) and ( x > $RECT$MinX ) and ( y > $RECT$MinY )
endfunction
//! endtextmacro
//! textmacro CreateRect takes RECT , MINX , MINY , MAXX , MAXY
library_once Rect$RECT$ToolsBounds initializer Init$RECT$ToolsBounds
globals
real $RECT$CenterX = ( $MINX$ + $MAXX$ ) / 2
real $RECT$CenterY = ( $MINY$ + $MAXY$ ) / 2
constant real $RECT$MaxX = $MAXX$
constant real $RECT$MaxY = $MAXY$
constant real $RECT$MinX = $MINY$
constant real $RECT$MinY = $MINX$
endglobals
private function Init$RECT$ToolsBounds takes nothing returns nothing
set $RECT$ = Rect( $MINX$ , $MINY$ , $MAXX$ , $MAXY$ )
endfunction
endlibrary
//! endtextmacro
endlibrary
//TESH.scrollpos=176
//TESH.alwaysfold=0
library TriggerGroups
struct triggergroup [163820] // 819 * 200 (So 819 total groups, with up to 200 triggers in each)
trigger array trig [200]
integer total = 0
method GET takes integer index returns trigger
return .trig[index]
endmethod
static method create takes nothing returns triggergroup
return triggergroup.allocate()
endmethod
endstruct
globals
private triggergroup Temp
private integer index = 0
private trigger callback = CreateTrigger()
endglobals
function TriggerGroupAdd takes triggergroup tg, trigger t returns nothing
set tg.total = tg.total + 1
if tg.total > 200 then
set tg.total = tg.total - 1
debug call BJDebugMsg("|cff995500TriggerGroup Error: No more space in TriggerGroup|r")
return
endif
set tg.trig[tg.total] = t
endfunction
function FirstOfTriggerGroup takes triggergroup tg returns trigger
return tg.trig[tg.total]
endfunction
function TriggerGroupRemove takes triggergroup tg, trigger t returns nothing
local integer a = 0
loop
exitwhen a > tg.total
if tg.trig[a] == t then
set tg.trig[a] = tg.trig[tg.total]
set tg.total = tg.total - 1
return
endif
set a = a + 1
endloop
debug call BJDebugMsg("|cff995500TriggerGroup Error: Attempt to remove a trigger not in group|r")
endfunction
// Creates the triggergroup for use
function CreateTriggerGroup takes nothing returns triggergroup
return triggergroup.create()
endfunction
// Used in ForTriggerGroup to get the current looping trigger
function GetEnumTrigger takes nothing returns trigger
return Temp.trig[index]
endfunction
// Counts how many triggers are in the triggergroup
function CountTriggersInTriggerGroup takes triggergroup tg returns integer
return tg.total
endfunction
// Refreshes the triggergroup:
// - Removes null (destroyed) triggers from the triggergroup
// - sets the total to the correct amount
function RefreshTriggerGroup takes triggergroup tg returns nothing
local integer a = 0
loop
exitwhen a > tg.total
if tg.trig[a] == null then
set tg.trig[a] = tg.trig[tg.total]
set a = a - 1
set tg.total = tg.total - 1
endif
set a = a + 1
endloop
endfunction
// Clear the triggergroup
function ClearTriggerGroup takes triggergroup tg returns nothing
local integer a = 0
loop
exitwhen a > tg.total
set tg.trig[a] = null
set a = a + 1
endloop
set tg.total = 0
endfunction
// Destroys the triggergroup to free up a slot for another one.
function DestroyTriggerGroup takes triggergroup tg returns nothing
local integer a = 0
loop
exitwhen a > tg.total
set tg.trig[a] = null
set a = a + 1
endloop
set tg.total = 0
call tg.destroy()
endfunction
// Loop through every trigger in the triggergroup
function ForTriggerGroupExecute takes triggergroup tg, string FuncName returns nothing
local integer a = 0
set Temp = tg
loop
exitwhen a > tg.total
set index = a
call ExecuteFunc(FuncName)
set a = a + 1
endloop
set Temp = 0
set index = 0
endfunction
// Loop through every trigger in the triggergroup
function ForTriggerGroup takes triggergroup tg, code FuncName returns nothing
local integer a = 0
set Temp = tg
call TriggerAddAction(callback, FuncName)
loop
exitwhen a > tg.total
set index = a
call TriggerExecute(callback)
set a = a + 1
endloop
call TriggerClearActions(callback)
set Temp = 0
set index = 0
endfunction
// Returns the evaluation of all the triggers, only 1 has to be true.
function TriggerGroupOrEvaluate takes triggergroup tg returns boolean
local integer a = 0
loop
exitwhen a > tg.total
if TriggerEvaluate(tg.trig[a]) then
return true
endif
set a = a + 1
endloop
return false
endfunction
// Returns the evaluation of all the triggers, all of them have to be true.
function TriggerGroupAndEvaluate takes triggergroup tg returns boolean
local integer a = 0
loop
exitwhen a > tg.total
if TriggerEvaluate(tg.trig[a]) == false then
return false
endif
set a = a + 1
endloop
return true
endfunction
// |======================|
// | E X T E N S I O N |
// |======================|
// Run every trigger in the group
function RunTriggerGroup takes triggergroup tg returns nothing
local integer a = 0
loop
exitwhen a > tg.total
call TriggerExecute(tg.trig[a])
set a = a + 1
endloop
endfunction
// Evaluate every trigger in the group
function EvaluateTriggerGroup takes triggergroup tg returns nothing
local integer a = 0
loop
exitwhen a > tg.total
call TriggerEvaluate(tg.trig[a])
set a = a + 1
endloop
endfunction
// Disable every trigger in the group
function DisableTriggerGroup takes triggergroup tg returns nothing
local integer a = 0
loop
exitwhen a > tg.total
call DisableTrigger(tg.trig[a])
set a = a + 1
endloop
endfunction
// Enable every trigger in the group
function EnableTriggerGroup takes triggergroup tg returns nothing
local integer a = 0
loop
exitwhen a > tg.total
call EnableTrigger(tg.trig[a])
set a = a + 1
endloop
endfunction
// Runs the triggers which evaluate true (Condition is true)
function ConditionalRunTriggerGroup takes triggergroup tg returns nothing
local integer a = 0
loop
exitwhen a > tg.total
if TriggerEvaluate(tg.trig[a]) then
call TriggerExecute(tg.trig[a])
endif
set a = a + 1
endloop
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
///// VER 01 09 - UnitAttacher
//! textmacro AddUnitValue takes NAME, TYPE, DEFAULT
library_once $NAME$AttacherUnit initializer Init$NAME$ needs Hash
globals
private hashtable IdHash
private $TYPE$ array $NAME$
private $TYPE$ Default$NAME$ = $DEFAULT$
endglobals
private function Init$NAME$ takes nothing returns nothing
set IdHash = hashtable.create()
endfunction
public function GetUnitTypeIndex takes integer unittypeid returns integer
return IdHash.Search( unittypeid )
endfunction
public function SetDefault$NAME$ takes $TYPE$ value returns nothing
set Default$NAME$ = value
endfunction
public function GetDefault$NAME$ takes nothing returns $TYPE$
return Default$NAME$
endfunction
function SetUnitType$NAME$ takes integer unittypeid, $TYPE$ value returns nothing
local integer index = IdHash.Search( unittypeid )
if index == -1 then
set index = IdHash.Hash( unittypeid )
endif
if value == Default$NAME$ then
set IdHash = IdHash.Remove( unittypeid )
else
set $NAME$[ index ] = value
endif
endfunction
function GetUnitType$NAME$ takes integer unittypeid returns $TYPE$
local integer index = GetUnitTypeIndex( unittypeid )
if index == -1 then
return Default$NAME$
endif
return $NAME$[ index ]
endfunction
function GetUnit$NAME$ takes unit whichunit returns $TYPE$
local integer index = GetUnitTypeIndex( GetUnitTypeId( whichunit ) )
if index == -1 then
return $DEFAULT$
endif
return $NAME$[ index ]
endfunction
endlibrary
//! endtextmacro
//TESH.scrollpos=0
//TESH.alwaysfold=0
library Debug initializer INIT needs Utilities
globals
debug constant string BADColor = "|cffff0303"
debug constant string MSGColor = "|cffffcc00"
debug constant string normtag = BADColor + "DEBUG! "
debug constant string entertag = BADColor + "ENTER> "
debug constant string leavetag = BADColor + "LEAVE> "
debug constant string end = "|r"
debug debugger STDERR
debug constant trigger TraceTrigger = CreateTrigger()
endglobals
//! textmacro ASSERT_FUNC takes NAME, TYPE, CONVERTER
method assert$NAME$ takes $TYPE$ check, $TYPE$ assert returns boolean
local boolean bool = check == assert
debug set .assertions = .assertions + 1
debug if bool then
debug call .Debug( MSGColor + "Assertion passed: " + $CONVERTER$( check ) )
debug else
debug call .Debug( "Assertion" + BADColor + " FAILED:" + MSGColor + " Expected: '" + $CONVERTER$( assert ) + "'; Got: '" + $CONVERTER$( check ) + "'" )
debug set .errors = .errors + 1
debug endif
return bool
endmethod
//! endtextmacro
private function H2S takes handle h returns string
return "H"+I2S( GetHandleId(h) - 0x100000 )
endfunction
private function B2S takes boolean b returns string
if b then
return "true"
endif
return "false"
endfunction
struct debugger
debug string nameID = "BAD DEBUGGER"
debug string array inMSG[ 10 ]
debug string msg
debug integer depth
debug integer id
debug integer assertions
debug integer errors
debug static integer count = 0
debug private static debugger array self
static method operator [] takes integer index returns debugger
debug return .self[ index ]
return 0
endmethod
method operator name takes nothing returns string
debug return .nameID + " (#" + I2S( .id ) + ")"
return ""
endmethod
method operator INDENT takes nothing returns string
debug local integer i = 0
debug local string s = MSGColor + " "
debug loop
debug exitwhen i >= .depth
debug set s = s + " "
debug set i = i + 1
debug endloop
debug return s
return ""
endmethod
static method create takes string name returns debugger
local debugger this = .allocate()
debug set .nameID = BADColor + StringCase( name, true )
debug set .msg = StringCase( name, false )
debug set .id = .count
debug set .self[ .id ] = this
debug set .count = .count + 1
debug set .depth = 0
debug set .inMSG[ .depth ] = this.name
return this
endmethod
method Shout takes string debugtag, string MSG returns nothing
debug call DisplayTimedTextToPlayer( LOCAL_PLAYER, 0, 0, 60, .name + "." + debugtag + .INDENT + MSG + end )
endmethod
method Debug takes string MSG returns nothing
debug call .Shout( normtag, MSGColor + MSG )
endmethod
method operator InMSG= takes string MSG returns nothing
debug call .Shout( entertag, BADColor + "start '" + MSG + "'" )
debug set .depth = .depth + 1
debug set .inMSG[ .depth ] = MSG
endmethod
method In takes string MSG returns nothing
debug set .InMSG = MSG
endmethod
method Out takes string outMSG returns nothing
debug if .assertString( outMSG, .inMSG[ .depth ] ) then
debug set .depth = .depth - 1
debug call .Shout( leavetag, BADColor + "end '" + outMSG + "'" )
debug else
debug set .depth = .depth - 1
debug call .Shout( normtag, BADColor + "Bad Out Message: " + outMSG )
debug endif
endmethod
method onDestroy takes nothing returns nothing
debug call .Debug( "DESTRUCTION" )
debug loop
debug exitwhen .depth <= 0
debug call .Out( .inMSG[ .depth ] )
debug endloop
endmethod
method operator state takes nothing returns string
debug return MSGColor + "\nAssertions: " + I2S( .assertions ) + "\nFails: " + I2S( .errors ) + "\nLast In: " + .inMSG[ .depth ]
return "Debug mode deactivated."
endmethod
//! runtextmacro ASSERT_FUNC( "Integer", "integer", "I2S" )
//! runtextmacro ASSERT_FUNC( "Boolean", "boolean", "B2S" )
//! runtextmacro ASSERT_FUNC( "Real", "real", "R2S" )
//! runtextmacro ASSERT_FUNC( "String", "string", "" )
//! runtextmacro ASSERT_FUNC( "Id", "integer", "GetObjectName" )
//! runtextmacro ASSERT_FUNC( "Handle", "handle", "H2S" )
endstruct
function CreateDebugger takes string name returns debugger
return debugger.create( name )
endfunction
function DebugMSG takes debugger db, string MSG returns nothing
debug call db.Debug( MSG )
endfunction
function InMSG takes debugger db, string MSG returns nothing
debug set db.InMSG = MSG
endfunction
function OutMSG takes debugger db, string MSG returns nothing
debug call db.Out( MSG )
endfunction
//! textmacro DebugArray takes ARRAY , CONVERTER
function Debug$ARRAY$ takes debugger db, integer start, integer end returns nothing
debug local integer iterator = start
debug loop
debug exitwhen iterator > end
debug call db.Debug( $CONVERTER$( $ARRAY$[iterator] ) )
debug set iterator = iterator + 1
debug endloop
endfunction
//! endtextmacro
private function TraceTrigger_Actions takes nothing returns nothing
debug local integer i = 0
debug local integer j = 0
debug local string eventString = StringCase( SubString( GetEventPlayerChatString(), 7, 20 ), false )
debug local string inString = "CHECK: " + eventString
debug set STDERR.InMSG = inString
debug loop
debug exitwhen i >= debugger.count
debug if debugger[ i ].msg == eventString then
debug set j = j + 1
debug call DisplayText( LOCAL_PLAYER, normtag + debugger[ i ].state )
debug call TriggerSleepAction( 2.00 )
debug endif
debug set i = i + 1
debug endloop
debug call STDERR.Out( inString )
endfunction
private function INIT takes nothing returns nothing
debug call TriggerRegisterAnyPlayerChatEvent( TraceTrigger, "-trace ", false )
debug call TriggerRegisterAnyPlayerChatEvent( TraceTrigger, "-debug ", false )
debug call TriggerRegisterAnyPlayerChatEvent( TraceTrigger, "-check ", false )
debug call TriggerAddAction( TraceTrigger, function TraceTrigger_Actions )
set STDERR = debugger.create( "STDERR" )
endfunction
endlibrary
//TESH.scrollpos=339
//TESH.alwaysfold=0
//----------------------------\\
// VER B2 \\
//----------------------------\\
// Special thanks: Tom_Kazansky for his incredible wisdom concerning the creation of texttags ; )
// PurplePoot for his countless tips on what to improve!
library UtilityParameters
globals
// parameters
// for parameter coloring
// GOLD will be used as the display color for positive bounty created with CreateBountyText()
// RED will be used as the display color for negative bounty created with CreateBountyText()
constant string NegativeTag = "|cffff3333"
constant string PositiveTag = "|cff33cf33"
constant string NeutralTag = "|cffffcc00"
constant string InactiveTag = "|cff808080"
constant string EndTag = "|r"
constant string RED = "|cffff3333"
constant string GREEN = "|cff33cf33"
constant string GOLD = "|cffffcc00"
constant string GREY = "|cff808080"
constant string LIGHTGREY = "|cffC0C0C0"
constant string TURQUOISE = "|cff33BBBB"
constant string WHITE = "|r"
// use %p for the name of the player that has left.
constant string LEAVER_MESSAGE = RED + "%p has left the game!"
endglobals
endlibrary
library Utilities initializer UtilityInit needs UtilityParameters
//! textmacro ChangePlayerState takes PLAYER, STATE, AMOUNT
call SetPlayerState( $PLAYER$, PLAYER_STATE_$STATE$, GetPlayerState( $PLAYER$, PLAYER_STATE_$STATE$ ) + $AMOUNT$ )
//! endtextmacro
//! textmacro State2Text takes STATE
globals
integer $STATE$s = 0
string array $STATE$Name
real array $STATE$State
endglobals
function Text2$STATE$ takes string text, real state returns nothing
local real curKey = state
local string parKey = text
local integer index = $STATE$s
local integer curdex = index - 1
set $STATE$s = $STATE$s + 1
loop
exitwhen index < 1
exitwhen curKey >= $STATE$State[ curdex ]
set $STATE$State[ index ] = $STATE$State[ curdex ]
set $STATE$Name[ index ] = $STATE$Name[ curdex ]
set index = curdex
set curdex = index - 1
endloop
set $STATE$State[ index ] = curKey
set $STATE$Name[ index ] = parKey
endfunction
function $STATE$2Text takes real state returns string
local integer index = 0
loop
if $STATE$State[ index ] >= state then
set index = index - 1
if index < 0 then
set index = 0
endif
exitwhen true
endif
exitwhen index >= $STATE$s - 1
set index = index + 1
endloop
return $STATE$Name[ index ]
endfunction
//! endtextmacro
globals
// Do not change these!
player array Players
constant integer NUMPLAYERS = 15
constant integer MAX_PLAYER_SLOT = 15
constant integer NUMUSERS = 11
constant integer MAX_USER_SLOT = 11
constant integer NUMSLOTS = 5
constant integer MAX_INV_SLOT = 5
integer LETTERS = 0
real array StartLocX
real array StartLocY
string array PlayerName
string array PlayerNameUncolored
string array PlayerStartName
string array PlayerColor
boolean array PlayerActive
playercolor array DefaultPlayerColor
private string array NormalPlayerColor
constant group GLOBAL_GROUP = CreateGroup()
constant integer HexBase = 16
string array Hex
string array LETTER
constant string BountyEffectString = "UI\\Feedback\\GoldCredit\\GoldCredit.mdl"
string BountyColoring = GOLD + "+"
constant real BountySpeed = 0.71 / 24
constant real BountyTextSize = 0.023
constant trigger LEAVER_HANDLER = CreateTrigger()
handle ReturnHandle
boolean array PLAYER_ALLIANCE_STATE_PASSIVE
boolean array PLAYER_ALLIANCE_STATE_HELP_REQUEST
boolean array PLAYER_ALLIANCE_STATE_HELP_RESPONSE
boolean array PLAYER_ALLIANCE_STATE_SHARED_XP
boolean array PLAYER_ALLIANCE_STATE_SHARED_SPELLS
boolean array PLAYER_ALLIANCE_STATE_ALLIANCE_SHARED_VISION
boolean array PLAYER_ALLIANCE_STATE_ALLIANCE_SHARED_CONTROL
boolean array PLAYER_ALLIANCE_STATE_ALLIANCE_SHARED_ADVANCED_CONTROL
constant boolean AUTOCOLOR_NAMES = true
string LEAVER_MESSAGE_A
string LEAVER_MESSAGE_B
boolean DISPLAY_LEAVER_NAME = false
player LOCAL_PLAYER
private multiboardchain array MBChain
endglobals
function DisplayText takes player whichplayer, string text returns nothing
call DisplayTimedTextToPlayer( whichplayer, 0, 0, 15, text )
endfunction
function Hex2S takes integer hex, integer digits returns string
local string hexstring = ""
local integer curDigit
loop
exitwhen digits <= 0
set curDigit = ModuloInteger( hex, HexBase )
set hex = hex / HexBase
set hexstring = Hex[ curDigit ] + hexstring
set digits = digits - 1
endloop
return hexstring
endfunction
function DistanceBetweenUnits takes unit a, unit b returns real
local real deltaX = GetUnitX( a ) - GetUnitX( b )
local real deltaY = GetUnitY( a ) - GetUnitY( b )
set a = null
set b = null
return SquareRoot( deltaX * deltaX + deltaY * deltaY )
endfunction
function GetHandleId takes handle h returns integer
return h
return 0
endfunction
function State2Color takes real state returns string
local integer hex = R2I( state * 204 )
if hex > 204 then
set hex = 204
elseif hex < 0 then
set hex = 0
endif
return "|cff" + Hex2S( 255 - hex, 2 ) + Hex2S( 51 + hex, 2 ) + "20"
endfunction
function SetPlayerNameSJ takes player whichplayer, string name returns nothing
local integer playerId = GetPlayerId( whichplayer )
set PlayerName[ playerId ] = PlayerColor[ playerId ] + name
set PlayerNameUncolored[ playerId ] = name
call SetPlayerName( whichplayer, name )
endfunction
function SetPlayerColors takes integer playerid, integer red, integer green, integer blue returns nothing
set PlayerColor[ playerid ] = "|cff" + Hex2S( red, 2 ) + Hex2S( green, 2 ) + Hex2S( blue, 2 )
set PlayerName[ playerid ] = PlayerColor[ playerid ] + PlayerNameUncolored[ playerid ]
endfunction
function SetPlayerColorsOld takes integer playerid, integer red, integer green, integer blue returns nothing
set NormalPlayerColor[ playerid ] = "|cff" + Hex2S( red, 2 ) + Hex2S( green, 2 ) + Hex2S( blue, 2 )
endfunction
private function LeaverHandlerNoName_Actions takes nothing returns nothing
local player leaver = GetTriggerPlayer( )
local integer leaverId = GetPlayerId ( leaver )
local string leaverName = GREY + PlayerName[ leaverId ] + " (LEFT)" + EndTag
call SetPlayerNameSJ( leaver, leaverName )
set PlayerActive [ leaverId ] = false
set PlayerName [ leaverId ] = leaverName
call DisplayTextToPlayer( GetLocalPlayer(), 0, 0, LEAVER_MESSAGE )
endfunction
private function LeaverHandlerName_Actions takes nothing returns nothing
local player leaver = GetTriggerPlayer( )
local integer leaverId = GetPlayerId ( leaver )
local string leaverName = InactiveTag + PlayerName[ leaverId ] + " (LEFT)" + EndTag
call SetPlayerNameSJ( leaver, leaverName )
set PlayerActive [ leaverId ] = false
set PlayerName [ leaverId ] = leaverName
call DisplayTextToPlayer( GetLocalPlayer(), 0, 0, LEAVER_MESSAGE_A + PlayerStartName[ leaverId ] + LEAVER_MESSAGE_B )
endfunction
function SetAllianceState takes integer alliancestate, boolean passive, boolean helprequest, boolean helpresponse, boolean sharedxp, boolean sharedspells, boolean sharedvision, boolean sharedcontrol, boolean sharedadvancedcontrol returns nothing
if alliancestate >= 0 and alliancestate <= 8 then
set PLAYER_ALLIANCE_STATE_PASSIVE[ alliancestate ] = passive
set PLAYER_ALLIANCE_STATE_HELP_REQUEST[ alliancestate ] = helprequest
set PLAYER_ALLIANCE_STATE_HELP_RESPONSE[ alliancestate ] = helpresponse
set PLAYER_ALLIANCE_STATE_SHARED_XP[ alliancestate ] = sharedxp
set PLAYER_ALLIANCE_STATE_SHARED_SPELLS[ alliancestate ] = sharedspells
set PLAYER_ALLIANCE_STATE_ALLIANCE_SHARED_VISION[ alliancestate ] = sharedvision
set PLAYER_ALLIANCE_STATE_ALLIANCE_SHARED_CONTROL[ alliancestate ] = sharedcontrol
set PLAYER_ALLIANCE_STATE_ALLIANCE_SHARED_ADVANCED_CONTROL[ alliancestate ] = sharedadvancedcontrol
endif
endfunction
private function AddLetter takes string char returns nothing
set LETTER[ LETTERS ] = char
set LETTERS = LETTERS + 1
endfunction
struct multiboardchain
player owner
multiboardchain_member first
multiboardchain_member last
static method create takes player owner returns multiboardchain
local multiboardchain this = .allocate()
set .owner = owner
set .first = 0
set .last = 0
return this
endmethod
endstruct
struct multiboardchain_member
multiboard mb
multiboardchain parent
multiboardchain_member next
multiboardchain_member last
static method create takes multiboard mb, multiboardchain parent returns multiboardchain_member
local multiboardchain_member this
local multiboardchain_member curChild = parent.first
if parent.first == 0 then
set this = .allocate()
set parent.first = this
else
loop
exitwhen curChild == 0
if curChild.mb == mb then
call curChild.reAppend()
return curChild
endif
set curChild = curChild.next
endloop
set this = .allocate()
endif
set .mb = mb
set .parent = parent
set .last = .parent.last
set .parent.last = this
set .last.next = this
set .next = 0
if LOCAL_PLAYER == .parent.owner then
if .last != 0 then
call MultiboardDisplay( .last.mb, false )
endif
call MultiboardDisplay( mb, true )
endif
return this
endmethod
// drops the chain member from the chain and fixes the chain
method drop takes nothing returns nothing
local boolean isLast = .next == 0
local boolean isFirst = .last == 0
if isLast and isFirst then
set .parent.last = 0
set .parent.first = 0
elseif isLast then
set .parent.last = .last
set .last.next = 0
elseif isFirst then
set .parent.first = .next
set .next.last = 0
else
set .next.last = .last
set .last.next = .next
endif
endmethod
method reAppend takes nothing returns nothing
// fix chain
call .drop()
// append self
set .last = .parent.last
set .parent.last = this
set .last.next = this
if LOCAL_PLAYER == .parent.owner then
if .last != 0 then
call MultiboardDisplay( .last.mb, false )
endif
call MultiboardDisplay( .mb, true )
endif
endmethod
method onDestroy takes nothing returns nothing
local boolean view = LOCAL_PLAYER == .parent.owner
local boolean showLast = ( .next == 0 ) and ( .last != 0 )
if view then
call MultiboardDisplay( .mb, false )
if showLast then
call MultiboardDisplay( .last.mb, true )
endif
endif
call .drop()
set .mb = null
endmethod
endstruct
function MultiboardDisplaySJ takes multiboard mb, boolean display, player viewer returns nothing
local multiboardchain parent
local multiboardchain_member curChild
local boolean view
if viewer == null then
set viewer = LOCAL_PLAYER
endif
set view = viewer == LOCAL_PLAYER
set parent = MBChain[ GetPlayerId( viewer ) ]
if display then
call multiboardchain_member.create( mb, parent )
else
set curChild = parent.last
loop
exitwhen curChild == 0
if curChild.mb == mb then
call curChild.destroy()
set view = false
exitwhen true
endif
set curChild = curChild.last
endloop
if view then
call MultiboardDisplay( mb, false )
endif
endif
endfunction
private function UtilityInit takes nothing returns nothing
local integer playerId = 0
local integer innerIndex = 0
local integer stringIndex = 0
local integer stringLen = StringLength( LEAVER_MESSAGE )
local integer startLocation
local playercolor curColor
set LOCAL_PLAYER = GetLocalPlayer()
set Hex[ 0 ] = "0"
set Hex[ 1 ] = "1"
set Hex[ 2 ] = "2"
set Hex[ 3 ] = "3"
set Hex[ 4 ] = "4"
set Hex[ 5 ] = "5"
set Hex[ 6 ] = "6"
set Hex[ 7 ] = "7"
set Hex[ 8 ] = "8"
set Hex[ 9 ] = "9"
set Hex[ 10 ] = "a"
set Hex[ 11 ] = "b"
set Hex[ 12 ] = "c"
set Hex[ 13 ] = "e"
set Hex[ 14 ] = "d"
set Hex[ 15 ] = "f"
call AddLetter( RED + "UNDEF CHAR" )
call AddLetter( "0" )
call AddLetter( "1" )
call AddLetter( "2" )
call AddLetter( "3" )
call AddLetter( "4" )
call AddLetter( "5" )
call AddLetter( "6" )
call AddLetter( "7" )
call AddLetter( "8" )
call AddLetter( "9" )
call AddLetter( "a" )
call AddLetter( "b" )
call AddLetter( "c" )
call AddLetter( "d" )
call AddLetter( "e" )
call AddLetter( "f" )
call AddLetter( "g" )
call AddLetter( "h" )
call AddLetter( "i" )
call AddLetter( "j" )
call AddLetter( "k" )
call AddLetter( "l" )
call AddLetter( "m" )
call AddLetter( "n" )
call AddLetter( "o" )
call AddLetter( "p" )
call AddLetter( "q" )
call AddLetter( "r" )
call AddLetter( "s" )
call AddLetter( "t" )
call AddLetter( "u" )
call AddLetter( "v" )
call AddLetter( "w" )
call AddLetter( "x" )
call AddLetter( "y" )
call AddLetter( "z" )
set BountyColoring = GOLD + "+"
call SetPlayerColorsOld( 0, 255, 3, 3 )
call SetPlayerColorsOld( 1, 0, 66, 255 )
call SetPlayerColorsOld( 2, 28, 230, 185 )
call SetPlayerColorsOld( 3, 84, 0, 129 )
call SetPlayerColorsOld( 4, 255, 252, 1 )
call SetPlayerColorsOld( 5, 254, 186, 14 )
call SetPlayerColorsOld( 6, 32, 192, 0 )
call SetPlayerColorsOld( 7, 229, 91, 176 )
call SetPlayerColorsOld( 8, 149, 150, 151 )
call SetPlayerColorsOld( 9, 126, 191, 241 )
call SetPlayerColorsOld( 10, 16, 98, 70 )
call SetPlayerColorsOld( 11, 78, 42, 4 )
call SetAllianceState( bj_ALLIANCE_ALLIED_ADVUNITS, true, true, true, true, true, true, true, true )
call SetAllianceState( bj_ALLIANCE_ALLIED_UNITS, true, true, true, true, true, true, true, false )
call SetAllianceState( bj_ALLIANCE_ALLIED_VISION, true, true, true, true, true, true, false, false )
call SetAllianceState( bj_ALLIANCE_ALLIED, true, true, true, true, true, false, false, false )
call SetAllianceState( bj_ALLIANCE_NEUTRAL_VISION, true, false, false, false, false, true, false, false )
call SetAllianceState( bj_ALLIANCE_NEUTRAL, false, false, false, false, false, false, false, false )
call SetAllianceState( bj_ALLIANCE_UNALLIED_VISION, false, false, false, false, false, true, false, false )
call SetAllianceState( bj_ALLIANCE_UNALLIED, false, false, false, false, false, false, false, false )
loop
exitwhen stringIndex >= stringLen
if SubString( LEAVER_MESSAGE, stringIndex, stringIndex +2 ) == "%p" then
set LEAVER_MESSAGE_A = SubString( LEAVER_MESSAGE, 0, stringIndex )
set LEAVER_MESSAGE_B = SubString( LEAVER_MESSAGE, stringIndex+2, stringLen )
set DISPLAY_LEAVER_NAME = true
exitwhen true
endif
set stringIndex = stringIndex + 1
endloop
set playerId = 0
loop
exitwhen playerId > NUMPLAYERS
set Players [ playerId ] = Player( playerId )
set PlayerActive [ playerId ] = GetPlayerSlotState( Players[ playerId ] ) == PLAYER_SLOT_STATE_PLAYING
set PlayerStartName[ playerId ] = GetPlayerName( Players[ playerId ] )
set curColor = GetPlayerColor( Player( playerId ) )
set PlayerColor[ playerId ] = NormalPlayerColor[ GetHandleId( curColor ) ]
set startLocation = GetPlayerStartLocation( Players[ playerId ] )
set StartLocX [ playerId ] = GetStartLocationX( startLocation )
set StartLocY [ playerId ] = GetStartLocationY( startLocation )
set MBChain[ playerId ] = multiboardchain.create( Players[ playerId ] )
if PlayerActive[ playerId ] then
set PlayerName[ playerId ] = PlayerColor[ playerId ] + PlayerStartName[ playerId ]
call TriggerRegisterPlayerEvent( LEAVER_HANDLER, Players[ playerId ], EVENT_PLAYER_LEAVE )
else
set PlayerName[ playerId ] = LIGHTGREY + "Player " + I2S( playerId + 1 ) + GREY + " (N/A)" + WHITE
endif
set PlayerNameUncolored[ playerId ] = PlayerStartName[ playerId ]
set playerId = playerId + 1
endloop
if DISPLAY_LEAVER_NAME then
call TriggerAddAction( LEAVER_HANDLER, function LeaverHandlerName_Actions )
else
call TriggerAddAction( LEAVER_HANDLER, function LeaverHandlerNoName_Actions )
endif
call SetPlayerNameSJ( Players[ PLAYER_NEUTRAL_AGGRESSIVE ], "Neutral aggressive" )
call SetPlayerNameSJ( Players[ PLAYER_NEUTRAL_PASSIVE ], "Neutral passive" )
call SetPlayerNameSJ( Players[ bj_PLAYER_NEUTRAL_EXTRA ], "Neutral extra" )
call SetPlayerNameSJ( Players[ bj_PLAYER_NEUTRAL_VICTIM ], "Neutral victim" )
endfunction
function CreateColoredBountyText takes string color, integer bounty, unit target, player getter returns nothing
local texttag bountyText = CreateTextTag()
local effect bountyArt
if bounty > 0 then
call SetTextTagText ( bountyText, color + "+" + I2S( bounty ) + "|r", BountyTextSize )
elseif bounty < 0 then
call SetTextTagText ( bountyText, color + I2S( bounty ) + "|r", BountyTextSize )
else
call SetTextTagText ( bountyText, "", BountyTextSize )
endif
set bountyArt = AddSpecialEffectTarget( BountyEffectString, target, "overhead" )
call SetTextTagVelocity ( bountyText, 0, BountySpeed )
call SetTextTagPermanent( bountyText, false )
call SetTextTagAge ( bountyText, 0 )
call SetTextTagFadepoint( bountyText, 2 )
call SetTextTagLifespan ( bountyText, 3 )
call SetTextTagPosUnit ( bountyText, target, 0 )
if LOCAL_PLAYER != getter then
call SetTextTagVisibility( bountyText, false )
endif
call DestroyEffect( bountyArt )
set bountyText = null
set bountyArt = null
endfunction
function CreateBountyText takes integer bounty, unit target, player getter returns nothing
local texttag bountyText = CreateTextTag()
local effect bountyArt
if bounty > 0 then
call SetTextTagText ( bountyText, BountyColoring + I2S( bounty ) + "|r", BountyTextSize )
elseif bounty < 0 then
call SetTextTagText ( bountyText, RED + I2S( bounty ) + "|r", BountyTextSize )
else
call SetTextTagText ( bountyText, "", BountyTextSize )
endif
set bountyArt = AddSpecialEffectTarget( BountyEffectString, target, "overhead" )
call SetTextTagVelocity ( bountyText, 0, BountySpeed )
call SetTextTagPermanent( bountyText, false )
call SetTextTagAge ( bountyText, 0 )
call SetTextTagFadepoint( bountyText, 2 )
call SetTextTagLifespan ( bountyText, 3 )
call SetTextTagPosUnit ( bountyText, target, 0 )
if LOCAL_PLAYER != getter then
call SetTextTagVisibility( bountyText, false )
endif
call DestroyEffect( bountyArt )
set bountyText = null
set bountyArt = null
endfunction
function TriggerRegisterAnyPlayerChatEvent takes trigger whichtrigger, string chatmessagetodetect, boolean exactmatchonly returns nothing
local integer playerId = 0
loop
exitwhen playerId > NUMPLAYERS
call TriggerRegisterPlayerChatEvent( whichtrigger, Players[ playerId ], chatmessagetodetect, exactmatchonly )
set playerId = playerId + 1
endloop
endfunction
function CreateNUnits takes player owner, integer unittypeid, real x, real y, integer n returns group
call GroupClear( GLOBAL_GROUP )
loop
exitwhen n <= 0
call GroupAddUnit( GLOBAL_GROUP, CreateUnit( owner, unittypeid, x, y, GetRandomReal( 0, 360 ) ) )
set n = n - 1
endloop
return GLOBAL_GROUP
endfunction
function CreateNUnitsAngle takes player owner, integer unittypeid, real x, real y, real angle, integer n returns group
call GroupClear( GLOBAL_GROUP )
loop
exitwhen n <= 0
call GroupAddUnit( GLOBAL_GROUP, CreateUnit( owner, unittypeid, x, y, angle ) )
set n = n - 1
endloop
return GLOBAL_GROUP
endfunction
function CreateNUnitsOrder takes player owner, integer unittypeid, real x, real y, integer n, string order, real targetx, real targety returns group
local real angle = Atan2( y-targety, x-targetx )
local unit loopUnit
call GroupClear( GLOBAL_GROUP )
loop
exitwhen n <= 0
set loopUnit = CreateUnit( owner, unittypeid, x, y, angle )
call GroupAddUnit( GLOBAL_GROUP, loopUnit )
call IssuePointOrder( loopUnit, order, targetx, targety )
set n = n - 1
endloop
set loopUnit = null
return GLOBAL_GROUP
endfunction
function SetPlayerAllianceStateSJ takes player sourcePlayer, player otherPlayer, integer allianceState returns nothing
if (sourcePlayer == otherPlayer) then
return
endif
//this works like the normal BJ, just that it allies in both ways
if allianceState >= 0 and allianceState <= 8 then
call SetPlayerAlliance( sourcePlayer, otherPlayer, ALLIANCE_PASSIVE, PLAYER_ALLIANCE_STATE_PASSIVE[ allianceState ] )
call SetPlayerAlliance( sourcePlayer, otherPlayer, ALLIANCE_HELP_REQUEST, PLAYER_ALLIANCE_STATE_HELP_REQUEST[ allianceState ] )
call SetPlayerAlliance( sourcePlayer, otherPlayer, ALLIANCE_HELP_RESPONSE, PLAYER_ALLIANCE_STATE_HELP_RESPONSE[ allianceState ] )
call SetPlayerAlliance( sourcePlayer, otherPlayer, ALLIANCE_SHARED_XP, PLAYER_ALLIANCE_STATE_SHARED_SPELLS[ allianceState ] )
call SetPlayerAlliance( sourcePlayer, otherPlayer, ALLIANCE_SHARED_SPELLS, PLAYER_ALLIANCE_STATE_SHARED_SPELLS[ allianceState ] )
call SetPlayerAlliance( sourcePlayer, otherPlayer, ALLIANCE_SHARED_VISION, PLAYER_ALLIANCE_STATE_ALLIANCE_SHARED_CONTROL[ allianceState ] )
call SetPlayerAlliance( sourcePlayer, otherPlayer, ALLIANCE_SHARED_CONTROL, PLAYER_ALLIANCE_STATE_ALLIANCE_SHARED_CONTROL[ allianceState ] )
call SetPlayerAlliance( sourcePlayer, otherPlayer, ALLIANCE_SHARED_ADVANCED_CONTROL, PLAYER_ALLIANCE_STATE_ALLIANCE_SHARED_ADVANCED_CONTROL[ allianceState ] )
call SetPlayerAlliance( otherPlayer, sourcePlayer, ALLIANCE_PASSIVE, PLAYER_ALLIANCE_STATE_PASSIVE[ allianceState ] )
call SetPlayerAlliance( otherPlayer, sourcePlayer, ALLIANCE_HELP_REQUEST, PLAYER_ALLIANCE_STATE_HELP_REQUEST[ allianceState ] )
call SetPlayerAlliance( otherPlayer, sourcePlayer, ALLIANCE_HELP_RESPONSE, PLAYER_ALLIANCE_STATE_HELP_RESPONSE[ allianceState ] )
call SetPlayerAlliance( otherPlayer, sourcePlayer, ALLIANCE_SHARED_XP, PLAYER_ALLIANCE_STATE_SHARED_SPELLS[ allianceState ] )
call SetPlayerAlliance( otherPlayer, sourcePlayer, ALLIANCE_SHARED_SPELLS, PLAYER_ALLIANCE_STATE_SHARED_SPELLS[ allianceState ] )
call SetPlayerAlliance( otherPlayer, sourcePlayer, ALLIANCE_SHARED_VISION, PLAYER_ALLIANCE_STATE_ALLIANCE_SHARED_CONTROL[ allianceState ] )
call SetPlayerAlliance( otherPlayer, sourcePlayer, ALLIANCE_SHARED_CONTROL, PLAYER_ALLIANCE_STATE_ALLIANCE_SHARED_CONTROL[ allianceState ] )
call SetPlayerAlliance( otherPlayer, sourcePlayer, ALLIANCE_SHARED_ADVANCED_CONTROL, PLAYER_ALLIANCE_STATE_ALLIANCE_SHARED_ADVANCED_CONTROL[ allianceState ] )
endif
endfunction
function GetClosestUnitInRange takes real x, real y, real radius, boolean closest, boolexpr filter returns unit
local group g = GLOBAL_GROUP
local unit curUnit = null
local unit loopUnit
local real curDist
local real dX
local real dY
local real loopDist
call GroupClear( g )
call GroupEnumUnitsInRange( g, x, y, radius, filter )
if closest then
set curDist = radius + 1
else
set curDist = 0
endif
loop
set loopUnit = FirstOfGroup( g )
exitwhen loopUnit == null
set dX = x - GetUnitX( loopUnit )
set dY = y - GetUnitY( loopUnit )
set loopDist = SquareRoot( dX * dX + dY * dY )
if loopDist < curDist == closest then
set curDist = loopDist
set curUnit = loopUnit
endif
call GroupRemoveUnit( g, loopUnit )
endloop
set ReturnHandle = curUnit
set filter = null
set loopUnit = null
set curUnit = null
return ReturnHandle
endfunction
function EndMap takes nothing returns nothing
call EndGame( true )
endfunction
function WinGame takes player whichPlayer, boolean win, string message returns nothing
local trigger t = CreateTrigger()
local dialog d = DialogCreate ()
local player localPlayer = LOCAL_PLAYER
if win then
call RemovePlayer ( whichPlayer, PLAYER_GAME_RESULT_VICTORY )
else
call RemovePlayer ( whichPlayer, PLAYER_GAME_RESULT_DEFEAT )
endif
call DialogSetMessage ( d, message )
call TriggerRegisterDialogButtonEvent( t, DialogAddButton( d, "Ok", GetLocalizedHotkey("GAMEOVER_CONTINUE") ) )
call TriggerAddAction ( t, function EndMap )
if localPlayer == whichPlayer then
call EnableUserControl( true )
call EnableUserUI ( false )
endif
call DialogDisplay( whichPlayer, d, true )
endfunction
function SetMultiboardItemValue takes multiboard mb, integer row, integer col, string value, string iconfilename, real width, player whichplayer returns nothing
local multiboarditem curItem
local boolean showIcon = iconfilename != ""
local boolean showValue = value != ""
local boolean changeWidth = width > 0
local integer minCol
local integer maxCol
local integer minRow
local integer maxRow
local integer i
local integer j
if col == - 1 then
set minCol = 0
set maxCol = MultiboardGetColumnCount( mb )
else
set minCol = col
set maxCol = col + 1
endif
if row == -1 then
set minRow = 0
set maxRow = MultiboardGetRowCount( mb )
else
set minRow = row
set maxRow = row + 1
endif
set col = minCol
loop
exitwhen col >= maxCol
set row = minRow
loop
exitwhen row >= maxRow
set curItem = MultiboardGetItem( mb, row, col )
if whichplayer == null or whichplayer == LOCAL_PLAYER then
call MultiboardSetItemStyle( curItem, showValue, showIcon )
if showIcon then
call MultiboardSetItemIcon( curItem, iconfilename )
endif
if showValue then
call MultiboardSetItemValue( curItem, value )
endif
if changeWidth then
call MultiboardSetItemWidth( curItem, width )
endif
endif
call MultiboardReleaseItem( curItem )
set row = row + 1
endloop
set col = col + 1
endloop
endfunction
function Char2I takes string char, integer min, integer max returns integer
local integer index
local string toInt = SubString( char, min, max )
local integer stringPos = StringLength( toInt ) - 1
local integer stringValue = 1
local string curChar
local integer returnValue = 0
set char = StringCase( toInt, false )
loop
exitwhen stringPos < 0
set index = 0
set curChar = SubString( char, stringPos, stringPos + 1 )
loop
exitwhen index == LETTERS
if curChar == LETTER[ index ] then
set returnValue = returnValue + index * stringValue
exitwhen true
endif
set index = index + 1
endloop
set stringValue = stringValue * LETTERS
set stringPos = stringPos - 1
endloop
return returnValue
endfunction
function I2Char takes integer i returns string
local string returnString = ""
local integer curValue
loop
exitwhen i == 0
set curValue = ModuloInteger( i, LETTERS )
if curValue != 0 then
set returnString = LETTER[ curValue ] + returnString
endif
set i = i / LETTERS
endloop
return returnString
endfunction
//! textmacro RandomString takes SCOPE, NAME
globals
private string array $NAME$
private integer $NAME$s = -1
endglobals
$SCOPE$ function Get$NAME$String takes nothing returns string
return $NAME$[GetRandomInt( 0, $NAME$s )]
endfunction
$SCOPE$ function Add$NAME$String takes string toadd returns nothing
set $NAME$s = $NAME$s + 1
set $NAME$[ $NAME$s ] = toadd
endfunction
//! endtextmacro
endlibrary
//TESH.scrollpos=-1
//TESH.alwaysfold=0
library Debug initializer INIT
globals
debug constant string BADColor = "|cffff0303"
debug constant string MSGColor = "|cffffcc00"
debug constant string normtag = BADColor + "DEBUG! "
debug constant string entertag = BADColor + "ENTER> "
debug constant string leavetag = BADColor + "LEAVE> "
debug constant string end = "|r"
debug debugger STDERR
debug constant trigger TraceTrigger = CreateTrigger()
endglobals
//! textmacro ASSERT_FUNC takes NAME, TYPE, CONVERTER
method assert$NAME$ takes $TYPE$ check, $TYPE$ assert returns boolean
local boolean bool = check == assert
debug set .assertions = .assertions + 1
debug if bool then
debug call .Debug( MSGColor + "Assertion passed: " + $CONVERTER$( check ) )
debug else
debug call .Debug( "Assertion" + BADColor + " FAILED:" + MSGColor + " Expected: '" + $CONVERTER$( assert ) + "'; Got: '" + $CONVERTER$( check ) + "'" )
debug set .errors = .errors + 1
debug endif
return bool
endmethod
//! endtextmacro
private function H2I takes handle h returns integer
return h
return 0
endfunction
private function H2S takes handle h returns string
return "H"+I2S( H2I(h) - 0x100000 )
endfunction
private function B2S takes boolean b returns string
if b then
return "true"
endif
return "false"
endfunction
struct trace
debug debugger parent
debug trace next
debug trace last
debug string msg
debug string show
debug string indent
static method create takes debugger parent, string msg returns trace
local trace this = .allocate()
debug set .parent = parent
debug set .indent = .parent.INDENT
debug set .msg = msg
debug set .show = BADColor + .parent.INDENT + msg
debug if .parent.first == 0 then
debug set .last = 0
debug set .parent.first = this
debug else
debug set .last = .parent.last
debug set .last.next = this
debug endif
debug set .next = 0
debug set .parent.last = this
return this
endmethod
method onDestroy takes nothing returns nothing
debug call .next.destroy()
endmethod
method operator to_s takes nothing returns string
debug local player p = GetLocalPlayer()
debug if .last == 0 then
debug call DisplayTimedTextToPlayer( p, 0, 0, 60, "\n---TRACE---\n")
debug endif
debug call DisplayTimedTextToPlayer( p, 0, 0, 60, "TRACE--> " + .show )
debug if .next == 0 then
debug call DisplayTimedTextToPlayer( p, 0, 0, 60, "\n---ENDTRACE---\n")
debug return .show + "\n\n"
debug else
debug return .show + "\n" + .next.to_s
debug endif
return ""
endmethod
method append takes string toAppend returns nothing
debug call trace.create( .parent, toAppend )
endmethod
endstruct
struct msgstack
debug debugger parent
debug msgstack next
debug msgstack last
debug string msg
static method create takes debugger parent, string msg returns msgstack
local msgstack this = .allocate()
debug set .parent = parent
debug set .msg = msg
debug if .parent.firstMSG == 0 then
debug set .last = 0
debug set .parent.firstMSG = this
debug else
debug set .last = .parent.lastMSG
debug set .last.next = this
debug endif
debug set .next = 0
debug set .parent.lastMSG = this
debug set .parent.lastInMSG = msg
return this
endmethod
method onDestroy takes nothing returns nothing
debug set .last.next = 0
debug set .parent.lastMSG = .last
debug set .parent.lastInMSG = .last.msg
endmethod
method append takes string toAppend returns nothing
debug call msgstack.create( .parent, toAppend )
endmethod
endstruct
struct debugger
debug delegate trace first
debug trace last
debug msgstack firstMSG
debug msgstack lastMSG
debug string nameID = "BAD DEBUGGER"
debug string lastInMSG
debug string msg
debug integer depth
debug integer id
debug integer assertions
debug integer errors
debug static integer count = 0
debug private static debugger array self
static method operator [] takes integer index returns debugger
debug return .self[ index ]
return 0
endmethod
method operator name takes nothing returns string
debug return .nameID + " (#" + I2S( .id ) + ")"
return ""
endmethod
method operator INDENT takes nothing returns string
debug local integer i = 0
debug local string s = MSGColor + " "
debug loop
debug exitwhen i >= .depth
debug set s = s + " "
debug set i = i + 1
debug endloop
debug return s
return ""
endmethod
static method create takes string name returns debugger
local debugger this = .allocate()
debug set .nameID = BADColor + StringCase( name, true )
debug set .msg = StringCase( name, false )
debug set .id = .count
debug set .last = 0
debug set .first = 0
debug set .self[ .id ] = this
debug set .count = .count + 1
debug set .depth = 0
debug set .lastInMSG = this.name
debug call msgstack.create( this, .name + ".INIT" )
debug call trace.create( this, "---TRACING: " + .name + " ---\n" )
return this
endmethod
method Shout takes string debugtag, string MSG returns nothing
debug call DisplayTimedTextToPlayer( GetLocalPlayer(), 0, 0, 60, .name + "." + debugtag + .INDENT + MSG + end )
debug call .append( debugtag + MSG )
endmethod
method Debug takes string MSG returns nothing
debug call .Shout( normtag, MSGColor + MSG )
endmethod
method operator InMSG= takes string MSG returns nothing
debug call .Shout( entertag, BADColor + "start '" + MSG + "'" )
debug call .lastMSG.append( MSG )
debug set .depth = .depth + 1
endmethod
method Out takes string outMSG returns nothing
debug if .assertString( outMSG, .lastInMSG ) then
debug set .depth = .depth - 1
debug call .lastMSG.destroy()
debug call .Shout( leavetag, BADColor + "end '" + outMSG + "'" )
debug else
debug set .depth = .depth - 1
debug call .Shout( normtag, BADColor + "Bad Out Message: " + outMSG )
debug endif
endmethod
method onDestroy takes nothing returns nothing
debug call .Debug( "DESTRUCTION" )
debug loop
debug exitwhen .depth <= 0
debug call .Out( .lastInMSG )
debug endloop
debug call .first.destroy()
endmethod
method operator state takes nothing returns string
debug return MSGColor + "\nAssertions: " + I2S( .assertions ) + "\nFails: " + I2S( .errors ) + "\nLast In: " + .lastInMSG
return "Debug mode deactivated."
endmethod
//! runtextmacro ASSERT_FUNC( "Integer", "integer", "I2S" )
//! runtextmacro ASSERT_FUNC( "Boolean", "boolean", "B2S" )
//! runtextmacro ASSERT_FUNC( "Real", "real", "R2S" )
//! runtextmacro ASSERT_FUNC( "String", "string", "" )
//! runtextmacro ASSERT_FUNC( "Id", "integer", "GetObjectName" )
//! runtextmacro ASSERT_FUNC( "Handle", "handle", "H2S" )
endstruct
function CreateDebugger takes string name returns debugger
return debugger.create( name )
endfunction
function DebugMSG takes debugger db, string MSG returns nothing
debug call db.Debug( MSG )
endfunction
function InMSG takes debugger db, string MSG returns nothing
debug set db.InMSG = MSG
endfunction
function OutMSG takes debugger db, string MSG returns nothing
debug call db.Out( MSG )
endfunction
//! textmacro DebugArray takes ARRAY , CONVERTER
function Debug$ARRAY$ takes debugger db, integer start, integer end returns nothing
debug local integer iterator = start
debug loop
debug exitwhen iterator > end
debug call db.Debug( $CONVERTER$( $ARRAY$[iterator] ) )
debug set iterator = iterator + 1
debug endloop
endfunction
//! endtextmacro
private function TraceTrigger_Actions takes nothing returns nothing
debug local integer i = 0
debug local integer j = 0
debug local string eventString = StringCase( SubString( GetEventPlayerChatString(), 7, 20 ), false )
debug local string inString = "TRACEBACK: " + eventString
debug set STDERR.InMSG = inString
debug loop
debug exitwhen i >= debugger.count
debug if debugger[ i ].msg == eventString then
debug set j = j + 1
debug call DisplayTimedTextToPlayer( GetLocalPlayer(), 0, 0, 10, normtag + debugger[ i ].state )
debug call TriggerSleepAction( 2.00 )
debug if debugger[ i ].to_s == "" then
debug endif
debug endif
debug set i = i + 1
debug endloop
debug call STDERR.Out( inString )
endfunction
private function INIT takes nothing returns nothing
debug local integer i = 0
debug local player p = null
debug loop
debug exitwhen i > 11
debug set p = Player( i )
debug call TriggerRegisterPlayerChatEvent( TraceTrigger, p, "-trace ", false )
debug call TriggerRegisterPlayerChatEvent( TraceTrigger, p, "-check ", false )
debug call TriggerRegisterPlayerChatEvent( TraceTrigger, p, "-debug ", false )
debug set i = i + 1
debug endloop
debug call TriggerAddAction( TraceTrigger, function TraceTrigger_Actions )
set STDERR = debugger.create( "STDERR" )
endfunction
endlibrary
//TESH.scrollpos=61
//TESH.alwaysfold=0
library Tutorial initializer INIT needs GetPlayerFeedback
globals
private constant trigger TutTrigger = CreateTrigger()
private boolean array WatchesTutorial
private integer array CurHelpMessage
private string array HelpMessage
private integer HelpMessages = 0
private integer Watchers = 0
private constant integer REVEAL_TIME = 15
private constant timer REVEAL_TIMER = CreateTimer()
endglobals
private keyword SetPlayerWatchState
private function TutorialMessage takes player whichplayer, string msg returns nothing
call DisplayTimedTextToPlayer( whichplayer, 0.5, 0.8, REVEAL_TIME, LIGHTGREY + msg )
endfunction
function AddTutorialMessage takes string msg returns nothing
set HelpMessage[ HelpMessages ] = msg
set HelpMessages = HelpMessages + 1
endfunction
private function ShowNextMessage takes nothing returns nothing
local integer i = 2
loop
exitwhen i > MAX_USER_SLOT
if WatchesTutorial[ i ] then
if CurHelpMessage[ i ] == HelpMessages then
set CurHelpMessage[ i ] = 0
call SetPlayerWatchState.execute( i, false )
else
if LOCAL_PLAYER == Players[ i ] then
call ClearTextMessages()
endif
call TutorialMessage( Players[ i ], HelpMessage[ CurHelpMessage[ i ] ] )
set CurHelpMessage[ i ] = CurHelpMessage[ i ] + 1
endif
endif
set i = i + 1
endloop
endfunction
private function SetPlayerWatchState takes integer playerId, boolean watches returns nothing
if watches == WatchesTutorial[ playerId ] then
elseif watches then
if Watchers == 0 then
call TimerStart( REVEAL_TIMER, REVEAL_TIME, true, function ShowNextMessage )
endif
set Watchers = Watchers + 1
set ShowMessages[ playerId ] = false
else
set Watchers = Watchers - 1
set ShowMessages[ playerId ] = true
if Watchers == 0 then
call PauseTimer( REVEAL_TIMER )
endif
endif
set WatchesTutorial[ playerId ] = watches
endfunction
private function Tutorial_Index takes nothing returns nothing
local player trigPlayer = GetTriggerPlayer()
local integer trigId = GetPlayerId( trigPlayer )
local boolean reset = GetPlayerFeedback( trigPlayer )
if reset then
set CurHelpMessage[trigId] = 0
endif
endfunction
private function Actions takes nothing returns nothing
local player trigPlayer = GetTriggerPlayer()
local integer trigId = GetPlayerId( trigPlayer )
call SetPlayerWatchState( trigId, not WatchesTutorial[ trigId ] )
if WatchesTutorial[ trigId ] then
if LOCAL_PLAYER == trigPlayer then
call ClearTextMessages()
endif
call TutorialMessage( trigPlayer, "Tutorial started. You can turn it off with the command you used to turn it on." )
else
if LOCAL_PLAYER == trigPlayer then
call ClearTextMessages()
endif
call TutorialMessage( trigPlayer, "Tutorial stopped." )
call AskPlayerFeedback( trigPlayer, "Reset tutorial index?", function Tutorial_Index )
endif
endfunction
private function INIT_REALLY takes nothing returns nothing
call TriggerRegisterAnyPlayerChatEvent( TutTrigger, "-start tut", false )
call TriggerRegisterAnyPlayerChatEvent( TutTrigger, "-tutorial", true )
call TriggerRegisterAnyPlayerChatEvent( TutTrigger, "-help", true )
call TriggerAddAction( TutTrigger, function Actions )
endfunction
private function INIT takes nothing returns nothing
call ExecuteFunc( SCOPE_PRIVATE + "INIT_REALLY" )
endfunction
endlibrary
//TESH.scrollpos=116
//TESH.alwaysfold=0
//! runtextmacro AddUnitValue( "WeaponSet", "onboardweapon", "-1" )
library NewWeap needs Utilities
globals
constant trigger TargetTrigger = CreateTrigger()
constant integer MAX_WEAPONS_PER_PLAYER = 8
player FilterPlayer = null
boolexpr WeaponFilter_Expr
boolean array TargetShip[MAX_USER_SLOT]
weaponarray array PlayerWeapons[MAX_USER_SLOT]
targetstruct array Target_Strutct
endglobals
type weapontypearray extends integer array [ MAX_WEAPONS_PER_PLAYER, HashSlots ]
type weaponarray extends unit array [ MAX_WEAPONS_PER_PLAYER, HashSlots ]
function TargetPlayerWeapons takes player toPause, unit target returns nothing
local integer i = 0
local integer trigId = GetPlayerId( toPause )
loop
exitwhen i >= MAX_WEAPONS_PER_PLAYER
exitwhen PlayerWeapons[ trigId ][ i ] == null
call IssueTargetOrder( PlayerWeapons[ trigId ][ i ], "attack", target )
set i = i + 1
endloop
endfunction
function PausePlayerWeapons takes player toPause, boolean pause returns nothing
local integer i = 0
local integer trigId = GetPlayerId( toPause )
loop
exitwhen i >= MAX_WEAPONS_PER_PLAYER
exitwhen PlayerWeapons[ trigId ][ i ] == null
call PauseUnit( PlayerWeapons[ trigId ][ i ], pause )
set i = i + 1
endloop
endfunction
function UpdatePos takes nothing returns nothing
local integer i = 0
local integer j
local real x
local real y
loop
exitwhen i > MAX_USER_SLOT
set x = GetUnitX( Hero[ i ] )
set y = GetUnitY( Hero[ i ] )
set j = 0
loop
exitwhen j >= MAX_WEAPONS_PER_PLAYER
exitwhen PlayerWeapons[ i ][ j ] == null
call SetUnitX( PlayerWeapons[ i ][ j ], x )
call SetUnitY( PlayerWeapons[ i ][ j ], y )
set j = j + 1
endloop
set i = i + 1
endloop
endfunction
private function IsFilterUnitHero takes nothing returns boolean
return IsUnitType( GetFilterUnit(), UNIT_TYPE_HERO ) == true
endfunction
private function WeaponFilter takes nothing returns boolean
local unit filter = GetFilterUnit()
local boolean b = GetUnitState(filter, UNIT_STATE_LIFE) > 0 and IsUnitEnemy( filter, FilterPlayer )
set filter = null
return b
endfunction
function ForceRandomTarget takes unit whichunit returns nothing
local unit target
set FilterPlayer = GetOwningPlayer( whichunit )
call GroupEnumUnitsInRange( GLOBAL_GROUP, GetUnitX( whichunit ), GetUnitY( whichunit ), GetUnitAcquireRange( whichunit ), WeaponFilter_Expr )
set target = GroupPickRandomUnit( GLOBAL_GROUP )
call IssueTargetOrder( whichunit, "attack", target )
set target = null
endfunction
private function WeaponsUpdater_Actions takes nothing returns nothing
local unit enterUnit = GetTriggerUnit()
local integer trigId = GetPlayerId( GetOwningPlayer( enterUnit ) )
local unit trigUnit = Hero[trigId]
local onboardweapon trigWeapons = GetUnitTypeWeaponSet( GetUnitTypeId( trigUnit ) )
local player owner = Players[ trigId ]
if trigWeapons != -1 then
call trigWeapons.exchangeWeapons( owner )
endif
set trigUnit = null
endfunction
private function TargetTrigger_Actions takes nothing returns nothing
local unit trigUnit = GetAttacker()
local player owner = GetOwningPlayer( trigUnit )
local integer ownerId = GetPlayerId( owner )
if ( not TargetShip[ ownerId ] ) and IsUnitType( trigUnit, UNIT_TYPE_GIANT ) then
call ForceRandomTarget( trigUnit )
endif
set trigUnit = null
endfunction
private function INIT takes nothing returns nothing
local integer i = 0
local region mapReg = CreateRegion()
call RegionAddRect( mapReg, GetWorldBounds() )
loop
exitwhen i > MAX_USER_SLOT
set PlayerWeapons[ i ] = weaponarray.create()
set i = i + 1
endloop
call TimerStart( GetExpiredTimer( ), 0.33, true, function UpdatePos )
call TriggerRegisterEnterRegion( onboardweapon.WeaponsUpdater, mapReg, Condition( function IsFilterUnitHero ) )
call TriggerAddAction( onboardweapon.WeaponsUpdater, function WeaponsUpdater_Actions )
call TriggerRegisterAnyUnitEventBJ( TargetTrigger, EVENT_PLAYER_UNIT_ATTACKED )
call TriggerAddAction( TargetTrigger, function TargetTrigger_Actions )
set WeaponFilter_Expr = Filter( function WeaponFilter )
set mapReg = null
endfunction
private function UpdateTargets takes nothing returns nothing
local integer i = 0
local targetstruct curStruct
loop
exitwhen i >= targetstruct.count
set curStruct = targetstruct.self[ i ]
set curStruct.ticks = curStruct.ticks + 1
if GetUnitState( curStruct.weapon, UNIT_STATE_LIFE ) <= 0 then
call curStruct.destroy()
elseif curStruct.ticks >= 8 then
call ForceRandomTarget( curStruct.weapon )
set curStruct.ticks = 0
endif
set i = i + 1
endloop
endfunction
struct onboardweapon
weapontypearray weaponId
integer unitId
string name
static constant trigger WeaponsUpdater = CreateTrigger()
static method onInit takes nothing returns nothing
call TimerStart( CreateTimer(), 0.00, false, function INIT )
endmethod
static method create takes integer unitId, weapontypearray weaponId returns onboardweapon
local onboardweapon this = .allocate()
local integer i = 0
set .unitId = unitId
set .weaponId = weaponId
call SetUnitTypeWeaponSet( unitId, this )
set .name = GetObjectName( unitId )
return this
endmethod
method exchangeWeapons takes player tochange returns nothing
local integer i = 0
local integer trigId = GetPlayerId( tochange )
local unit trigUnit = Hero[ trigId ]
local real x = GetUnitX( trigUnit )
local real y = GetUnitY( trigUnit )
local targetstruct curStruct
set TargetShip[ trigId ] = GetUnitShipId( trigUnit ) == SHIP_TYPE_TARGET
loop
exitwhen i >= MAX_WEAPONS_PER_PLAYER
if PlayerWeapons[ trigId ][ i ] != null then
call KillUnit( PlayerWeapons[ trigId ][ i ] )
endif
if .weaponId[ i ] != 0 then
set PlayerWeapons[ trigId ][ i ] = CreateUnit( tochange, .weaponId[ i ], x, y, 270 )
if TargetShip[ trigId ] then
set curStruct = targetstruct.create( PlayerWeapons[ trigId ][ i ] )
set curStruct.ticks = GetRandomInt( 0, 7 )
endif
else
set PlayerWeapons[ trigId ][ i ] = null
endif
set i = i + 1
endloop
set trigUnit = null
endmethod
endstruct
struct targetstruct
integer playerId
unit weapon
integer ticks
integer index
static integer count = 0
static constant timer ticker = CreateTimer()
static targetstruct array self
static method create takes unit whichUnit returns targetstruct
local targetstruct this = .allocate()
set .weapon = whichUnit
set .playerId = GetPlayerId( GetOwningPlayer( .weapon ) )
if .count == 0 then
call TimerStart( .ticker, 0.30, true, function UpdateTargets )
endif
set .self[ .count ] = this
set .index = .count
set .count = .count + 1
set .ticks = 0
return this
endmethod
private method onDestroy takes nothing returns nothing
set .count = .count - 1
set .self[ .index ] = .self[ .count ]
set .self[ .index ].index = .index
set .self[ .count ] = 0
set .weapon = null
if .count == 0 then
call PauseTimer( .ticker )
endif
endmethod
endstruct
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
// This can switch items
// Simply create a switch with
// //! runtextmacro Switcher( NAME )
// Then add Items to it using
// call SetNAMEPair( item1id, item2id )
// afterwards you can switch with
// call SwitchNAME( item )
//EXAMPLE:
// //! runtextmacro Switcher( "Active" )
//...
// call SetActivePair( 'I000', 'I001' )
// set udg_MyItem = Switch( udg_MyItem )
//...
//! runtextmacro AddItemValue( "SwapId", "integer", "-1" )
//! textmacro Switcher takes NAME
library $NAME$Switcher needs SwapIdAttacherItem, Hash
globals
private hashtable IdHash
endglobals
function Set$NAME$Pair takes integer itemtypeidA, integer itemtypeidB returns nothing
local integer swapidA = GetItemTypeSwapId( itemtypeidA )
local integer swapidB = GetItemTypeSwapId( itemtypeidB )
if swapidA != -1 then
call SetItemTypeSwapId( swapidA, -1 )
endif
if swapidB != -1 then
call SetItemTypeSwapId( swapidB, -1 )
endif
call SetItemTypeSwapId( itemtypeidA, itemtypeidB )
call SetItemTypeSwapId( itemtypeidB, itemtypeidA )
endfunction
function Switch$NAME$ takes item toswitch returns item
local integer itemId = GetItemTypeId( toswitch )
local integer swapId = GetItemTypeSwapId( itemId )
local real x = GetItemX( toswitch )
local real y = GetItemY( toswitch )
if swapId != -1 then
call RemoveItem( toswitch )
set toswitch = null
set bj_lastCreatedItem = CreateItem( swapId, x, y )
return bj_lastCreatedItem
endif
return null
endfunction
private function Init takes nothing returns nothing
set IdHash = hashtable.create()
endfunction
endlibrary
//! endtextmacro
//TESH.scrollpos=-1
//TESH.alwaysfold=0
// upgrades Items from A -> B
//! runtextmacro AddItemValue( "UpgradeId", "integer", "-1" )
//! runtextmacro Attach( "UpgradeType", "integer", "integer", "REQ_NONE" )
//! runtextmacro Attach( "ShipRequirements", "integer", "reqarray", "0" )
library ItemUpgrader needs UpgradeIdAttacherItem, Utilities, NewWeap
globals
// parameters
private constant integer ProgressItemId = 'I00K'
constant integer REQ_TYPES = 4
constant integer SHIP_TYPES = 3
// end of parameters
constant integer REQ_POW = 0
constant integer REQ_CARGO = 0
constant integer REQ_CD = 1
constant integer REQ_PROFIT = 1
constant integer REQ_SAILS = 2
constant integer REQ_HULL = 3
constant integer REQ_NONE = -1
string array REQ_NAME[SHIP_TYPES][REQ_TYPES]
integer array ItemLevels[MAX_USER_SLOT][REQ_TYPES]
private string array reqString
endglobals
struct reqarray
private integer array req[REQ_TYPES]
private string array reqString[SHIP_TYPES]
method getStringIndex takes integer req, integer shipId returns integer
return this * REQ_TYPES * SHIP_TYPES + req * SHIP_TYPES + shipId
endmethod
private method setString takes integer stringIndex, string reqstring returns nothing
set reqString[ stringIndex ] = reqstring
endmethod
private method getString takes integer stringIndex returns string
return reqString[ stringIndex ]
endmethod
static method create takes integer pow, integer cd, integer sails, integer hull returns reqarray
local reqarray this = .allocate()
local integer i = 0
local integer j = 0
local integer index
set .req[ REQ_POW ] = pow
set .req[ REQ_CD ] = cd
set .req[ REQ_SAILS ] = sails
set .req[ REQ_HULL ] = hull
loop
exitwhen i >= REQ_TYPES
if .req[ i ] > 0 then
set j = 0
set index = .getStringIndex( i, j )
loop
exitwhen j >= SHIP_TYPES
call .setString( index + j, LIGHTGREY + REQ_NAME[j][i] + ": " + GOLD + I2S( .req[ i ] + 1 ) )
set j = j + 1
endloop
endif
set i = i + 1
endloop
return this
endmethod
method check takes player tocheck returns boolean
local integer i = 0
local integer id = GetPlayerId( tocheck )
loop
exitwhen i >= REQ_TYPES
if .req[ i ] > ItemLevels[ id ][ i ] then
return false
endif
set i = i + 1
endloop
return true
endmethod
method to_s takes integer id returns string
local integer i = 0
local string nlString = " "
local string result = ""
local integer j = GetUnitShipId( Hero[ id ] )
local integer index
loop
exitwhen i >= REQ_TYPES
if .req[ i ] > ItemLevels[ id ][ i ] then
set index = .getStringIndex( i, j )
set result = result + nlString + .getString( index )
set nlString = "\n "
endif
set i = i + 1
endloop
return result
endmethod
endstruct
function SetUnitRequirements takes integer unitId, integer pow, integer cd, integer sails, integer hull returns nothing
set ShipRequirements[ unitId ] = reqarray.create( pow, cd, sails, hull )
endfunction
globals
public integer array UpgradeTarget
public integer array UpgradeCost
public integer Upgrades = 0
integer array PlayerUpgrades
integer array TotalPlayerUpgrades
endglobals
private struct upgradedata
item progressItem
unit upgradeUnit
integer charges
integer target
integer base
private static upgradedata array Data
private static integer count = -1
private integer position
static constant timer upgrader = CreateTimer()
static method create takes unit upgradeunit, integer base, integer target returns upgradedata
local upgradedata this = .allocate()
set .progressItem = CreateItem( ProgressItemId, 0, 0 )
set .charges = GetItemCharges( .progressItem )
set .base = base
set .target = target
set .upgradeUnit = upgradeunit
set .count = .count + 1
set .position = .count
set .Data[ .position ] = this
call UnitAddItem( .upgradeUnit, .progressItem )
return this
endmethod
static method onInit takes nothing returns nothing
call TimerStart( .upgrader, 1, true, function upgradedata.runUpgrades )
set REQ_NAME[ SHIP_TYPE_NORMAL ][ REQ_POW ] = "Damage"
set REQ_NAME[ SHIP_TYPE_NORMAL ][ REQ_CD ] = "Cooldown"
set REQ_NAME[ SHIP_TYPE_NORMAL ][ REQ_SAILS ] = "Sails"
set REQ_NAME[ SHIP_TYPE_NORMAL ][ REQ_HULL ] = "Hull"
set REQ_NAME[ SHIP_TYPE_TRADER ][ REQ_PROFIT ] = "Profit"
set REQ_NAME[ SHIP_TYPE_TRADER ][ REQ_CARGO ] = "Cargo"
set REQ_NAME[ SHIP_TYPE_TRADER ][ REQ_SAILS ] = "Sails"
set REQ_NAME[ SHIP_TYPE_TRADER ][ REQ_HULL ] = "Hull"
set REQ_NAME[ SHIP_TYPE_TARGET ][ REQ_POW ] = "Damage"
set REQ_NAME[ SHIP_TYPE_TARGET ][ REQ_CD ] = "Cooldown"
set REQ_NAME[ SHIP_TYPE_TARGET ][ REQ_SAILS ] = "Sails"
set REQ_NAME[ SHIP_TYPE_TARGET ][ REQ_HULL ] = "Hull"
endmethod
method onDestroy takes nothing returns nothing
set .Data[ .position ] = .Data[ .count ]
set .Data[ .count ].position = .position
set .Data[ .count ] = 0
set .count = .count - 1
call RemoveItem( .progressItem )
call SetUnitCargo( .upgradeUnit, GetUnitCargo( .upgradeUnit ) - GetItemTypeWeight( .target ) )
set .progressItem = null
set .upgradeUnit = null
endmethod
static method runUpgrades takes nothing returns nothing
local integer i = 0
loop
exitwhen i > .count
call .Data[ i ].upgrade()
set i = i + 1
endloop
endmethod
method upgrade takes nothing returns nothing
local integer itemCharges = GetItemCharges( .progressItem )
local item result
local unit trigUnit = .upgradeUnit
local player owner
local integer trigId
local integer index = GetItemTypeUpgradeId( .base )
local string baseName
local string upgradeName
local integer upgradeType
//local integer room = GetUnitMaxCargo( trigUnit ) - GetUnitCargo( trigUnit )
//if .reqCargo > room then
// set owner = GetOwningPlayer( trigUnit )
// set trigId = GetPlayerId( owner )
// set result = CreateItem( .base, 0, 0 )
// call DisplayText( owner, RED + "Not enough free cargo. Upgrade cancelled." )
// call SetPlayerState( owner, PLAYER_STATE_RESOURCE_GOLD, GetPlayerState( owner, PLAYER_STATE_RESOURCE_GOLD ) + UpgradeCost[ index ] )
// call .destroy()
// call UnitAddItem( trigUnit, result )
// set PlayerUpgrades[ trigId ] = PlayerUpgrades[ trigId ] - 1
//else
if itemCharges < .charges then
set owner = GetOwningPlayer( trigUnit )
set trigId = GetPlayerId( owner )
set result = CreateItem( .base, 0, 0 )
call DisplayText( owner, RED + "Upgrade cancelled." )
call SetPlayerState( owner, PLAYER_STATE_RESOURCE_GOLD, GetPlayerState( owner, PLAYER_STATE_RESOURCE_GOLD ) + UpgradeCost[ index ] )
call .destroy()
call UnitAddItem( trigUnit, result )
set PlayerUpgrades[ trigId ] = PlayerUpgrades[ trigId ] - 1
set BankSys_LastGold[ trigId ] = BankSys_LastGold[ trigId ] + UpgradeCost[ index ]
elseif GetUnitState( trigUnit, UNIT_STATE_LIFE ) > 0 then
set .charges = .charges - 1
if .charges == 0 then
set owner = GetOwningPlayer( trigUnit )
set trigId = GetPlayerId( owner )
call RemoveItem( .progressItem )
call AddBilance( trigId, -UpgradeCost[ index ], "Upgrades" )
if ShowMessages[ trigId ] then
call DisplayText( owner, GREEN + "Upgrade Finished." )
endif
set result = CreateItem( .target, 0, 0 )
set upgradeType = UpgradeType[ .target ]
if upgradeType != REQ_NONE then
set ItemLevels[ trigId ][ upgradeType ] = ItemLevels[ trigId ][ upgradeType ] + 1
if upgradeType == REQ_PROFIT and GetUnitShipId( trigUnit ) == SHIP_TYPE_TRADER then
set TradeSystem_Multiplier[ trigId ] = Profit[ ItemLevels[ trigId ][ upgradeType ] ]
endif
endif
call .destroy()
call UnitAddItem( trigUnit, result )
set PlayerUpgrades[ trigId ] = PlayerUpgrades[ trigId ] - 1
else
call SetItemCharges( .progressItem, .charges )
endif
endif
if PlayerUpgrades[ trigId ] == 0 then
call PausePlayerWeapons( owner, false )
endif
set result = null
endmethod
endstruct
function SetItemUpgrade takes integer basetypeid, integer upgradetypeid, integer cost returns nothing
local integer index = GetItemTypeUpgradeId( basetypeid )
if index == -1 then
call SetItemTypeUpgradeId( basetypeid, Upgrades )
set index = Upgrades
set Upgrades = Upgrades + 1
endif
set UpgradeCost[ index ] = cost
set UpgradeTarget[ index ] = upgradetypeid
call SetItemTypeCost( upgradetypeid, GetItemTypeCost( basetypeid ) + cost )
// call DisplayText( LOCAL_PLAYER, LIGHTGREY + GetObjectName( upgradetypeid ) + ": " + GOLD + I2S( GetItemTypeCost( basetypeid ) + cost ) )
endfunction
function Upgrade takes unit trigUnit, item whichitem returns nothing
local integer typeId = GetItemTypeId( whichitem )
local integer index = GetItemTypeUpgradeId( typeId )
local integer gold
local real x
local real y
local string baseName
local string upgradeName
local player owner = null
local integer trigId
local integer reqRoom = GetItemTypeWeight( UpgradeTarget[ index ] ) - GetItemTypeWeight( typeId )
local integer room = GetUnitMaxCargo( trigUnit ) - GetUnitCargo( trigUnit )
if index != -1 then
if trigUnit == null then
set gold = 0
else
set owner = GetOwningPlayer( trigUnit )
set gold = GetPlayerState( owner, PLAYER_STATE_RESOURCE_GOLD ) - UpgradeCost[ index ]
endif
if room >= reqRoom then
if gold >= 0 then
if reqRoom > 0 then
call RemoveItem( whichitem )
call SetUnitCargo( trigUnit, GetUnitCargo( trigUnit ) + GetItemTypeWeight( UpgradeTarget[ index ] ) )
else
call SetUnitCargo( trigUnit, GetUnitCargo( trigUnit ) + GetItemTypeWeight( UpgradeTarget[ index ] ) )
call RemoveItem( whichitem )
endif
if owner != null then
set trigId = GetPlayerId( owner )
set BankSys_LastGold[ trigId ] = BankSys_LastGold[ trigId ] - UpgradeCost[ index ]
set PlayerUpgrades[ trigId ] = PlayerUpgrades[ trigId ] + 1
if PlayerUpgrades[ trigId ] == 1 then
call PausePlayerWeapons( owner, true )
endif
set TotalPlayerUpgrades[ trigId ] = TotalPlayerUpgrades[ trigId ] + 1
set baseName = GetObjectName( typeId )
if ShowMessages[ trigId ] then
call DisplayText( owner, GREEN + "Started upgrading " + GOLD + baseName + GREEN + " (" + GOLD + I2S( UpgradeCost[ index ] ) + GREEN + ")..." )
endif
call SetPlayerState( owner, PLAYER_STATE_RESOURCE_GOLD, gold )
endif
call upgradedata.create( trigUnit, typeId, UpgradeTarget[ index ] )
elseif owner != null then
call DisplayText( owner, NegativeTag + "Not enough gold for upgrade (" + NeutralTag + I2S( UpgradeCost[ index ] ) + NegativeTag + ")." )
call SetItemCharges( whichitem, GetItemCharges( whichitem ) + 1 )
endif
else
call SetItemCharges( whichitem, GetItemCharges( whichitem ) + 1 )
call DisplayText( owner, NegativeTag + "Not enough cargo free for upgrade (" + LIGHTGREY + I2S( reqRoom ) + NegativeTag + ")." )
endif
endif
set whichitem = null
set trigUnit = null
endfunction
endlibrary
//TESH.scrollpos=-1
//TESH.alwaysfold=0
scope UpgradeOnClick initializer INIT
globals
private constant trigger Upgrader = CreateTrigger()
endglobals
private function Upgrader_Actions takes nothing returns nothing
local item trigItem = GetManipulatedItem()
local unit trigUnit = GetTriggerUnit()
local player trigPlayer = GetOwningPlayer( trigUnit )
local string baseName
local string upgradeName
local integer gold
local integer typeId = GetItemTypeId( trigItem )
local integer index = GetItemTypeUpgradeId( typeId )
local integer charges
local real x
local real y
if index != - 1 then
call Upgrade( trigUnit, trigItem )
endif
set trigItem = null
set trigUnit = null
endfunction
//===========================================================================
function INIT takes nothing returns nothing
call TriggerRegisterAnyUnitEventBJ( Upgrader, EVENT_PLAYER_UNIT_USE_ITEM )
call TriggerAddAction( Upgrader, function Upgrader_Actions )
endfunction
endscope
//TESH.scrollpos=-1
//TESH.alwaysfold=0
//! runtextmacro AddItemValue( "MaxStack", "integer", "-1" )
library ItemStacker initializer InitIS needs MaxStackAttacherItem, Utilities, CargoSystem
globals
constant trigger ItemStacker = CreateTrigger()
endglobals
function SetMaxStack takes integer itemid, integer maxstack returns nothing
call SetItemTypeMaxStack( itemid, maxstack )
endfunction
function ItemStacker_Actions takes nothing returns nothing
local item trigItem = GetManipulatedItem()
local integer trigItemId = GetItemTypeId( trigItem )
local integer curCharges = GetItemCharges( trigItem )
local integer maxStack = GetItemTypeMaxStack( trigItemId )
local integer weight = GetItemTypeWeight( trigItemId )
local unit trigUnit = GetTriggerUnit()
local item curItem
local integer room
local integer newCharges
local integer oldCharges
local integer slotId = 0
local integer total = 0
local integer delta
local integer maxCargo = GetUnitMaxCargo( trigUnit )
if maxStack != -1 then
loop
if slotId > NUMSLOTS then
call SetItemCharges( trigItem, curCharges )
exitwhen true
endif
set curItem = UnitItemInSlot( trigUnit, slotId )
if GetItemTypeId( curItem ) == trigItemId and curItem != trigItem then
set oldCharges = GetItemCharges( curItem )
set newCharges = oldCharges + curCharges
if newCharges <= maxStack then
set delta = curCharges
call SetItemCharges( curItem, newCharges )
call RemoveItem( trigItem )
set curCharges = 0
set total = total + delta
exitwhen true
else
set delta = maxStack - oldCharges
call SetItemCharges( curItem, maxStack )
set curCharges = curCharges - delta
set total = total + delta
endif
endif
set slotId = slotId + 1
endloop
endif
call CheckUnitCargo( trigUnit )
set curItem = null
set trigItem = null
set trigUnit = null
endfunction
function InitIS takes nothing returns nothing
call TriggerRegisterAnyUnitEventBJ( ItemStacker, EVENT_PLAYER_UNIT_PICKUP_ITEM )
call TriggerAddAction(ItemStacker, function ItemStacker_Actions )
endfunction
endlibrary
//TESH.scrollpos=-1
//TESH.alwaysfold=0
///// VER 0A
//! runtextmacro AddUnitValue( "Cost", "integer", "0" )
library Combiner initializer InitCombiner needs Utilities, Hash, CostAttacherUnit
globals
integer array CombineEduct1
integer array CombineEduct2
integer array CombineEduct2Charges
integer array CombineId
integer array CombineProduct
constant trigger Combiner = CreateTrigger()
private hashtable IdTable
endglobals
function GetRecipeNum takes integer toSearch returns integer
return IdTable.Search( toSearch )
endfunction
function Combiner_Actions takes nothing returns nothing
local unit soldUnit = GetSoldUnit()
local unit buyUnit = GetBuyingUnit()
local player buyPlayer = GetOwningPlayer( buyUnit )
local integer buyPlayerID = GetPlayerId( buyPlayer )
local integer soldUnitID = GetUnitTypeId( soldUnit )
local integer recipeId = GetRecipeNum( soldUnitID )
local integer recipePrice = GetUnitTypeCost ( soldUnitID )
local real Dummy1
local real Dummy2
local item educt1
local item educt2
local integer educt2charges
local item product
local integer loopIndicator
local item array inventoryItem
local integer array inventoryItemID
local boolean preceed = true
if recipeId != -1 then
call RemoveUnit( soldUnit )
set loopIndicator = 0
loop
exitwhen loopIndicator > 5
set inventoryItem[ loopIndicator ] = UnitItemInSlot( buyUnit , loopIndicator )
set inventoryItemID[ loopIndicator ] = GetItemTypeId( inventoryItem[ loopIndicator ] )
set loopIndicator = loopIndicator + 1
endloop
set loopIndicator = 0
loop
if loopIndicator > 5 then
set preceed = false
exitwhen true
elseif CombineEduct1[ recipeId ] == inventoryItemID[ loopIndicator ] then
set educt1 = inventoryItem[ loopIndicator ]
exitwhen true
endif
set loopIndicator = loopIndicator + 1
endloop
if preceed then
set loopIndicator = 0
if CombineEduct2Charges[recipeId] != 0 then
loop
set educt2charges = GetItemCharges( inventoryItem[ loopIndicator ] )
if loopIndicator > 5 then
set preceed = false
exitwhen true
elseif ( CombineEduct2[ recipeId ] == inventoryItemID[ loopIndicator ] ) and ( CombineEduct2Charges[ recipeId ] <= educt2charges ) then
set educt2 = inventoryItem[ loopIndicator ]
exitwhen true
endif
set loopIndicator = loopIndicator + 1
endloop
if preceed then
call RemoveItem( educt1 )
if educt2charges == CombineEduct2Charges[ recipeId ] then
call RemoveItem( educt2 )
else
call SetItemCharges( educt2 , educt2charges - CombineEduct2Charges[ recipeId ] )
endif
set product = CreateItem( CombineProduct[ recipeId ] , GetUnitX( buyUnit ), GetUnitY( buyUnit ) )
call DisplayTextToPlayer( buyPlayer , 0 , 0 , PositiveTag + "Combining completed sucessfully" + EndTag )
call UnitAddItem( buyUnit, product )
else
call DisplayTextToPlayer( buyPlayer , 0 , 0 , NegativeTag + "You don't have enough charges on your item!" + EndTag )
call SetPlayerState( buyPlayer , PLAYER_STATE_RESOURCE_GOLD , GetPlayerState( buyPlayer, PLAYER_STATE_RESOURCE_GOLD ) + recipePrice )
endif
else
loop
if loopIndicator > 5 then
set preceed = false
exitwhen true
elseif CombineEduct2[ recipeId ] == inventoryItemID[ loopIndicator ] then
set educt2 = inventoryItem[ loopIndicator ]
exitwhen true
endif
set loopIndicator = loopIndicator + 1
endloop
if preceed then
call RemoveItem( educt1 )
call RemoveItem( educt2 )
set product = CreateItem( CombineProduct[ recipeId ] , GetUnitX( buyUnit ), GetUnitY( buyUnit ) )
call DisplayTextToPlayer( buyPlayer , 0 , 0 , PositiveTag + "Combining completed sucessfully" + EndTag )
call UnitAddItem( buyUnit, product )
else
call DisplayTextToPlayer( buyPlayer , 0 , 0 , NegativeTag + "Combination did not work..." + EndTag )
call SetPlayerState( buyPlayer , PLAYER_STATE_RESOURCE_GOLD , GetPlayerState( buyPlayer, PLAYER_STATE_RESOURCE_GOLD ) + recipePrice )
endif
endif
else
call DisplayTextToPlayer( buyPlayer , 0 , 0 , NegativeTag + "Combination did not work..." + EndTag )
call SetPlayerState( buyPlayer , PLAYER_STATE_RESOURCE_GOLD , GetPlayerState( buyPlayer, PLAYER_STATE_RESOURCE_GOLD ) + recipePrice )
endif
endif
endfunction
function NewCombineRecipe takes integer recipeid, integer educt1id, integer educt2id, integer productid returns nothing
local integer index = IdTable.Hash( recipeid )
set CombineEduct1 [ index ] = educt1id
set CombineEduct2 [ index ] = educt2id
set CombineEduct2Charges[ index ] = 0
set CombineProduct [ index ] = productid
set CombineId [ index ] = recipeid
endfunction
function NewCombineRecipeCharges takes integer recipeid, integer educt1id, integer educt2id, integer educt2charges, integer productid returns nothing
local integer index = IdTable.Hash( recipeid )
set CombineEduct1 [ index ] = educt1id
set CombineEduct2 [ index ] = educt2id
set CombineEduct2Charges[ index ] = educt2charges
set CombineProduct [ index ] = productid
set CombineId [ index ] = recipeid
endfunction
//==== Init Trigger NewTrigger ====
function InitCombiner takes nothing returns nothing
local integer playerId = 0
set IdTable = hashtable.create()
loop
exitwhen playerId > NUMPLAYERS
call TriggerRegisterPlayerUnitEvent( Combiner, Players[ playerId ], EVENT_PLAYER_UNIT_SELL, null )
set playerId = playerId + 1
endloop
call TriggerAddAction( Combiner, function Combiner_Actions )
endfunction
endlibrary
//TESH.scrollpos=11
//TESH.alwaysfold=0
//! textmacro UserDefinedTargetModes
// Syntax:
// if targetmode == 'NAME' then
// set next = 'FUNC'( targets, this )
// endif
//! endtextmacro
// End Parameters
//! runtextmacro Attach( "UnitWeapon", "unit", "weapon", "0" )
//! runtextmacro Attach( "TimerWeapon", "timer", "weapon", "0" )
//! runtextmacro Attach( "UnitTypeAutoWeapon", "integer", "autoweapontypechain", "0" )
library WeaponSys initializer INIT needs Utilities, ItemWeapon, ItemTypeAutoWeapon, TimerWeapon
// NAME, ATTACHTYPE, ATTACHEDTYPE, DEFAULT, LIBRARYNAME
globals
constant integer TARGET_MODE_SALVE = 0
constant integer TARGET_MODE_RANDOM = 1
constant integer TARGET_MODE_KILL = 2
private constant trigger WeaponActivator = CreateTrigger()
private constant trigger WeaponDeactivator = CreateTrigger()
private unit FireUnit
private boolexpr BaseFilter
endglobals
private function GetRandomTarget takes group targets, weapon this returns unit
local integer i = 0
local unit target = null
local unit curUnit
loop
set curUnit = FirstOfGroup( targets )
exitwhen curUnit == null
set i = i + 1
if GetRandomInt( 1, i ) == 1 then
set target = curUnit
endif
call GroupRemoveUnit( targets, curUnit )
endloop
set ReturnHandle = target
set target = null
set targets = null
set curUnit = null
return ReturnHandle
endfunction
private function GetSalveTarget takes group targets, weapon gun returns unit
local unit target
if gun.shot != 0 and IsUnitInGroup( gun.lastTarget , targets ) then
set target = gun.lastTarget
else
set target = GetRandomTarget( targets, gun )
endif
set ReturnHandle = target
set target = null
set targets = null
return ReturnHandle
endfunction
private function GetKillTarget takes group targets, weapon gun returns unit
local unit target
if IsUnitInGroup( gun.lastTarget , targets ) then
set target = gun.lastTarget
else
set target = GetRandomTarget( targets, gun )
endif
set ReturnHandle = target
set target = null
set targets = null
return ReturnHandle
endfunction
function GetNextTarget takes weapon gun returns unit
local unit next = null
local integer targetmode = gun.targetmode
local group targets = GLOBAL_GROUP
call GroupClear( targets )
call GroupEnumUnitsInRange( targets, GetWidgetX( gun.owner ), GetWidgetY( gun.owner ), gun.range, gun.targeting )
if targetmode == TARGET_MODE_SALVE then
set next = GetSalveTarget( targets, gun )
elseif targetmode == TARGET_MODE_RANDOM then
set next = GetRandomTarget( targets, gun )
elseif targetmode == TARGET_MODE_KILL then
set next = GetKillTarget( targets, gun )
else
//! runtextmacro UserDefinedTargetModes()
endif
set ReturnHandle = next
set next = null
set targets = null
return ReturnHandle
endfunction
private function Fire takes nothing returns nothing
local timer shotTimer = GetExpiredTimer()
local weapon gun = TimerWeapon[ shotTimer ]
local unit next
local unit dummy
if GetUnitState( gun.owner, UNIT_STATE_LIFE ) > 0 then
set FireUnit = gun.owner
set next = GetNextTarget( gun )
set gun.lastTarget = next
if next != null then
set dummy = gun.model
call PauseUnit( dummy, false )
call SetUnitX( dummy, GetUnitX( FireUnit ) )
call SetUnitY( dummy, GetUnitY( FireUnit ) )
call IssueTargetOrder( dummy, gun.orderId, next )
call UnitDamageTarget( dummy, next, gun.damage, true, true, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS )
call PauseUnit( dummy, true )
endif
endif
set gun.shot = gun.shot + 1
if gun.shot >= gun.shots then
set gun.shot = 0
call TimerStart( shotTimer, gun.cooldown, false, function Fire )
else
call TimerStart( shotTimer, gun.interval, false, function Fire )
endif
set next = null
set dummy = null
set shotTimer = null
endfunction
function GetFiringUnit takes nothing returns unit
return FireUnit
endfunction
struct weapon
private delegate autoweapontype weaponType
unit model
timer shotTimer
integer shot
unit lastTarget
unit owner
static method create takes autoweapontype weaponType, unit owner returns weapon
local weapon this = weapon.allocate()
set .weaponType = weaponType
set .shotTimer = CreateTimer()
set TimerWeapon[ .shotTimer ] = this
set .shot = 0
set .lastTarget = null
set .owner = owner
set .model = CreateUnit( GetOwningPlayer( .owner ), .dummyTypeId, GetUnitX( .owner ), GetUnitY( .owner ), 270 )
call TimerStart( .shotTimer, .cooldown, false, function Fire )
return this
endmethod
private method onDestroy takes nothing returns nothing
call PauseTimer( .shotTimer )
call DestroyTimer( .shotTimer )
set .shotTimer = null
set .lastTarget = null
set .owner = null
endmethod
endstruct
struct autoweapontype
integer damage
integer shots
integer dummyTypeId
string orderId
real cooldown
real range
real interval
boolexpr targeting
integer targetmode
static method create takes integer damage, real cooldown, real range, integer shots, real interval, boolexpr targeting, integer targetmode, integer dummyTypeId, string orderId returns autoweapontype
local autoweapontype this = .allocate()
set .damage = damage
set .shots = shots
set .cooldown = cooldown
set .range = range
if targeting == null then
set .targeting = BaseFilter
else
set .targeting = And( targeting, BaseFilter )
endif
if orderId == "" then
set .orderId = "attack"
else
set .orderId = orderId
endif
set .interval = interval
set .dummyTypeId = dummyTypeId
return this
endmethod
method createInstance takes unit owner returns weapon
return weapon.create( this, owner )
endmethod
endstruct
function WeaponActivator_Actions takes nothing returns nothing
local unit trigUnit = GetTriggerUnit()
local item trigItem = GetManipulatedItem()
local integer trigItemId = GetItemTypeId( trigItem )
local autoweapontype trigWeaponType = ItemTypeAutoWeapon[ trigItemId ]
if trigWeaponType != 0 then
set ItemWeapon[ trigItem ] = trigWeaponType.createInstance( trigUnit )
endif
set trigUnit = null
set trigItem = null
endfunction
function WeaponDeactivator_Actions takes nothing returns nothing
local unit trigUnit = GetTriggerUnit()
local item trigItem = GetManipulatedItem()
local integer trigItemId = GetItemTypeId( trigItem )
local autoweapontype trigWeaponType = ItemTypeAutoWeapon[ trigItemId ]
if trigWeaponType != 0 then
call ItemWeapon[ trigItem ].destroy()
set ItemWeapon[ trigItem ] = 0
endif
set trigUnit = null
set trigItem = null
endfunction
private function BaseFilter_Func takes nothing returns boolean
local unit filter = GetFilterUnit()
local player fireOwner = GetOwningPlayer( GetFiringUnit() )
local boolean b = ( GetUnitState( filter, UNIT_STATE_LIFE ) > 0 ) and ( not IsUnitAlly( filter, fireOwner ) ) and IsUnitVisible( filter, fireOwner ) and IsUnitInvisible( GetFiringUnit(), GetOwningPlayer( filter ) )
set filter = null
set fireOwner = null
return b
endfunction
private function INIT takes nothing returns nothing
set BaseFilter = Condition( function BaseFilter_Func )
call TriggerAddAction( WeaponActivator, function WeaponActivator_Actions )
call TriggerRegisterAnyUnitEventBJ( WeaponActivator, EVENT_PLAYER_UNIT_PICKUP_ITEM )
call TriggerAddAction( WeaponDeactivator, function WeaponDeactivator_Actions )
call TriggerRegisterAnyUnitEventBJ( WeaponDeactivator, EVENT_PLAYER_UNIT_DROP_ITEM )
endfunction
// WRAPPERS:
// CreateWeaponType( integer damage, real cooldown, real range, integer shots, real interval, boolexpr targeting, integer targetmode, integer dummyTypeId, string orderId )
// WeaponTypeAddItemTypeId( autoweapontype weaponType, integer itemtypeid )
// CreateWeapon( autoweapontype type, unit owner )
function CreateWeaponType takes integer damage, real cooldown, real range, integer shots, real interval, boolexpr targeting, integer targetmode, integer dummyTypeId, string orderId returns autoweapontype
return autoweapontype.create( damage, cooldown, range, shots, interval, targeting, targetmode, dummyTypeId, orderId )
endfunction
function CreateWeaponTypeSimple takes integer damage, real cooldown, real range, boolexpr targeting, integer dummyTypeId returns autoweapontype
return CreateWeaponType( damage, cooldown, range, 1, 0.00, targeting, TARGET_MODE_RANDOM, dummyTypeId, "attack" )
endfunction
function WeaponTypeAddItemTypeId takes autoweapontype weaponType, integer itemtypeid returns nothing
call weaponType.addWeapon( itemtypeid )
endfunction
function CreateWeapon takes autoweapontype weaponType, unit owner returns weapon
return weaponType.createInstance( owner )
endfunction
function DestroyWeapon takes weapon toDestroy returns nothing
call toDestroy.destroy()
endfunction
endlibrary
//TESH.scrollpos=28
//TESH.alwaysfold=0
//! textmacro LvlItemSkill takes NAME, SKILL, LEVELS
library_once InitItemSkills initializer INIT
globals
public constant trigger Leveler = CreateTrigger()
endglobals
private function INIT takes nothing returns nothing
call TriggerRegisterAnyUnitEventBJ( Leveler, EVENT_PLAYER_HERO_SKILL )
endfunction
endlibrary
scope LevelItemSkill$NAME$ initializer INIT
globals
private level_ar LevelsStruct
endglobals
private function LevelSkill takes unit u returns nothing
local integer curLevel = GetUnitAbilityLevel( u, '$SKILL$' ) - 1
if curLevel > 0 then
call UnitRemoveAbility( u, LevelsStruct.id[ curLevel - 1 ] )
endif
call UnitAddAbility ( u, LevelsStruct.id[ curLevel ] )
set u = null
endfunction
private function Leveler_Actions takes nothing returns nothing
if GetLearnedSkill() == '$SKILL$' then
call LevelSkill( GetLearningUnit() )
endif
endfunction
function Get$NAME$SkillId takes unit u returns integer
local integer curLevel = GetUnitAbilityLevel( u, '$SKILL$')
set u = null
return LevelsStruct.id[ curLevel ]
endfunction
private function INIT takes nothing returns nothing
call TriggerAddAction( InitItemSkills_Leveler, function Leveler_Actions )
set LevelsStruct = Levels($LEVELS$)
endfunction
endscope
//! endtextmacro
struct level_ar
integer array id [6]
static method create takes integer id1, integer id2, integer id3, integer id4, integer id5, integer id6 returns level_ar
local level_ar this = .allocate()
set .id[ 0 ] = id1
set .id[ 1 ] = id2
set .id[ 2 ] = id3
set .id[ 3 ] = id4
set .id[ 4 ] = id5
set .id[ 5 ] = id6
return this
endmethod
endstruct
function Levels takes integer id1, integer id2, integer id3, integer id4, integer id5, integer id6 returns level_ar
return level_ar.create( id1, id2, id3, id4, id5, id6 )
endfunction
//! runtextmacro LvlItemSkill( "Hp0", "A01A", "'A01B', 'A01C', 'A01D', 'A01E', 'A01F', 'A01G'" )
//! runtextmacro LvlItemSkill( "Rp0", "A01H", "'A01I', 'A01J', 'A01K', 'A01L', 'A01M', 'A01N'" )
//! runtextmacro LvlItemSkill( "Hp1", "A01R", "'A01S', 'A01T', 'A01U', 'A01V', 'A01W', 'A01X'" )
// //! runtextmacro LvlItemSkill( "Hp0", "A01A", "Levels('A01B', 'A01C', 'A01D', 'A01E', 'A01F', 'A01G')" )
//TESH.scrollpos=0
//TESH.alwaysfold=0
//! runtextmacro Switcher( "TraderUpgrade" )
//! runtextmacro AddUnitValue( "ShipId", "integer", "0" )
scope TradeItemSwitcher initializer INIT
globals
integer array SLOT
endglobals
function SwitchUpgrades takes unit trigUnit returns nothing
call UnitAddItem( trigUnit, SwitchTraderUpgrade( UnitItemInSlot( trigUnit, SLOT[ REQ_POW ] ) ) )
call UnitAddItem( trigUnit, SwitchTraderUpgrade( UnitItemInSlot( trigUnit, SLOT[ REQ_CD ] ) ) )
call UnitAddItem( trigUnit, SwitchTraderUpgrade( UnitItemInSlot( trigUnit, SLOT[ REQ_HULL ] ) ) )
set trigUnit = null
endfunction
private function INIT_REALLY takes nothing returns nothing
// Cooldown / Profit
call SetTraderUpgradePair( 'I00Z', 'I019' )
call SetTraderUpgradePair( 'I010', 'I01A' )
call SetTraderUpgradePair( 'I013', 'I01B' )
call SetTraderUpgradePair( 'I012', 'I01C' )
call SetTraderUpgradePair( 'I011', 'I01D' )
// Power / Cargo
call SetTraderUpgradePair( 'I00R', 'I01E' )
call SetTraderUpgradePair( 'I00S', 'I01F' )
call SetTraderUpgradePair( 'I00T', 'I01G' )
call SetTraderUpgradePair( 'I00U', 'I01H' )
call SetTraderUpgradePair( 'I00W', 'I01I' )
call SetTraderUpgradePair( 'I00X', 'I01J' )
call SetTraderUpgradePair( 'I00V', 'I01K' )
call SetTraderUpgradePair( 'I00Y', 'I01L' )
// Hull / THull
call SetTraderUpgradePair( 'I014', 'I01Q' )
call SetTraderUpgradePair( 'I015', 'I01M' )
call SetTraderUpgradePair( 'I016', 'I01N' )
call SetTraderUpgradePair( 'I017', 'I01O' )
call SetTraderUpgradePair( 'I018', 'I01P' )
set SLOT[ REQ_POW ] = 0
set SLOT[ REQ_CD ] = 2
set SLOT[ REQ_HULL ] = 3
endfunction
private function INIT takes nothing returns nothing
call ExecuteFunc( SCOPE_PRIVATE + "INIT_REALLY" )
endfunction
endscope
//TESH.scrollpos=152
//TESH.alwaysfold=0
//! runtextmacro Attach( "AdminSpec", "string", "admin", "0" )
library Admins initializer InitAdmins needs Utilities, Dialogs
globals
private constant string PARAMETER_INIT_STRING = "connect"
endglobals
//! runtextmacro RandomString( "private", "Question" )
private function PassWd takes string name returns string
local integer nameId = Char2I( name, 0, 5 )
local integer a = StringLength( name )
local integer b = ( nameId + 3 * a ) / 7
local integer c = a * b * nameId
return I2Char( 50653 + ModuloInteger( c + a + b , 1874161 ) )
endfunction
struct admin
private string Name
private string Passwd
private adminspec Specification
static method create takes string name, adminspec spec returns admin
local admin this = .allocate()
set .Name = name
set .Specification = spec
set .Passwd = PassWd( name )
set AdminSpec[ name ] = this
return this
endmethod
method operator name takes nothing returns string
return .Name
endmethod
method operator passwd takes nothing returns string
return .Passwd
endmethod
method operator spec takes nothing returns adminspec
return .Specification
endmethod
endstruct
struct adminspec
integer level
integer dataId
string name
static method create takes string name, integer dataId, integer level returns adminspec
local adminspec new = adminspec.allocate()
set new.name = name
set new.level = level
set new.dataId = dataId
return new
endmethod
endstruct
globals
private player RegisteredAdmin
private string array AdminName
private integer array PasswordLength
private string array Password
private adminspec array AdminSpec
private integer Admins = 0
private adminspec array PlayerSpec
private integer array Lock[6][MAX_USER_SLOT]
private integer array Gate
private integer array Gates
private Dialog array EntryDialog
private adminspec array Login
private integer array Errors
private adminspec NilSpec
private adminspec FalseSpec
private constant integer BUTTONS = 8
private constant trigger LogIn = CreateTrigger()
private integer COMMAND_LENGTH = StringLength( PARAMETER_INIT_STRING )
private integer AttachedTriggerNum = 0
private trigger array AttachedTrigger
private integer array UnusedKeys[MAX_USER_SLOT][41]
private integer array NumKeys
endglobals
function GetPlayerAdminSpec takes player whichplayer returns adminspec
return PlayerSpec[ GetPlayerId( whichplayer ) ]
endfunction
function GetPlayerAdminText takes player whichplayer returns string
return GetPlayerAdminSpec( whichplayer ).name
endfunction
function GetPlayerAdminLevel takes player whichplayer returns integer
return GetPlayerAdminSpec( whichplayer ).level
endfunction
function GetRegisteredAdmin takes nothing returns player
return RegisteredAdmin
endfunction
function ExecuteAdminTriggers takes player executor returns nothing
local integer i = 0
set RegisteredAdmin = executor
loop
exitwhen i > AttachedTriggerNum
if TriggerEvaluate( AttachedTrigger[ i ] ) then
call TriggerExecute( AttachedTrigger[ i ] )
endif
set i = i + 1
endloop
set RegisteredAdmin = null
endfunction
function TriggerRegisterAdminEvent takes trigger t returns nothing
set AttachedTrigger[ AttachedTriggerNum ] = t
set AttachedTriggerNum = AttachedTriggerNum + 1
endfunction
function AddAdmin takes string name, adminspec level returns nothing
local admin new = admin.create( StringCase( name, false ), level )
set AdminName[ Admins ] = new.name
set AdminSpec[ Admins ] = new.spec
set PasswordLength[ Admins ] = StringLength( new.passwd )
set Password[ Admins ] = new.passwd
set Admins = Admins + 1
endfunction
function TryKey takes nothing returns nothing
local player trigPlayer = GetTriggerPlayer()
local integer trigId = GetPlayerId( trigPlayer )
local integer key = EntryDialog[ trigId ].GetResult()
if key == HK_ESC then
set Errors[ trigId ] = 0
return
elseif key != Lock[ Gate[ trigId ] ][ trigId ] then
set Errors[ trigId ] = Errors[ trigId ] + 1
endif
set Gate[ trigId ] = Gate[ trigId ] + 1
call InitGate.evaluate( trigId )
endfunction
private function InitAdmin_Single takes integer i returns nothing
local integer j = 41
set NumKeys[i] = 0
loop
exitwhen j > 89
set UnusedKeys[i][j] = j
set NumKeys[i] = NumKeys[i]+1
set j = j + 1
endloop
endfunction
function InitGate takes integer trigId returns boolean
local integer i = 1
local integer insert
local integer curKey
if Lock[ Gate[ trigId ] ][ trigId ] != NumKeys[trigId] then
set UnusedKeys[ trigId ][ Lock[ Gate[ trigId ] ][ trigId ] ] = NumKeys[trigId]
endif
set NumKeys[ trigId ] = NumKeys[ trigId ] - 1
if Gate[ trigId ] < Gates[ trigId ] then
set insert = GetRandomInt( 1, BUTTONS )
call EntryDialog[ trigId ].destroy()
set EntryDialog[ trigId ] = Dialog.create()
call EntryDialog[ trigId ].SetMessage( GetQuestionString() )
loop
exitwhen i > BUTTONS
if i == insert then
call EntryDialog[ trigId ].AddButton( I2S( i ), Lock[ ( Gate[ trigId ] ) ][ trigId ] )
else
set curKey = GetRandomInt( 0,NumKeys[ trigId ] )
set NumKeys[ trigId ] = NumKeys[ trigId ] - 1
call EntryDialog[ trigId ].AddButton( I2S( i ), UnusedKeys[ trigId ][ curKey ] )
set UnusedKeys[ trigId ][ curKey ] = UnusedKeys[ trigId ][ NumKeys[ trigId ] ]
endif
set i = i + 1
endloop
call EntryDialog[ trigId ].AddButton( "Exit", HK_ESC )
call EntryDialog[ trigId ].AddAction( function TryKey )
call EntryDialog[ trigId ].Show( Players[ trigId ] )
else
if Errors[ trigId ] == 0 then
set PlayerSpec[ trigId ] = Login[ trigId ]
call ExecuteAdminTriggers( Players[ trigId ] )
call DisplayText( LOCAL_PLAYER, PlayerName[ trigId ] + GREEN + " has logged in as " + GetPlayerAdminText( Players[ trigId ] ) + GREEN + "!" )
elseif Errors[ trigId ] >= Gates[ trigId ] then
set PlayerSpec[ trigId ] = FalseSpec
call ExecuteAdminTriggers( Players[ trigId ] )
call DisplayText( LOCAL_PLAYER, PlayerName[ trigId ] + GREEN + " has tried to log in. His attempt failed, because he didn't know the password." )
call DisplayText( Players[ trigId ], RED + "You can't login for the whole game." )
// call WinGame( Players[ trigId ], false, "You have been warned!" )
else
call DisplayText( Players[ trigId ], RED + "Login failed!" )
set Errors[ trigId ] = 0
endif
call InitAdmin_Single.execute( trigId )
return true
endif
return false
endfunction
function LogIn_Init takes nothing returns nothing
local player trigPlayer = GetTriggerPlayer()
local integer trigId = GetPlayerId( trigPlayer )
local integer i = 0
local integer j = 0
local string trigString = GetEventPlayerChatString()
local string connectString = StringCase( SubString( trigString, COMMAND_LENGTH + 1, StringLength( trigString ) ), false )
local integer curKey
if PlayerSpec[ trigId ] == NilSpec then
call InitAdmin_Single.execute( trigId )
loop
exitwhen i >= Admins
if AdminName[ i ] == connectString then
set Login[ trigId ] = AdminSpec[ i ]
set j = 0
loop
exitwhen j >= PasswordLength[ i ]
set curKey = Char2I( Password[ i ], j, j+1 )
if curKey > 10 then
set curKey = curKey + 54
else
set curKey = curKey + 47
endif
set Lock[j][trigId] = curKey
set j = j + 1
endloop
set Gate[trigId] = 0
set Gates[trigId] = PasswordLength[ i ]
call InitGate( trigId )
exitwhen true
endif
set i = i + 1
endloop
else
call DisplayText( trigPlayer, RED + "Already logged in!" )
endif
endfunction
private function InitAdmins takes nothing returns nothing
local integer i = 0
local integer j = 0
set NilSpec = adminspec.create( "user", 0, 0 )
set FalseSpec = adminspec.create( RED + "CHEATER", 0, 0 )
call AddQuestionString( "What is the squareroot of 16?" )
call AddQuestionString( "2 + 3 = ?" )
call AddQuestionString( "What is 2 raised to the second power?" )
call AddQuestionString( "2x² - 5x + 3 = 0 for x = ?" )
call AddQuestionString( "How many roads must a man walk down?" )
call AddQuestionString( "9 - 13 / 6.5 = ?" )
call AddQuestionString( "sin(<3) = ?" )
call AddQuestionString( "How many maps has SerraAvenger published?" )
call AddQuestionString( "-.^ = ?" )
call TriggerRegisterAnyPlayerChatEvent( LogIn, PARAMETER_INIT_STRING, false )
call TriggerAddAction( LogIn, function LogIn_Init )
set i = 0
loop
exitwhen i > NUMUSERS
set PlayerSpec[ i ] = NilSpec
set Gate[ i ] = 0
set Gates[ i ] = 0
set EntryDialog[ i ] = Dialog.create()
set i = i + 1
call InitAdmin_Single.execute(i)
endloop
endfunction
endlibrary
//TESH.scrollpos=-1
//TESH.alwaysfold=0
//! runtextmacro AddItemValue( "Weight", "integer", "0" )
library CargoSystem initializer Init needs WeightAttacherItem, MaxCargoAttacherUnit, CostAttacherItem, Utilities, ItemTypeResourceId
//! runtextmacro PUI_PROPERTY( "private", "integer", "Cargo", "0" )
//! runtextmacro RandomString( "private", "TOOMUCHFREIGHT" )
globals
private constant trigger CargoUpdater = CreateTrigger()
private constant trigger CargoRemove = CreateTrigger()
endglobals
function GetUnitCargo takes unit whichunit returns integer
return Cargo[ whichunit ]
endfunction
function SetUnitCargo takes unit whichunit, integer cargo returns nothing
set Cargo[ whichunit ] = cargo
endfunction
function CheckUnitCargo takes unit trigUnit returns nothing
local item trigItem
local item dropItem
local player trigPlayer
local integer trigItemId
local integer itemWeight
local integer curStack
local integer newCargo
local integer curCargo = 0
local integer maxCargo = GetUnitMaxCargo( trigUnit )
local integer baseCargo = Cargo[ trigUnit ]
local integer index = 0
local integer curGold
local integer itemCost
local integer dropStack
local integer i = 0
local real x = GetUnitX( trigUnit )
local real y = GetUnitY( trigUnit )
loop
exitwhen i > MAX_INV_SLOT
set trigItem = UnitItemInSlot( trigUnit, i )
set trigPlayer = GetOwningPlayer( trigUnit )
set trigItemId = GetItemTypeId( trigItem )
set itemWeight = GetItemTypeWeight( trigItemId )
set curStack = GetItemCharges( trigItem )
if curStack == 0 or GetItemTypeMaxStack( trigItemId ) == -1 then
set curStack = 1
endif
set newCargo = curCargo + itemWeight * curStack
if newCargo > maxCargo then
set curGold = GetPlayerState( trigPlayer, PLAYER_STATE_RESOURCE_GOLD )
set itemCost = GetItemTypeCost( trigItemId )
set dropItem = CreateItem( trigItemId, x, y )
if curStack > 1 then
set dropStack = R2I( I2R( newCargo - maxCargo ) / itemWeight + 0.999 )
call SetItemCharges( dropItem, dropStack)
else
// Item is not stackable or only 1 stack remaining
set dropStack = 1
endif
set curStack = curStack - dropStack
if curStack <= 0 then
call RemoveItem( trigItem )
else
call SetItemCharges( trigItem, curStack)
endif
call DisplayText( trigPlayer, GetTOOMUCHFREIGHTString() )
endif
set curCargo = curCargo + curStack * itemWeight
set i = i + 1
endloop
set Cargo[ trigUnit ] = curCargo
set trigUnit = null
set trigItem = null
set dropItem = null
endfunction
private function CargoUpdater_Actions takes nothing returns boolean
if GetItemMaxStack( GetManipulatedItem() ) == 0 then
call CheckUnitCargo( GetTriggerUnit() )
endif
return false
endfunction
private function CargoRemove_Actions takes nothing returns nothing
local unit trigUnit = GetTriggerUnit()
local item trigItem = GetManipulatedItem()
local integer trigItemId = GetItemTypeId( trigItem )
local integer itemWeight = GetItemTypeWeight( trigItemId )
local integer curStack = GetItemCharges( trigItem )
if curStack == 0 then
set curStack = 1
endif
set Cargo[ trigUnit ] = Cargo[ trigUnit ] - curStack * itemWeight
set trigUnit = null
set trigItem = null
endfunction
private function Init takes nothing returns nothing
call AddTOOMUCHFREIGHTString( NegativeTag + "Captain, we cannot carry more freight!" )
call AddTOOMUCHFREIGHTString( NegativeTag + "That's too much cargo, sir." )
call AddTOOMUCHFREIGHTString( NegativeTag + "The ship is full, captain!" )
call AddTOOMUCHFREIGHTString( NegativeTag + "With all regards - we have a ship, not a mule, sir!" )
call AddTOOMUCHFREIGHTString( NegativeTag + "Sir, where should we put this stuff?" )
call AddTOOMUCHFREIGHTString( NegativeTag + "Do you want to taste the sea, captain?" )
call AddTOOMUCHFREIGHTString( NegativeTag + "Sir, too much is too much, sir." )
call TriggerRegisterAnyUnitEventBJ( CargoUpdater, EVENT_PLAYER_UNIT_PICKUP_ITEM )
call TriggerAddCondition( CargoUpdater, Condition( function CargoUpdater_Actions ) )
call TriggerRegisterAnyUnitEventBJ( CargoRemove, EVENT_PLAYER_UNIT_DROP_ITEM )
call TriggerAddAction( CargoRemove, function CargoRemove_Actions )
endfunction
endlibrary
//TESH.scrollpos=3
//TESH.alwaysfold=0
globals
player Empire
endglobals
function MakePickedUnitEmpire takes nothing returns nothing
call SetUnitOwner( GetEnumUnit(), Empire, true )
endfunction
function ClearLeaver takes player leaver, boolean showmsg returns nothing
local integer leaverId = GetPlayerId ( leaver )
local unit hero = Hero [ leaverId ]
local integer teamId = Team[ leaverId ].id
local integer playerGold
local integer slotId = 0
local item slotItem
local integer i = 0
local player localPlayer = LOCAL_PLAYER
call TeamRemovePlayerSJ( teamId, leaver )
if GetTeamPlayersSJ( teamId ) > 1 then
set playerGold = R2I( 0.8 * GetPlayerState( leaver, PLAYER_STATE_RESOURCE_GOLD ) + 0.5 )
set playerGold = playerGold + R2I( playerGold + 0.8 * GetUnitPointValue( hero ) + 0.5 )
loop
exitwhen slotId > NUMSLOTS
set slotItem = UnitItemInSlot( hero, slotId )
if slotItem != null then
set playerGold = R2I( playerGold + GetItemCost( slotItem ) + 0.5 )
endif
set slotId = slotId + 1
endloop
if showmsg then
if IsPlayerAlly( localPlayer, leaver ) then
call DisplayTimedTextToPlayer( localPlayer, 0, 0, 15, PlayerName[ leaverId ] + NegativeTag + " has deserted!" )
else
call DisplayTimedTextToPlayer( localPlayer, 0, 0, 15, PlayerName[ leaverId ] + NegativeTag + " has left the battlefield!" )
endif
endif
if IsPlayerAlly( localPlayer, leaver ) then
call DisplayText( LOCAL_PLAYER, GREY + "Your empire confiscated " + NeutralTag + I2S( playerGold ) + GREY + " gold. " )
endif
set LeaverGold = playerGold / GetTeamPlayersSJ( teamId )
loop
exitwhen i > MAX_USER_SLOT
if teamId == Team[ i ].id then
call AddGold( LeaverGold, i, TRANSFERTYPE_PLAYER_PLAYER, "Leavergold" )
endif
set i = i + 1
endloop
set Empire = Players[ teamId ]
call RemoveUnit( hero )
call GroupClear( GLOBAL_GROUP )
call GroupEnumUnitsOfPlayer( GLOBAL_GROUP, leaver, null )
call ForGroup( GLOBAL_GROUP, function MakePickedUnitEmpire )
set LeaverGold = 0
call SetPlayerState( leaver, PLAYER_STATE_RESOURCE_GOLD, 0 )
elseif GameRuns then
if showmsg then
call DisplayTimedTextToPlayer( localPlayer, 0, 0, 10, PlayerName[ leaverId ] + NegativeTag + " has left the battlefield!" )
endif
call DisplayTimedTextToPlayer( localPlayer, 0, 0, 30, PositiveTag + "There are no players remaining in " + TeamName[ teamId ] + PositiveTag + "! With no enemy captains left, the other Mage can no longer establish the protective barrier!" )
call ExitCode( ModuloInteger( teamId + 1 , 2 ) )
endif
set hero = null
endfunction
function PlayerLeave_Action takes nothing returns nothing
call ClearLeaver( GetTriggerPlayer(), true )
endfunction
function InitTrig_LeaverHandler takes nothing returns nothing
call TriggerAddAction( LEAVER_HANDLER, function PlayerLeave_Action )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
library MoneyAdder initializer InitMoneyAdder needs Utilities, AntarcticaMapInit
globals
constant trigger MoneyAdder = CreateTrigger()
integer GoldPerSec = 15
constant integer Interval = 5
private integer Times = 0
endglobals
function MoneyAdder_Actions takes nothing returns nothing
local integer playerId = 2
local integer array money
if GameRuns then
call AddGold( GoldPerSec * Interval, 0, TRANSFERTYPE_PLAYER_PLAYER, "gps" )
call AddGold( GoldPerSec * Interval, 1, TRANSFERTYPE_PLAYER_PLAYER, "gps" )
set Times = Times + 1
if Times >= 10 then
set GoldPerSec = GoldPerSec + 1
set Times = 0
endif
if Team[ SouthTeamId ].numPlayers > 0 then
set money[ SouthTeamId ] = ( GoldPerSec * Interval ) / ( Team[ SouthTeamId ].numPlayers + 1 )
else
set money[ SouthTeamId ] = 0
endif
if Team[ NorthTeamId ].numPlayers > 0 then
set money[ NorthTeamId ] = ( GoldPerSec * Interval ) / ( Team[ NorthTeamId ].numPlayers + 1 )
else
set money[ NorthTeamId ] = 0
endif
loop
exitwhen playerId > NUMPLAYERS
if PlayerActive[ playerId ] then
call Transfer( money[ Team[ playerId ].id ], Team[ playerId ].empireId, playerId, TRANSFERTYPE_PLAYER_PLAYER, "Empire" )
endif
set playerId = playerId + 1
endloop
endif
endfunction
function InitMoneyAdder takes nothing returns nothing
call TriggerRegisterTimerEvent( MoneyAdder, Interval, true )
call TriggerAddAction ( MoneyAdder, function MoneyAdder_Actions )
endfunction
endlibrary
//TESH.scrollpos=21
//TESH.alwaysfold=0
///// VER 07
library UpgradeSystem initializer UpgraderInit needs BountySystem , Utilities , AntarcticaMapInit
globals
constant integer DamageItem = 'n00C'
constant integer ArmorItem = 'n00B'
boolean ShowText = true
private constant trigger Upgrader = CreateTrigger()
private real Give_Value
private integer Upgrade
endglobals
private function AddUpgradeLevel_Enum takes nothing returns nothing
local player enumPlayer = GetEnumPlayer()
local integer enumId = GetPlayerId ( enumPlayer )
call AddPlayerTechResearched( enumPlayer, Upgrade, 1 )
call SetPlayerBounty( enumId, Give_Value, 1 )
endfunction
function AddUpgradeLevel takes integer upgrade , force toupgrade, integer researcherid returns nothing
local string upgradeString
set Give_Value = ( GetPlayerTechCount( Players[ researcherid ], DamageUpgrade, true ) + GetPlayerTechCount( Players[ researcherid ], LifeUpgrade, true ) + 1.0 ) / 20
set Upgrade = upgrade
call ForForce( Team[ researcherid ].members, function AddUpgradeLevel_Enum )
if upgrade == DamageUpgrade then
set upgradeString = "weapons"
else
set upgradeString = "armor"
endif
set upgradeString = LIGHTGREY + PlayerName[ researcherid ] + LIGHTGREY + " has upgraded your team's " + upgradeString + " to level " + GOLD + I2S( GetPlayerTechCount( Players[ researcherid ], upgrade , true ) ) + LIGHTGREY + "." + EndTag
if ShowText and IsPlayerInForce( LOCAL_PLAYER, toupgrade ) then
call DisplayText( LOCAL_PLAYER, upgradeString )
endif
endfunction
private function Upgrader_Actions takes nothing returns nothing
local unit soldUnit = GetSoldUnit ( )
local integer soldUnitId = GetUnitTypeId ( soldUnit )
local player upgrader = GetOwningPlayer( soldUnit )
local integer upgraderId = GetPlayerId ( upgrader )
local boolean inTeam1 = IsPlayerAlly ( upgrader , Players[ 0 ] )
if soldUnitId == DamageItem then
call AddUpgradeLevel ( DamageUpgrade, Team[ upgraderId ].members, upgraderId )
call RemoveUnit( soldUnit )
call BilanceAddValue( upgraderId, -AutoUpgrader_UpgradeCost, "Team Upgrades" )
elseif soldUnitId == ArmorItem then
call AddUpgradeLevel ( LifeUpgrade, Team[ upgraderId ].members, upgraderId )
call RemoveUnit( soldUnit )
call BilanceAddValue( upgraderId, -AutoUpgrader_UpgradeCost, "Team Upgrades" )
endif
set soldUnit = null
endfunction
private function UpgraderInit takes nothing returns nothing
call TriggerRegisterAnyUnitEventBJ( Upgrader , EVENT_PLAYER_UNIT_SELL )
call TriggerAddAction ( Upgrader , function Upgrader_Actions )
endfunction
endlibrary
library AutoUpgrader initializer UpgraderInit needs UpgradeSystem
globals
private constant trigger AutoUpgrader = CreateTrigger()
public constant integer UpgradeCost = 1000
endglobals
function AutoUpgrader_Actions takes nothing returns nothing
local integer team1DLevel = GetPlayerTechCount( Players[ 0 ], DamageUpgrade, true ) + 1
local integer team1LLevel = GetPlayerTechCount( Players[ 0 ], LifeUpgrade , true ) + 1
local real team1Give = 1 + ( team1DLevel + team1LLevel ) / 20.0
local integer team2DLevel = GetPlayerTechCount( Players[ 1 ], DamageUpgrade, true ) + 1
local integer team2LLevel = GetPlayerTechCount( Players[ 1 ], LifeUpgrade , true ) + 1
local real team2Give = 1 + ( team2DLevel + team2LLevel ) / 20.0
local real sleepTime = GetRandomReal ( 100, 140 )
local integer localId = GetPlayerId( LOCAL_PLAYER )
local integer teamId = Team[ localId ].id
local string array msg
set msg[ 0 ] = PlayerNameUncolored[ 0 ] + LIGHTGREY + " has upgraded your team's creeps!"
set msg[ 1 ] = PlayerNameUncolored[ 1 ] + LIGHTGREY + " has upgraded your team's creeps!"
call AddPlayerTechResearched( PiratePlayer, LifeUpgrade , 1 )
call AddPlayerTechResearched( PiratePlayer, DamageUpgrade, 1 )
call SetPlayerState( Players[ 0 ], PLAYER_STATE_RESOURCE_GOLD, GetPlayerState( Players[ 0 ], PLAYER_STATE_RESOURCE_GOLD ) - 2 * UpgradeCost )
call SetPlayerState( Players[ 1 ], PLAYER_STATE_RESOURCE_GOLD, GetPlayerState( Players[ 1 ], PLAYER_STATE_RESOURCE_GOLD ) - 2 * UpgradeCost )
if ShowMessages[ localId ] then
call DisplayText( LOCAL_PLAYER, msg[ teamId ] )
endif
set ShowText = false
call AddUpgradeLevel( DamageUpgrade, Team[ 0 ].members, 0 )
call AddUpgradeLevel( LifeUpgrade , Team[ 0 ].members, 0 )
call AddUpgradeLevel( DamageUpgrade, Team[ 1 ].members, 1 )
call AddUpgradeLevel( LifeUpgrade , Team[ 1 ].members, 1 )
set ShowText = true
call SetPlayerBounty( 0, team1Give, 1 )
call SetPlayerBounty( 1, team2Give, 1 )
call SetPlayerBounty( GetPlayerId( PiratePlayer ), ( team1Give + team2Give ) / 2, 1 )
call TriggerSleepAction ( sleepTime )
call AutoUpgrader_Actions()
endfunction
private function UpgraderInit takes nothing returns nothing
call TriggerRegisterTimerEvent( AutoUpgrader, 145, false )
call TriggerAddAction ( AutoUpgrader, function AutoUpgrader_Actions )
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope Spell initializer INIT
globals
private constant integer ABIL_ID = 'A000'
private constant trigger SpellTrigger = CreateTrigger()
endglobals
private function Spell_Actions takes nothing returns nothing
local unit trigUnit = GetTriggerUnit()
local player trigPlayer = GetOwningPlayer( trigUnit )
local integer trigId = GetPlayerId( trigPlayer )
local integer level = GetUnitAbilityLevel( trigUnit, ABIL_ID )
if GetSpellAbilityId() == ABIL_ID then
endif
set trigUnit = null
endfunction
private function INIT_REALLY takes nothing returns nothing
call TriggerRegister
call TriggerAddAction( SpellTrigger, function Spell_Actions )
endfunction
private function INIT takes nothing returns nothing
call ExecuteFunc( SCOPE_PRIVATE + "INIT_REALLY" )
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope MOTW initializer INIT
globals
private constant integer ABIL_ID = 'A022'
private constant trigger SpellTrigger = CreateTrigger()
endglobals
private function Spell_Actions takes nothing returns nothing
local unit trigUnit = GetTriggerUnit()
local player trigPlayer = GetOwningPlayer( trigUnit )
local integer trigId = GetPlayerId( trigPlayer )
local integer level = GetUnitAbilityLevel( trigUnit, ABIL_ID )
if GetLearnedSkill() == ABIL_ID then
if level == 1 then
call UnitAddAbility( trigUnit, 'A01Z' )
endif
call SetUnitAbilityLevel( trigUnit, 'A020', level )
call SetUnitAbilityLevel( trigUnit, 'A021', level )
endif
set trigUnit = null
endfunction
private function INIT_REALLY takes nothing returns nothing
local integer i = 0
call TriggerRegisterAnyUnitEventBJ( SpellTrigger, EVENT_PLAYER_HERO_SKILL )
call TriggerAddAction( SpellTrigger, function Spell_Actions )
loop
exitwhen i > MAX_USER_SLOT
call SetPlayerAbilityAvailable( Players[ i ], 'A01Z', false )
set i = i + 1
endloop
endfunction
private function INIT takes nothing returns nothing
call ExecuteFunc( SCOPE_PRIVATE + "INIT_REALLY" )
endfunction
endscope
//TESH.scrollpos=749
//TESH.alwaysfold=1
//! runtextmacro AddItemValue( "Resource", "resource", "0" )
//! runtextmacro Attach( "TimerTradepoint", "timer", "tradepoint", "0" )
//! runtextmacro Attach( "TimerResource", "timer", "resource", "0" )
//! runtextmacro Attach( "NameResource", "string", "resource", "0" )
library TradeSystem initializer InitTS needs ResourceAttacherItem, ItemStacker, WeightAttacherItem, Utilities
function GetProductionFactor takes tradepoint trigTp, exresource trigRs returns real
return 1.0
endfunction
globals
debugger TradeDB
constant integer MaxResources = 40
constant integer MaxTradepoints = 200
constant integer MaxResourceStack = 250
constant real StateLossPerSecond = 12
constant real StateRegenPerSecond = 9
private unit Trader
private integer TradeAmount
private integer TradeAttachment
private resource TradeResource
private tradepoint TradeTradepoint
private player ConquestPlayer
public player Owner = null
public boolexpr CorOwner
private boolean array ShowTradeMessages
private trigger array TradeEventTrigger
private trigger array ConquestEventTrigger
private integer array EventId
private integer array Attachment
private integer TradeTriggers = 0
private integer ConquestTriggers = 0
integer AlliedUnitsInGroup
integer EnemyUnitsInGroup
player TestPlayer
constant integer EVENT_TRADE_SELL = -1
constant integer EVENT_TRADE_BUY = 1
constant integer EVENT_TRADE_ANY = 0
public resource array Resource
public tradepoint array Tradepoint
public constant trigger TradeTrigger = CreateTrigger()
public constant trigger PawnTrigger = CreateTrigger()
endglobals
//! runtextmacro RandomString( "private", "Attack" )
//! runtextmacro RandomString( "private", "Siege" )
//! runtextmacro RandomString( "private", "Success" )
//! runtextmacro State2Text( "Stash" )
//! runtextmacro PUI_PROPERTY( "", "tradepoint", "TradePoint", "0" )
function PlayerShowTradeMessages takes player p, boolean show returns nothing
set ShowTradeMessages[ GetPlayerId( p ) ] = show
endfunction
function CorrectOwner takes nothing returns boolean
return GetOwningPlayer( GetFilterUnit() ) == Owner
endfunction
function GetConquestPlayer takes nothing returns player
return ConquestPlayer
endfunction
function GetTriggerTradepoint takes nothing returns tradepoint
return TradeTradepoint
endfunction
function GetTriggerResource takes nothing returns resource
return TradeResource
endfunction
function GetTriggerAmount takes nothing returns integer
return TradeAmount
endfunction
function GetTriggerAttachment takes nothing returns integer
return TradeAttachment
endfunction
function GetTradingUnit takes nothing returns unit
return Trader
endfunction
function TriggerRegisterConquestEvent takes trigger register returns nothing
set ConquestTriggers = ConquestTriggers + 1
set ConquestEventTrigger[ ConquestTriggers ] = register
endfunction
function TriggerClearConquestEvent takes trigger register returns nothing
local integer index = 0
local integer outdex
loop
exitwhen index > ConquestTriggers
if ConquestEventTrigger[ ConquestTriggers ] == register then
set outdex = index
loop
exitwhen outdex == ConquestTriggers
set Attachment[ outdex ] = Attachment[ outdex + 1 ]
set ConquestEventTrigger[ outdex ] = ConquestEventTrigger[ outdex + 1 ]
set outdex = outdex + 1
endloop
set ConquestTriggers = ConquestTriggers - 1
endif
set index = index + 1
endloop
endfunction
function CallConquestTriggers takes player conqueror, tradepoint conquesttp returns nothing
local integer index = 0
set ConquestPlayer = conqueror
set TradeTradepoint = conquesttp
loop
exitwhen index > ConquestTriggers
if TriggerEvaluate( ConquestEventTrigger[ index ] ) then
call TriggerExecute( ConquestEventTrigger[ index ] )
endif
set index = index + 1
endloop
endfunction
function TriggerRegisterTradeEvent takes trigger register, integer eventId, integer attachment returns nothing
set TradeTriggers = TradeTriggers + 1
set TradeEventTrigger[ TradeTriggers ] = register
set Attachment[ TradeTriggers ] = attachment
set EventId[ TradeTriggers ] = eventId
endfunction
function TriggerClearTradeActions takes trigger register returns nothing
local integer index = 0
local integer outdex
loop
exitwhen index > TradeTriggers
if TradeEventTrigger[ TradeTriggers ] == register then
set outdex = index
loop
exitwhen outdex == TradeTriggers
set Attachment[ outdex ] = Attachment[ outdex + 1 ]
set EventId[ outdex ] = EventId[ outdex + 1 ]
set TradeEventTrigger[ outdex ] = TradeEventTrigger[ outdex + 1 ]
set outdex = outdex + 1
endloop
set TradeTriggers = TradeTriggers - 1
endif
set index = index + 1
endloop
endfunction
function CallTradeTriggers takes integer amount, resource traders, tradepoint tradetp, unit trader returns nothing
local integer index = 0
local integer eventId = ISignBJ( amount )
if amount != 0 then
set TradeAmount = amount
set TradeResource = traders
set TradeTradepoint = tradetp
set Trader = trader
loop
exitwhen index > TradeTriggers
if TriggerEvaluate( TradeEventTrigger[ index ] ) and EventId[ index ] * eventId >= 0 then
set TradeAttachment = Attachment[ index ]
call TriggerExecute( TradeEventTrigger[ index ] )
endif
set index = index + 1
endloop
else
set TradeAmount = 0
set TradeResource = 0
set TradeTradepoint = 0
endif
endfunction
function FilterNonTradepoint takes nothing returns boolean
local unit filterUnit = GetFilterUnit()
local player filterPlayer = GetOwningPlayer( filterUnit )
local boolean filter = GetUnitState( filterUnit, UNIT_STATE_LIFE ) >= 0 and ( IsUnitType( filterUnit, UNIT_TYPE_STRUCTURE ) == false )and GetPlayerId( filterPlayer ) < MAX_USER_SLOT and IsUnitVisible( TradeTradepoint.model, filterPlayer )
set filterUnit = null
return filter
endfunction
function CountAllied_LoopAction takes nothing returns nothing
if IsUnitAlly( GetEnumUnit(), TestPlayer ) then
set AlliedUnitsInGroup = AlliedUnitsInGroup + 1
else
set EnemyUnitsInGroup = EnemyUnitsInGroup + 1
endif
endfunction
function CountOwn_LoopAction takes nothing returns nothing
if GetOwningPlayer( GetEnumUnit() ) == TestPlayer then
set AlliedUnitsInGroup = AlliedUnitsInGroup + 1
endif
endfunction
function CountAlliedUnitsInRange takes real x, real y, real radius, player testplayer returns integer
local group g = GLOBAL_GROUP
call GroupClear( g )
call GroupEnumUnitsInRange( g, x, y, radius, Condition( function FilterNonTradepoint ) )
set EnemyUnitsInGroup = 0
set AlliedUnitsInGroup = 0
set TestPlayer = testplayer
call ForGroup( g, function CountAllied_LoopAction )
return AlliedUnitsInGroup
endfunction
function OwnerOfMostUnitsInRange takes real x, real y, real radius returns player
local group g = GLOBAL_GROUP
local integer playerIndex = 0
local player curPlayer = null
local integer curUnits = 0
call GroupEnumUnitsInRange( g, x, y, radius, Condition( function FilterNonTradepoint ) )
loop
exitwhen playerIndex > MAX_PLAYER_SLOT
set EnemyUnitsInGroup = 0
set AlliedUnitsInGroup = 0
set TestPlayer = Players[ playerIndex ]
call ForGroup( g, function CountOwn_LoopAction )
if AlliedUnitsInGroup > curUnits then
set curPlayer = Players[ playerIndex ]
set curUnits = AlliedUnitsInGroup
endif
set playerIndex = playerIndex + 1
endloop
return curPlayer
endfunction
function IsFilterUnitTradePoint takes nothing returns boolean
return TradePoint[ GetFilterUnit() ] != 0
endfunction
struct resource
string name
integer baseValue
integer itemId
integer id
integer maxAmount
static constant integer startStack = 0
static integer count = 0
static method create takes string name, integer basevalue, integer itemtypeid, integer weight, integer maxstack returns resource
local resource this
local integer tpIndex = 0
if resource.count >= MaxResources then
debug call BJDebugMsg( RED + "Too many Resources. Please increment MaxResources." )
return 0
endif
set this = resource.allocate()
set .name = name
set .baseValue = basevalue
set .itemId = itemtypeid
set .maxAmount = maxstack
set .id = .count
set .count = .count + 1
set Resource[ .id ] = this
call SetItemTypeResource( itemtypeid, this )
call SetItemTypeWeight( itemtypeid, weight )
call SetItemTypeMaxStack( itemtypeid, 100 )
set NameResource[ StringCase( name, false ) ] = this
return this
endmethod
static method S2Resource takes string name returns resource
return NameResource[ StringCase( name, false ) ]
endmethod
method onDestroy takes nothing returns nothing
local integer id
call SetItemTypeResource( .itemId, ResourceAttacherItem_GetDefaultResource() )
set resource.count = resource.count - 1
set id = .id
set NameResource[ .name ] = 0
set Resource[ id ] = Resource[ resource.count ]
set Resource[ resource.count ] = 0
set Resource[ id ].id = id
endmethod
endstruct
struct tradepoint
string name
unit model
boolean attacked = false
boolean array onScreen[ NUMPLAYERS ]
delegate resourceset deposits
static integer count = 0
region lookUpRegion
real ownState
integer id
real regen
real loss
timer regenerationTimer
static constant real LOOKUPRANGE = 800
static constant real INTERVAL = 0.33
string funcToExec
texttag display
real xVal
real yVal
method operator x takes nothing returns real
return .xVal
endmethod
method operator y takes nothing returns real
return .yVal
endmethod
method operator x= takes real x returns nothing
set .xVal = x
call SetUnitX( .model, x )
endmethod
method operator y= takes real y returns nothing
set .yVal = y
call SetUnitX( .model, y )
endmethod
static method conquer takes nothing returns nothing
local tradepoint this = GetTimerTradepoint( GetExpiredTimer() )
local player localPlayer = GetLocalPlayer()
local player tpOwner = GetOwningPlayer( .model )
local player conqueror
local integer tpOwnerId = GetPlayerId( tpOwner )
local string ownerName = PlayerName[ tpOwnerId ]
local boolean tpAlly = IsPlayerAlly( localPlayer, tpOwner )
local boolean conquerorAlly = not tpAlly
local real lossFactor = .INTERVAL / 100
set TradeTradepoint = this
if not .attacked then
set .attacked = true
if tpAlly then
call DisplayTextToPlayer( localPlayer, 0, 0, RED + .name + " is under " + GetSiegeString() + "!" )
elseif conquerorAlly then
call DisplayTextToPlayer( localPlayer, 0, 0, GREEN + "An ally has started to " + GetSiegeString() + " " + .name + "!" )
else
call DisplayTextToPlayer( localPlayer, 0, 0, GOLD + PlayerName[ GetPlayerId( conqueror ) ] + GOLD + " has started to " + GetSiegeString() + " " + .name + "." )
endif
endif
if .ownState <= 0 then
set conqueror = OwnerOfMostUnitsInRange( .x, .y, tradepoint.LOOKUPRANGE )
call SetUnitOwner( .model, conqueror, true )
set .ownState = 0.1
set conquerorAlly = IsPlayerAlly( localPlayer, conqueror )
if tpAlly then
call DisplayTextToPlayer( localPlayer, 0, 0, RED + .name + " has fallen to the " + GetAttackString() + "!" )
elseif conquerorAlly then
call DisplayTextToPlayer( localPlayer, 0, 0, GREEN + "We have conquered " + .name + "!" )
else
call DisplayTextToPlayer( localPlayer, 0, 0, GOLD + .name + " has been conquered." )
endif
call CallConquestTriggers( conqueror, this )
call TimerStart( .regenerationTimer, .INTERVAL, true, function tradepoint.regenerate )
endif
call CountAlliedUnitsInRange( .x, .y, tradepoint.LOOKUPRANGE, tpOwner )
if EnemyUnitsInGroup > 0 and AlliedUnitsInGroup == 0 then
set .ownState = .ownState - .loss * lossFactor
else
call CountAlliedUnitsInRange( .x, .y, tradepoint.LOOKUPRANGE + 400, tpOwner )
if EnemyUnitsInGroup == 0 then
if tpAlly then
call DisplayTextToPlayer( localPlayer, 0, 0, GREEN + .name + " has " + GetSuccessString() + " fended the " + GetAttackString() + "!" )
elseif conquerorAlly then
call DisplayTextToPlayer( localPlayer, 0, 0, RED + "The " + GetAttackString() + " on " + .name + " has failed." )
else
call DisplayTextToPlayer( localPlayer, 0, 0, GOLD + "The " + GetAttackString() + " on " + .name + " could be defended." )
endif
call TimerStart( .regenerationTimer, .INTERVAL, true, function tradepoint.regenerate )
endif
endif
endmethod
static method regenerate takes nothing returns nothing
local tradepoint this = GetTimerTradepoint( GetExpiredTimer() )
local real regenFactor = .INTERVAL / 100
local player owner = GetOwningPlayer( .model )
local integer i = 0
set .attacked = false
set TradeTradepoint = this
call CountAlliedUnitsInRange( .x, .y, tradepoint.LOOKUPRANGE, owner )
if EnemyUnitsInGroup > 0 then
call TimerStart( .regenerationTimer, .INTERVAL, true, function tradepoint.conquer )
elseif .ownState + .regen * regenFactor <= 1 then
set .ownState = .ownState + .regen * regenFactor
else
set .ownState = 1
endif
loop
exitwhen i > MAX_USER_SLOT
call .showText( Players[ i ] )
set i = i + 1
endloop
call .updateResources()
endmethod
static method create takes player owner, string name, real x, real y, integer unittypeid returns tradepoint
local tradepoint this
local integer index = 0
if .count >= MaxTradepoints then
debug call BJDebugMsg( RED + "Too many Tradepoints. Please increment MaxTradepoints." )
return 0
endif
set this = .allocate()
set .funcToExec = SCOPE_PRIVATE + "Change_View"
set .display = CreateTextTag()
call SetTextTagPos( .display, x, y, 32 )
set .x = x
set .y = y
set .lookUpRegion = CreateRegion()
set .deposits = resourceset.create()
set .model = CreateUnit( owner, unittypeid, x, y, 270 )
set .name = name
set .ownState = 0.9
set .loss = StateLossPerSecond
set .regen = StateRegenPerSecond
set .attacked = false
set .id = .count
set .count = .count + 1
set Tradepoint[ .id ] = this
set TradePoint[ .model ] = this
loop
exitwhen index > MAX_PLAYER_SLOT
set .onScreen[ index ] = false
set index = index + 1
endloop
set index = 0
set .regenerationTimer = CreateTimer()
call TimerStart( .regenerationTimer, .INTERVAL, true, function tradepoint.regenerate )
call SetTimerTradepoint( .regenerationTimer, this )
return this
endmethod
method toText takes player viewer returns string
local real rsState
local exresource curRs = .deposits.first
local player tpOwner = GetOwningPlayer( .model )
local integer tpOwnerId = GetPlayerId( tpOwner )
local string ownerName = PlayerName[ tpOwnerId ]
local string msg
if IsPlayerAlly( tpOwner, viewer ) then
set msg = GREEN + .name + "\n" + ownerName + State2Color( .ownState ) + " " + I2S( R2I( 100 * .ownState + 0.5 ) ) + "%\n"
loop
exitwhen curRs == 0
set rsState = ( curRs.amount + 0.0 ) / curRs.maxAmount
set msg = msg + GREY + curRs.name + ": " + State2Color( rsState ) + Stash2Text( rsState ) + GREY + " (" + GOLD + I2S( .getCost( curRs.kind, 1 ) ) + GREY + ")\n"
set curRs = curRs.next
endloop
else
set msg = RED + .name + "\n" + ownerName + State2Color( 1 - .ownState ) + " " + I2S( R2I( 100 * .ownState ) ) + "%\n"
endif
return msg
endmethod
// amount < 0: trader sells, amount > 0: trader buys
// Pow( 1.4, production / 6.0 )
// ( 2 - Pow( 1.4, - production / 6.0 ) )
method getCost takes resource tradeobject, integer amount returns integer
local exresource tradeRs = .deposits.getResource( tradeobject )
local integer stock = tradeRs.amount
local real stockState
local integer cost = 0
local integer delta = ISignBJ( amount )
local real baseValue = delta * tradeRs.baseValue
local integer turns = 0
set baseValue = baseValue * GetProductionFactor( this, tradeRs )
if delta == 1 then
set amount = IMinBJ( amount, stock )
else
set amount = IMaxBJ( amount, stock - tradeRs.maxAmount )
endif
loop
set stockState = ( stock + 0.0 ) / tradeRs.maxAmount
set cost = cost + R2I( baseValue * ( 1.4 - 0.8 * stockState ) + .5 )
set stock = stock + delta
set amount = amount - delta
set turns = turns + 1
exitwhen delta * amount <= 0
endloop
if delta > 0 then
set cost = R2I( cost )
else
set cost = R2I( cost * 0.8 )
endif
return cost
endmethod
method showText takes player viewer returns nothing
set Owner = viewer
set TradeTradepoint = this
call ExecuteFunc( .funcToExec )
endmethod
method toScreen takes player viewer returns nothing
local string msg
local integer viewId = GetPlayerId( viewer )
local boolean isLocal = LOCAL_PLAYER == viewer
if IsUnitVisible( .model, viewer ) then
if not .onScreen[ viewId ] then
set .onScreen[ viewId ] = true
if isLocal then
call SetTextTagVisibility( .display, true )
endif
endif
set msg = .toText( viewer )
if isLocal then
call SetTextTagText( .display, msg, 0.019 )
endif
else
if isLocal then
call SetTextTagVisibility( .display, false )
endif
endif
endmethod
method updateResources takes nothing returns nothing
local integer i = 0
local resource curRs
loop
exitwhen i >= resource.count
set curRs = Resource[ i ]
call AddItemToStock( .model, curRs.itemId, .getAmount( curRs ), curRs.maxAmount )
set i = i + 1
endloop
endmethod
method buyFrom takes unit buyUnit, item trigItem returns integer
local player trigPlayer = GetOwningPlayer( buyUnit )
local integer trigItemId = GetItemTypeId( trigItem )
local resource itemResource = GetItemTypeResource( trigItemId )
local exresource trigRs = .deposits.getResource( itemResource )
local integer stack = GetItemCharges( trigItem )
local integer cost
local integer gold = GetPlayerState( trigPlayer, PLAYER_STATE_RESOURCE_GOLD )
local integer weight
local integer cargo
local integer maxCargo
local boolean show = ShowTradeMessages[ GetPlayerId( trigPlayer ) ]
if ( trigRs != 0 ) and ( stack > trigRs.amount - trigRs.maxAmount / 10 ) then
call TradeDB.Debug( "Fault A")
set stack = trigRs.amount - trigRs.maxAmount / 10
if stack < 0 then
set stack = 0
endif
endif
set weight = GetItemTypeWeight( trigItemId )
set cargo = GetUnitCargo( buyUnit ) + weight * stack
set maxCargo = GetUnitMaxCargo( buyUnit )
if cargo > maxCargo then
call TradeDB.Debug( "Fault B")
call TradeDB.Debug( "Old Stack: " + I2S( stack ) )
set stack = stack - R2I( I2R( cargo - maxCargo ) / weight + 0.999 )
call TradeDB.Debug( "New Stack: " + I2S( stack ) )
call TradeDB.Debug( "Max Cargo: " + I2S( maxCargo ) )
call TradeDB.Debug( "Old Cargo: " + I2S( cargo ) )
set cargo = GetUnitCargo( buyUnit ) + weight * stack
endif
call SetUnitCargo( buyUnit, GetUnitCargo( buyUnit ) + weight*stack )
if ( trigRs == 0 ) or ( trigRs.amount == 0 ) then
call RemoveItem( trigItem )
if show then
call DisplayTextToPlayer( trigPlayer, 0, 0, RED + "No " + itemResource.name + " available in " + .name + "." )
endif
elseif ( stack == 0 ) then
call RemoveItem( trigItem )
if show then
call DisplayTextToPlayer( trigPlayer, 0, 0, RED + "No " + itemResource.name + " could be bought." )
endif
else
call SetItemCharges( trigItem, stack )
set cost = .getCost( itemResource, stack )
if cost <= gold then
set gold = gold - cost
call CreateBountyText( -cost, .model, trigPlayer )
call SetPlayerState( trigPlayer, PLAYER_STATE_RESOURCE_GOLD, gold )
set trigRs.amount = trigRs.amount - stack
call CallTradeTriggers( stack, itemResource, this , buyUnit )
else
if show then
call DisplayTextToPlayer( trigPlayer, 0, 0, RED + "Not enough gold (" + GOLD + I2S( cost ) + RED + ")." )
endif
call RemoveItem( trigItem )
endif
endif
set trigItem = null
set buyUnit = null
return stack
endmethod
method sellTo takes unit sellUnit, item trigItem returns integer
local player trigPlayer = GetOwningPlayer( sellUnit )
local integer trigItemId = GetItemTypeId( trigItem )
local resource itemResource = GetItemResource( trigItem )
local exresource trigRs = .deposits.getResource( itemResource )
local integer stack = GetItemCharges( trigItem )
local integer restStack = 0
local item restItem
local integer reward
local integer room
local integer gold = GetPlayerState( trigPlayer, PLAYER_STATE_RESOURCE_GOLD )
local boolean show = ShowTradeMessages[ GetPlayerId( trigPlayer ) ]
if trigRs == 0 then
call .deposits.setAmount( itemResource, itemResource.startStack )
set trigRs = .deposits.getResource( itemResource )
endif
set room = trigRs.maxAmount - trigRs.amount
if stack > room then
set restStack = stack - room
set stack = room
endif
if stack > 0 then
set reward = -.getCost( itemResource, -stack )
set gold = gold + reward
call CreateBountyText( reward, sellUnit, trigPlayer )
set trigRs.amount = trigRs.amount + stack
call SetPlayerState( trigPlayer, PLAYER_STATE_RESOURCE_GOLD, gold )
call CallTradeTriggers( -stack, itemResource, this, sellUnit )
elseif show then
call DisplayTextToPlayer( trigPlayer, 0, 0, RED + "Stocks are allready full!" )
endif
call RemoveItem( trigItem )
if restStack > 0 then
set restItem = CreateItem( trigItemId, GetUnitX( sellUnit ), GetUnitY( sellUnit ) )
call SetItemCharges( restItem, restStack )
call UnitAddItem( sellUnit, restItem )
endif
set restItem = null
set trigItem = null
set sellUnit = null
return restStack
endmethod
static method operator [] takes integer index returns tradepoint
return Tradepoint[ index ]
endmethod
endstruct
private function PawnTrigger_Actions takes nothing returns boolean
local unit sellUnit = GetSellingUnit()
local unit buyUnit = GetBuyingUnit()
local tradepoint trigTp = TradePoint[ buyUnit ]
local item trigItem = GetSoldItem()
local integer trigItemId = GetItemTypeId( trigItem )
local integer playerId = GetPlayerId( GetOwningPlayer( sellUnit ) )
local resource itemResource = GetItemResource( trigItem )
local boolean proceed = itemResource != 0
if trigTp == 0 then
if ShowTradeMessages[ playerId ] then
call DisplayTextToPlayer( Players[ playerId ], 0, 0, RED + "This is no tradepoint! Resources can only be sold to tradepoints." )
endif
elseif proceed then
call trigTp.sellTo( sellUnit, trigItem )
endif
set trigItem = null
set sellUnit = null
set buyUnit = null
return true
endfunction
private function TradeTrigger_Actions takes nothing returns boolean
local unit sellUnit = GetSellingUnit()
local unit buyUnit = GetBuyingUnit()
local tradepoint trigTp = TradePoint[ sellUnit ]
local item trigItem = GetSoldItem()
local integer trigItemId = GetItemTypeId( trigItem )
local resource itemResource = GetItemTypeResource( trigItemId )
local boolean proceed = trigTp != 0 and itemResource != 0
if proceed then
call trigTp.buyFrom( buyUnit, trigItem )
endif
set trigItem = null
set sellUnit = null
set buyUnit = null
return true
endfunction
private function Change_View takes nothing returns nothing
call TradeTradepoint.toScreen( Owner )
endfunction
struct exresource
delegate resource kind
integer amount
exresource last
exresource next
resourceset parent
static method create takes resource kind, integer amount, resourceset parent returns exresource
local exresource this = .allocate()
set .kind = kind
set .amount = amount
set .last = parent.last
set .last.next = this
set parent.last = this
set .parent = parent
set .next = 0
if parent.first == 0 then
set parent.first = this
endif
return this
endmethod
endstruct
struct resourceset
exresource first = 0
exresource last = 0
static method create takes nothing returns resourceset
local resourceset this = .allocate()
return this
endmethod
method getResource takes resource rs returns exresource
local exresource curResource = .first
loop
exitwhen curResource == 0
if curResource.kind == rs then
return curResource
endif
set curResource = curResource.next
endloop
return 0
endmethod
method getAmount takes resource rs returns integer
return .getResource( rs ).amount
endmethod
method setAmount takes resource rs, integer toset returns nothing
local exresource curResource = .first
loop
exitwhen curResource == 0
if curResource.kind == rs then
set curResource.amount = toset
return
endif
set curResource = curResource.next
endloop
call exresource.create( rs, toset, this )
endmethod
method addAmount takes resource rs, integer toadd returns nothing
local exresource curResource = .first
local integer result
loop
exitwhen curResource == 0
if curResource.kind == rs then
set result = curResource.amount + toadd
set result = IMinBJ( curResource.maxAmount, IMaxBJ( result, 0 ) )
set curResource.amount = result
return
endif
set curResource = curResource.next
endloop
call exresource.create( rs, toadd, this )
endmethod
endstruct
private function InitTS takes nothing returns nothing
local integer i = 0
if MaxResources * MaxTradepoints > 8190 then
call DisplayTextToPlayer( GetLocalPlayer(), 0, 0, RED + "WARNING: MaxResources and/or MaxTradepoints are too high. Please decrease or you might suffer a Crash!" )
endif
call TriggerRegisterAnyUnitEventBJ( TradeTrigger, EVENT_PLAYER_UNIT_SELL_ITEM )
call TriggerAddCondition( TradeTrigger, Condition( function TradeTrigger_Actions ) )
call TriggerRegisterAnyUnitEventBJ( PawnTrigger, EVENT_PLAYER_UNIT_PAWN_ITEM )
call TriggerAddCondition( PawnTrigger, Condition( function PawnTrigger_Actions ) )
call AddSiegeString( "attack" )
call AddSiegeString( "siege" )
call AddSiegeString( "assault" )
call AddSuccessString( "successfully" )
call AddSuccessString( "triumphantly" )
call AddSuccessString( "effectively" )
call AddSuccessString( "" )
call AddAttackString( "attack" )
call AddAttackString( "ambush" )
call AddAttackString( "assault" )
call AddAttackString( "strike" )
call AddAttackString( "raid" )
call Text2Stash( "Empty depot", 0 )
call Text2Stash( "Needed", .20 )
call Text2Stash( "Insufficient supply", .35 )
call Text2Stash( "In stock", .50 )
call Text2Stash( "Sufficiently in stock", .70 )
call Text2Stash( "Depot is Full", .90 )
set CorOwner = Filter( function CorrectOwner )
set TradeDB = debugger.create( "TradeSystem" )
loop
exitwhen i > MAX_PLAYER_SLOT
set ShowTradeMessages[ i ] = true
set i = i + 1
endloop
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
//! runtextmacro Attach( "TradepointTown", "tradepoint", "town", "0" )
//! runtextmacro Attach( "TimerTown", "timer", "town", "0" )
globals
constant integer PRODUCTION_TIME = 1
endglobals
//! textmacro resources
set Food = resource.create( "Food", 75, 'I00N', 10, 1000 )
//! endtextmacro
library TradepointUpgradeSystem initializer INIT needs Utilities, TradepointTown, TradeSystem
//! runtextmacro State2Text( "Population" )
globals
resource Food
endglobals
struct buildingtype
buildinglevel first
buildinglevel last
string name
integer levels
integer priority
static method create takes string name, integer priority returns buildingtype
local buildingtype this = .allocate()
set .name = name
set .levels = 0
set .first = 0
set .last = 0
set .priority = priority
return this
endmethod
endstruct
struct buildinglevel
resourceset production
resourceset consumption
resourceset upgradeCost
integer capacity
buildinglevel next
buildinglevel last
buildingtype parent
static method create takes buildingtype parent, resourceset production, resourceset consumption, resourceset upgradecost, integer capacity returns buildinglevel
local buildinglevel this = .allocate()
set .parent = parent
set .production = production
set .consumption = consumption
set .next = 0
set .parent.last = this
set .capacity = capacity
set .parent.levels = .parent.levels + 1
if .parent.first == 0 then
set .parent.first = this
set .last = 0
else
set .last.upgradeCost = upgradecost
set .last = .parent.last
set .last.next = this
endif
return this
endmethod
endstruct
struct building
delegate buildingtype kind
delegate buildinglevel curLevel
building last
building next
integer level
integer workers
real productionFactor
town loc
static method create takes buildingtype kind, town loc returns building
local building this = .allocate()
local building curBuilding = loc.first
set .kind = kind
set .curLevel = .first
set .loc = loc
set .level = 1
loop
exitwhen curBuilding == 0
exitwhen .priority > curBuilding.priority
set curBuilding = curBuilding.next
endloop
if curBuilding == 0 then
set .next = 0
set .last = .loc.last
set .loc.last = this
if .loc.first == 0 then
set .loc.first = this
endif
else
set .last = curBuilding.last
set .next = curBuilding.next
set curBuilding.last = this
set .last.next = this
endif
set .workers = 0
call .addWorkers( .capacity, true, false )
return this
endmethod
method addWorkers takes integer toAdd, boolean next, boolean continue returns nothing
local integer added = IMinBJ( toAdd , IMinBJ( .loc.freeWorkers, .capacity - .workers ) )
// Adds as many workers as possible. Either as many as needed, or as many as there are.
set .workers = .workers + added
if .capacity > 0 then
set .productionFactor = ( .workers + 0.0 )/ ( .capacity )
else
set .productionFactor = 1
endif
set .loc.freeWorkers = .loc.freeWorkers - added
if toAdd > added and continue then
if ( next and .next != 0 ) then
call .next.addWorkers( toAdd - added, next, continue )
elseif .last != 0 then
call .last.addWorkers( toAdd - added, next, continue )
endif
endif
endmethod
method tryUpgrade takes nothing returns boolean
if ( .level < .levels ) and ( .loc.checkAndSubstract( .upgradeCost ) ) then
set .curLevel = .curLevel.next
set .level = .level + 1
call .addWorkers( .capacity - .workers, true, false )
//call DisplayText( GetOwningPlayer( .loc.model ), GREEN + "Upgraded " + .name + " in " + .loc.name + " (" + I2S( .level ) + "/" + I2S( .levels ) + ")" )
return true
endif
return false
endmethod
endstruct
struct town
delegate tradepoint tp
integer population
integer freeWorkers
real happiness
real taxes
timer ticker
building first
building last
integer prodTicks
static constant real SLEEP = 1.00
static method create takes player owner, string name, real x, real y, integer unittypeid returns town
local town this = .allocate()
set .tp = tradepoint.create( owner, name, x, y, unittypeid )
set TradepointTown[ .tp ] = this
set .taxes = 0.01
set .population = 10
set .freeWorkers = 10
set .happiness = 1
set .ticker = CreateTimer()
set TimerTown[ .ticker ] = this
set .first = 0
set .last = 0
set .prodTicks = 0
call TimerStart( .ticker, .SLEEP, true, function town.Produce )
set .funcToExec = SCOPE_PRIVATE + "ShowThis"
return this
endmethod
method checkAndSubstract takes resourceset tocheck returns boolean
local exresource curRs = tocheck.first
local exresource array locResource
local exresource array checkResource
local integer i = 0
local integer maxI
loop
exitwhen curRs == 0
set locResource[ i ] = .getResource( curRs.kind )
set checkResource[ i ] = curRs
if locResource[ i ] == 0 or locResource[ i ].amount < curRs.amount then
return false
endif
set curRs = curRs.next
endloop
set maxI = i
set i = 0
loop
exitwhen i > maxI
set locResource[ i ].amount = locResource[ i ].amount - checkResource[ i ].amount
set i = i + 1
endloop
return true
endmethod
static method Produce takes nothing returns nothing
local town this = TimerTown[ GetExpiredTimer() ]
local player owner = GetOwningPlayer( .model )
local building curBuilding = .first
local exresource curRs
local exresource array locResource
local exresource array checkResource
local boolean hasResources
local integer i = 0
local integer maxI
local integer foodConsumption
local integer food
local integer dPopulation
local real happinessFactor = ( 1 + .happiness ) / 2
local real productionFactor
set .prodTicks = .prodTicks + 1
if .prodTicks == PRODUCTION_TIME then
set .prodTicks = 0
loop
exitwhen curBuilding == 0
set curRs = curBuilding.consumption.first
set hasResources = true
set productionFactor = curBuilding.productionFactor * happinessFactor
loop
exitwhen curRs == 0
set locResource[ i ] = .getResource( curRs.kind )
set checkResource[ i ] = curRs
if locResource[ i ] == 0 or locResource[ i ].amount < curRs.amount * productionFactor then
set hasResources = false
call curBuilding.addWorkers( - curBuilding.capacity / 10, false, false )
exitwhen true
endif
set i = i + 1
set curRs = curRs.next
endloop
if hasResources then
set maxI = i
set i = 0
loop
exitwhen i >= maxI
set locResource[ i ].amount = locResource[ i ].amount - R2I( checkResource[ i ].amount * productionFactor )
set i = i + 1
endloop
set curRs = curBuilding.production.first
loop
exitwhen curRs == 0
call .addAmount( curRs.kind, R2I( curRs.amount * productionFactor ) )
set curRs = curRs.next
endloop
endif
set curBuilding = curBuilding.next
endloop
set foodConsumption = R2I( .population * 0.06 + 1 )
set food = .getAmount( Food )
if foodConsumption > food then
set dPopulation = -foodConsumption + 1
call .changeHappiness( 0.9 )
else
set dPopulation = R2I( SquareRoot( foodConsumption * ( happinessFactor ) ) )
call .changeHappiness( 1.02 * ( 1 - .taxes ) )
endif
//! runtextmacro AddPlayerState( "owner", "RESOURCE_GOLD", "R2I( .population * .taxes )" )
call .changePopulation( dPopulation )
if .population > 16 then
call .changeHappiness( 1.1 - ( .freeWorkers - 16.0 )/( .population - 15 ) )
endif
call .addAmount( Food, -foodConsumption )
endif
endmethod
method changePopulation takes integer toChange returns nothing
set toChange = IMaxBJ( toChange, -.population )
set .population = .population + toChange
set .freeWorkers = .freeWorkers + toChange
if .freeWorkers > 0 and .first != 0 then
call .first.addWorkers( .freeWorkers, true, true )
elseif .last != 0 then
call .last.addWorkers( .freeWorkers, false, true )
endif
endmethod
method changeHappiness takes real alter returns nothing
set .happiness = .happiness * alter
if .happiness < 0.01 then
set .happiness = 0.01
endif
endmethod
method toText takes player viewer returns string
local real rsState
local exresource curRs = .deposits.first
local player tpOwner = GetOwningPlayer( .model )
local integer tpOwnerId = GetPlayerId( tpOwner )
local string ownerName = PlayerName[ tpOwnerId ]
local string msg
if IsPlayerAlly( tpOwner, viewer ) then
set msg = GREEN + .name + "\n" + ownerName + State2Color( .ownState ) + " " + I2S( R2I( 100 * .ownState + 0.5 ) ) + "%\n "
set msg = msg + GREY + "Population: " + Population2Text( .population ) + "/" + I2S( R2I( .happiness * 100 ) ) + "\n "
loop
exitwhen curRs == 0
set rsState = ( curRs.amount + 0.0 ) / curRs.maxAmount
set msg = msg + GREY + curRs.name + ": " + State2Color( rsState ) + Stash2Text( rsState ) + GREY + " (" + GOLD + I2S( .getCost( curRs.kind, 1 ) ) + GREY + ")\n "
set curRs = curRs.next
endloop
else
set msg = RED + .name + "\n" + ownerName + State2Color( 1 - .ownState ) + " " + I2S( R2I( 100 * .ownState ) ) + "%\n"
endif
return msg
endmethod
method toScreen takes player viewer returns nothing
local string msg
local integer viewId = GetPlayerId( viewer )
local boolean isLocal = LOCAL_PLAYER == viewer
if IsUnitVisible( .model, viewer ) then
if not .onScreen[ viewId ] then
set .onScreen[ viewId ] = true
if isLocal then
call SetTextTagVisibility( .display, true )
endif
endif
set msg = .toText( viewer )
if isLocal then
call SetTextTagText( .display, msg, 0.019 )
endif
else
if isLocal then
call SetTextTagVisibility( .display, false )
endif
endif
endmethod
method tryUpgrade takes nothing returns integer
local building curBuilding = .first
local integer count = 0
loop
exitwhen curBuilding == 0
if curBuilding.tryUpgrade() then
set count = count + 1
endif
set curBuilding = curBuilding.next
endloop
return count
endmethod
endstruct
private function ShowThis takes nothing returns nothing
local town toShow = TradepointTown[ GetTriggerTradepoint() ]
call toShow.toScreen( TradeSystem_Owner )
endfunction
private function INIT takes nothing returns nothing
//! runtextmacro resources()
call Text2Population( State2Color( 0.0 ) + "None", 0 )
call Text2Population( State2Color( 0.2 ) + "Low", 20 )
call Text2Population( State2Color( 1.0 ) + "Mediocre", 50 )
call Text2Population( State2Color( 0.9 ) + "High", 150 )
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library TradeRoute initializer InitTR needs TradeSystem
//! runtextmacro PUI_PROPERTY( "", "traderoute", "Traderoute", "0" )
//! runtextmacro State2Text( "DepotState" )
//! runtextmacro RandomString( "private", "TOOMANYORDERS" )
globals
public constant trigger OrderHandler = CreateTrigger()
public constant integer MaxTradeOrders = 15
endglobals
struct traderoute
tradepoint array Loc[MaxTradeOrders]
resource array Rs[MaxTradeOrders]
integer array Amount[MaxTradeOrders]
real array TradeCondition[MaxTradeOrders]
unit toOrder
integer orders
integer currentOrder
boolean inOrder
static constant integer TRADERANGE = 450
static method create takes unit toOrder returns traderoute
local traderoute new = traderoute.allocate()
set new.orders = 0
set new.currentOrder = - 1
set new.toOrder = toOrder
set new.inOrder = false
set Traderoute[ toOrder ] = new
call TriggerRegisterUnitEvent( OrderHandler, toOrder, EVENT_UNIT_ISSUED_POINT_ORDER )
call TriggerRegisterUnitEvent( OrderHandler, toOrder, EVENT_UNIT_ISSUED_TARGET_ORDER )
set toOrder = null
return new
endmethod
method addTradepoint takes tradepoint toadd, resource totrade, integer amount, real tradecondition returns integer
local integer index = .orders - 1
local integer i = index
local string amountText
if amount != 0 and totrade != 0 then
loop
exitwhen .Loc[ i ] != toadd
if .Rs[ i ] == totrade then
call .configTradepoint( i , amount, tradecondition, true )
return index
endif
set i = i - 1
endloop
if .orders >= MaxTradeOrders then
call DisplayTextToPlayer( GetOwningPlayer( .toOrder ), 0, 0, RED + GetTOOMANYORDERSString() )
return index
endif
set index = .orders
set .orders = .orders + 1
set .Loc[ index ] = toadd
set .Rs[ index ] = totrade
set .Amount[ index ] = amount
if tradecondition > 1 then
set tradecondition = 1
elseif tradecondition < 0.1 then
set tradecondition = 0.1
endif
set .TradeCondition[ index ] = tradecondition
if amount < 0 then
set amountText = "Sell " + I2S( -amount )
else
set amountText = "Buy " + I2S( amount )
endif
call DisplayTextToPlayer( GetOwningPlayer( .toOrder ), 0, 0, GREEN + "Added " + toadd.name + ": " + amountText + " " + totrade.name + " when " + DepotState2Text( tradecondition ) + " (" + GOLD + I2S( .orders ) + GREEN + "/" + GOLD + I2S( MaxTradeOrders ) + GREEN + ").")
return index
endif
return -1
endmethod
method configTradepoint takes integer index, integer amount, real tradecondition, boolean add returns nothing
local string amountText
if add then
set .Amount[ index ] = .Amount[ index ] + amount
elseif amount != 0 then
set .Amount[ index ] = amount
endif
if .Amount[ index ] == 0 then
call .removeTradepoint( index )
endif
if tradecondition > 1 then
set tradecondition = 1
elseif tradecondition < 0.1 then
set tradecondition = 0.1
endif
set .TradeCondition[ index ] = tradecondition
if amount < 0 then
set amountText = "Sell " + I2S( -amount )
else
set amountText = "Buy " + I2S( amount )
endif
call DisplayTextToPlayer( GetOwningPlayer( .toOrder ), 0, 0, GREEN + "Changed " + .Loc[ index ].name + ": " + amountText + " " + .Rs[ index ].name + " when " + DepotState2Text( tradecondition ) + ".")
endmethod
method removeTradepoint takes integer index returns nothing
local integer nextIndex = index + 1
local player owner = GetOwningPlayer( .toOrder )
call DisplayText( owner, RED + "Tradepoint " + I2S( index+1) + " has been removed." )
set .Amount[ index ] = 0
set .TradeCondition[ index ] = 1
set .Loc[ index ] = 0
set .Rs[ index ] = 0
loop
exitwhen nextIndex >= .orders
set .Amount[ index ] = .Amount[ nextIndex ]
set .TradeCondition[ index ] = .TradeCondition[ nextIndex ]
set .Loc[ index ] = .Loc[ nextIndex ]
set .Rs[ index ] = .Rs[ nextIndex ]
set index = nextIndex
set nextIndex = index + 1
endloop
if .currentOrder >= index then
set .currentOrder = .currentOrder - 1
endif
set .orders = .orders - 1
endmethod
method reset takes nothing returns nothing
local player owner = GetOwningPlayer( .toOrder )
call DisplayTextToPlayer( owner, 0, 0, RED + "Traderoute has been deleted." )
loop
exitwhen .orders == 0
set .Amount[ .orders ] = 0
set .TradeCondition[ .orders ] = 1
set .Loc[ .orders ] = 0
set .Rs[ .orders ] = 0
set .orders = .orders - 1
endloop
set .currentOrder = -1
set .inOrder = false
endmethod
method toScreen takes nothing returns string
local integer index = 0
local string msg
local string tmpString
local string amountString
local string red
local string green
local player owner = GetOwningPlayer( .toOrder )
local integer curOrder
local tradepoint curTp
if .inOrder then
set msg = GREEN + "Traderoute (active)\n"
set red = RED
set green = GREEN
set curOrder = .currentOrder
else
set msg = GREY + "Traderoute (inactive)\n"
set red = GREY
set green = GREY
set curOrder = .currentOrder
endif
call DisplayText( owner, msg )
loop
exitwhen index >= .orders
set curTp = .Loc[ index ]
if index == curOrder then
set tmpString = GOLD + curTp.name
else
set tmpString = red + curTp.name
endif
call DisplayText( owner, tmpString )
set msg = msg + "\n" + tmpString
loop
exitwhen curTp != .Loc[ index ]
if .Amount[ index ] > 0 then
set amountString = " Buy " + I2S( .Amount[ index ] )
else
set amountString = " Sell " + I2S( -.Amount[ index ] )
endif
set tmpString = green + " (" + GOLD + I2S( index + 1 ) + green + "):" + amountString + " " + .Rs[ index ].name + " if " + DepotState2Text( .TradeCondition[ index ] )
call DisplayText( owner, tmpString )
set msg = msg + "\n" + tmpString
set index = index + 1
endloop
endloop
return msg
endmethod
method stopOrder takes nothing returns nothing
if .inOrder then
set .inOrder = false
set .currentOrder = .currentOrder - 1
endif
endmethod
method sendToNext takes boolean check returns nothing
local player owner = GetOwningPlayer( .toOrder )
if .orders > 1 then
if check and .inOrder then
return
else
// Either check, inOrder ot both are false
set .inOrder = true
set .currentOrder = .currentOrder + 1
endif
if .currentOrder >= .orders then
set .currentOrder = 0
endif
call IssuePointOrder( .toOrder, "move", GetUnitX( .Loc[ .currentOrder ].model ), GetUnitY( .Loc[ .currentOrder ].model ) )
if .Loc[ .currentOrder ].model != .Loc[ .currentOrder - 1 ].model then
call TriggerSleepAction( 1 )
endif
loop
exitwhen not .inOrder
if IsPlayerEnemy( owner, GetOwningPlayer( .Loc[ .currentOrder ].model ) ) then
exitwhen true
elseif DistanceBetweenUnits( .toOrder, .Loc[ .currentOrder ].model ) < .TRADERANGE then
call .DoTrade_Actions()
exitwhen true
endif
call TriggerSleepAction( 1 )
endloop
if .inOrder then
call .sendToNext( false)
endif
else
set .inOrder = false
call DisplayText( owner, RED + "No traderoute defined. A traderoute must contain at least two orders." )
endif
endmethod
// amount < 0: trader sells, amount > 0: trader buys
method DoTrade_Actions takes nothing returns nothing
local tradepoint trigTp = .Loc[ .currentOrder ]
local resource curRs = .Rs[ .currentOrder ]
local exresource trigRs = trigTp.getResource( curRs )
local integer amount = .Amount[ .currentOrder ]
local integer conditionAmount = R2I( .TradeCondition[ .currentOrder ] * trigRs.maxAmount )
local integer price
local integer stock = trigRs.amount
local integer index = 0
local item slotItem
local integer slotItemId
local integer charges
local integer turnover = 0
local player trigPlayer = GetOwningPlayer( .toOrder )
local integer gold = GetPlayerState( trigPlayer, PLAYER_STATE_RESOURCE_GOLD )
local item restItem
local real x
local real y
local integer stockRoom = stock - conditionAmount
if amount > 0 and stockRoom > 0 then
set x = GetUnitX( .toOrder )
set y = GetUnitY( .toOrder )
set amount = IMinBJ( amount, stockRoom )
set turnover = amount
set price = trigTp.getCost( curRs, turnover )
if price > gold then
call DisplayText( trigPlayer, RED + "Not enough gold to buy " + I2S( amount ) + " " + trigRs.name + " from " + trigTp.name + " (" + GOLD + I2S( price ) + RED + ")." )
loop
exitwhen turnover <= 0
exitwhen price <= gold
set price = trigTp.getCost( curRs, turnover )
set turnover = turnover - 1
endloop
endif
if price <= gold and turnover > 0 then
set trigRs.amount = stock - turnover
call CreateBountyText( -price, trigTp.model, trigPlayer )
call DisplayTextToPlayer( trigPlayer, 0, 0, GREEN + "Bought " + I2S( turnover ) + " " + trigRs.name + " from " + trigTp.name + " (" + GOLD + I2S( price ) + GREEN + ")." )
call SetPlayerState( trigPlayer, PLAYER_STATE_RESOURCE_GOLD, gold - price )
set restItem = CreateItem( trigRs.itemId, x, y )
call SetItemCharges( restItem, turnover - 1 )
call UnitAddItem( .toOrder, restItem )
set restItem = CreateItem( trigRs.itemId, x, y )
call SetItemCharges( restItem, 1 )
call UnitAddItem( .toOrder, restItem )
call CallTradeTriggers( turnover, curRs, trigTp, .toOrder )
endif
elseif amount < 0 and stockRoom < 0 then
set amount = -IMaxBJ( amount, stockRoom )
loop
exitwhen amount == 0
exitwhen index > NUMSLOTS
set slotItem = UnitItemInSlot( .toOrder, index )
set slotItemId = GetItemTypeId( slotItem )
if GetItemTypeResource( slotItemId ) == curRs then
set charges = GetItemCharges( slotItem )
if charges <= amount then
set turnover = turnover - charges
set amount = amount - charges
set charges = 0
call RemoveItem( slotItem )
else
set turnover = turnover - amount
set charges = charges - amount
set amount = 0
call SetItemCharges( slotItem, charges )
endif
endif
set index = index + 1
endloop
if turnover < 0 then
set price = -trigTp.getCost( curRs, turnover )
set trigRs.amount = stock - turnover
call DisplayTextToPlayer( trigPlayer, 0, 0, GREEN + "Sold " + I2S( -turnover ) + " " + trigRs.name + " to " + trigTp.name + " (" + GOLD + I2S( price ) + GREEN + ")." )
call SetPlayerState( trigPlayer, PLAYER_STATE_RESOURCE_GOLD, gold + price )
call CreateBountyText( price, .toOrder, trigPlayer )
call CallTradeTriggers( turnover, curRs, trigTp, .toOrder )
else
call DisplayTextToPlayer( trigPlayer, 0, 0, RED + "No " + trigRs.name + " could be sold to " + trigTp.name + "." )
endif
elseif amount < 0 and stockRoom > 0 then
call DisplayTextToPlayer( trigPlayer, 0, 0, RED + "No " + trigRs.name + " could be sold to " + trigTp.name + " ( Condition not met )." )
elseif amount > 0 and stockRoom < 0 then
call DisplayTextToPlayer( trigPlayer, 0, 0, RED + "No " + trigRs.name + " could be bought from " + trigTp.name + " ( Condition not met )." )
endif
set slotItem = null
set restItem = null
endmethod
method onDestroy takes nothing returns nothing
set .toOrder = null
endmethod
endstruct
function OrderHandler_Actions takes nothing returns nothing
local unit trigUnit = GetTriggerUnit()
local traderoute trigTr = Traderoute[ trigUnit ]
if GetIssuedOrderId() != OrderId( "move" ) then
call trigTr.stopOrder()
endif
set trigUnit = null
endfunction
private function InitTR takes nothing returns nothing
call TriggerAddAction( OrderHandler, function OrderHandler_Actions )
call AddTOOMANYORDERSString( "Sir, we cannot accept additional trade orders." )
call AddTOOMANYORDERSString( "Our traderoute has reached the maximum length, sir." )
call AddTOOMANYORDERSString( "I'm sorry, sir, but our traderoute is too long." )
call Text2DepotState( "depot is empty", 0 )
call Text2DepotState( "resource is needed", .20 )
call Text2DepotState( "supply is insufficient", .35 )
call Text2DepotState( "resource is in stock", .50 )
call Text2DepotState( "resource is sufficiently in stock", .70 )
call Text2DepotState( "depot is full", .90 )
endfunction
endlibrary
//TESH.scrollpos=114
//TESH.alwaysfold=0
library TradeRouteSettings initializer InitTRS needs HelpFile, TradeRoute
//! runtextmacro PUI_PROPERTY( "private", "TradeRouteSettings_resourcecollector", "ResourceSet", "0" )
globals
constant string START_TRADE_ROUTE = "berserk"
constant string RESET_ROUTE = "bloodlust"
constant string SHOW_ROUTE = "blink"
constant string START_REMEMBER_ROUTE = "defend"
constant string STOP_REMEMBER_ROUTE = "undefend"
integer SHOW_ROUTE_ORDER
integer RESET_ROUTE_ORDER
integer START_TRADE_ROUTE_ORDER
integer START_REMEMBER_ROUTE_ORDER
integer STOP_REMEMBER_ROUTE_ORDER
public constant trigger SetTradeRoute_Chat = CreateTrigger()
public constant trigger ShowTradeRoute_Chat = CreateTrigger()
public constant trigger StartTradeRoute_Chat = CreateTrigger()
public constant trigger ResetTradeRoute_Chat = CreateTrigger()
public constant trigger ButtonHandler = CreateTrigger()
public constant trigger ConfigTradeRoute = CreateTrigger()
traderoute array PlayerTraderoute
helpfile Trade
helpfile Route
helpfile CreateRoute
helpfile Tradepoint
helpfile Resource
helpfile RouteChat
helpfile ShowRoute
helpfile RouteExecute
endglobals
struct traderoutearray
endstruct
public struct resourcecollector
delegate resourceset resources
tradepoint Tp
trigger Tradetrigger
unit collector
static method create takes tradepoint Tp, unit collector returns resourcecollector
local resourcecollector this = resourcecollector.allocate()
set .resources = resourceset.create()
set .Tp = Tp
set .Tradetrigger = CreateTrigger()
set .collector = collector
call TriggerRegisterTradeEvent( .Tradetrigger, EVENT_TRADE_ANY, this )
call TriggerAddAction( .Tradetrigger, function resourcecollector.Tradetrigger_Actions )
return this
endmethod
static method Tradetrigger_Actions takes nothing returns nothing
local resourcecollector this = GetTriggerAttachment()
local tradepoint tp = GetTriggerTradepoint()
local integer amount = GetTriggerAmount()
local resource rs = GetTriggerResource()
if this != 0 then
if tp == .Tp then
call .addAmount( rs, amount )
elseif GetTradingUnit() == .collector then
call IssueImmediateOrder( .collector, STOP_REMEMBER_ROUTE )
call IssueImmediateOrder( .collector, START_REMEMBER_ROUTE )
endif
endif
endmethod
method onDestroy takes nothing returns nothing
call TriggerClearTradeActions( .Tradetrigger )
call DestroyTrigger( .Tradetrigger )
set .collector = null
set .Tradetrigger = null
endmethod
endstruct
private function IsUnitTp takes nothing returns boolean
return TradePoint[ GetFilterUnit() ] != 0
endfunction
//Chat
function StartTradeRoute_Chat_Actions takes nothing returns nothing
local player trigPlayer = GetTriggerPlayer()
local traderoute trigTr = PlayerTraderoute[ GetPlayerId( trigPlayer ) ]
call trigTr.sendToNext( true )
endfunction
function ResetTradeRoute_Chat_Actions takes nothing returns nothing
local player trigPlayer = GetTriggerPlayer()
local traderoute trigTr = PlayerTraderoute[ GetPlayerId( trigPlayer ) ]
call trigTr.reset()
endfunction
function ShowTradeRoute_Chat_Actions takes nothing returns nothing
local player trigPlayer = GetTriggerPlayer()
local traderoute trigTr = PlayerTraderoute[ GetPlayerId( trigPlayer ) ]
call trigTr.toScreen()
endfunction
function SetTradeRoute_Chat_Actions takes nothing returns nothing
local string trigString = GetEventPlayerChatString()
local integer length = StringLength( trigString )
local string array parameter
local integer amount
local real condAmount
local resource trigRs
local integer stringPos = 0
local integer lowIndex = 0
local integer curString = 0
local integer trigPlayerId = GetPlayerId( GetTriggerPlayer() )
local tradepoint trigTp = TradePoint[ GetClosestUnitInRange( GetUnitX( Hero[ trigPlayerId ] ), GetUnitY( Hero[ trigPlayerId ] ), tradepoint.LOOKUPRANGE, true, Condition( function IsUnitTp ) ) ]
loop
exitwhen stringPos > length
if SubString( trigString, stringPos, stringPos + 1 ) == " " or stringPos == length then
if curString != -1 then
set parameter[ curString ] = SubString( trigString, lowIndex, stringPos )
endif
set curString = curString + 1
set lowIndex = stringPos + 1
endif
set stringPos = stringPos + 1
endloop
set amount = S2I( parameter[ 1 ] )
if parameter[ 0 ] == "-sell" then
set amount = -amount
endif
set trigRs = resource.S2Resource( parameter[ 2 ] )
set condAmount = S2I( parameter[ 3 ] ) / 100.0
if condAmount == 0 then
if amount > 0 then
set condAmount = 0.75 - ( amount + 0.0 ) / trigRs.maxAmount
else
set condAmount = 0.25 - ( amount + 0.0 ) / trigRs.maxAmount
endif
endif
call PlayerTraderoute[ trigPlayerId ].addTradepoint( trigTp, trigRs, amount, condAmount )
endfunction
function ConfigTradeRoute_Actions takes nothing returns nothing
local integer parameters = 0
local integer intParameters = 0
local integer lastIndex = 0
local integer curIndex = 0
local string trigString = StringCase( GetEventPlayerChatString(), false )
local integer length = StringLength( trigString )
local integer curIntParameter
local resource trigRs
local string subString
local integer array parameter
local player trigPlayer = GetTriggerPlayer()
local traderoute trigTr = PlayerTraderoute[ GetPlayerId( trigPlayer ) ]
set parameter[ 2 ] = 0
loop
exitwhen curIndex > length
exitwhen parameters >= 2
if SubString( trigString, curIndex, curIndex + 1 ) == " " or curIndex == length then
set subString = SubString( trigString, lastIndex, curIndex )
set curIntParameter = S2I( subString )
if curIntParameter != 0 or I2S( curIntParameter ) == subString then
set parameter[ intParameters ] = curIntParameter
set parameters = parameters + 1
set intParameters = intParameters + 1
elseif subString == "sell" then
set parameter[ 2 ] = -1
elseif subString == "buy" then
set parameter[ 2 ] = 1
endif
set lastIndex = curIndex + 1
endif
set curIndex = curIndex + 1
endloop
set parameter[ 0 ] = parameter[ 0 ] - 1
if parameters >= 2 and parameter[ 0 ] <= trigTr.orders then
if parameter[ 2 ] == 0 then
set parameter[ 2 ] = ISignBJ( trigTr.Amount[ parameter[ 0 ] ] )
endif
set parameter[ 1 ] = parameter[ 1 ] * parameter[ 2 ]
set trigRs = trigTr.Rs[ parameter[ 0 ] ]
if parameter[ 1 ] > 0 then
set parameter[ 3 ] = 75 - ( parameter[ 1 ] * 100 ) / trigRs.maxAmount
else
set parameter[ 3 ] = 25 + ( -parameter[ 1 ] * 100 ) / trigRs.maxAmount
endif
call trigTr.configTradepoint( parameter[ 0 ], parameter[ 1 ], parameter[ 3 ]/100.0 , false )
else
call DisplayText( trigPlayer, RED + "Not enough arguments for configuration." )
endif
endfunction
//Button
function StartTradeRoute_Button takes player trigPlayer returns nothing
local traderoute trigTr = PlayerTraderoute[ GetPlayerId( trigPlayer ) ]
call IssueImmediateOrder( trigTr.toOrder, STOP_REMEMBER_ROUTE )
call trigTr.sendToNext( true )
endfunction
function ResetTradeRoute_Button takes player trigPlayer returns nothing
local traderoute trigTr = PlayerTraderoute[ GetPlayerId( trigPlayer ) ]
call IssueImmediateOrder( trigTr.toOrder, STOP_REMEMBER_ROUTE )
call trigTr.reset()
endfunction
function ShowTradeRoute_Button takes player trigPlayer returns nothing
local traderoute trigTr = PlayerTraderoute[ GetPlayerId( trigPlayer ) ]
if trigTr.inOrder then
call trigTr.toScreen()
call trigTr.sendToNext( true )
else
call trigTr.toScreen()
endif
endfunction
function SetTradeRoute_Button_Save takes player trigPlayer returns nothing
local integer trigPlayerId = GetPlayerId( trigPlayer )
local integer amount
local real condAmount
local exresource curRs
local traderoute trigTr = PlayerTraderoute[ trigPlayerId ]
local unit trigUnit = trigTr.toOrder
local resourcecollector rsSet = ResourceSet[ trigUnit ]
local tradepoint trigTp = rsSet.Tp
if rsSet != 0 then
set curRs = rsSet.first
loop
exitwhen curRs == 0
set amount = curRs.amount
if amount > 0 then
set condAmount = 0.75 - ( amount + 0.0 )/ curRs.maxAmount
else
set condAmount = 0.25 - ( amount + 0.0 )/ curRs.maxAmount
endif
call trigTr.addTradepoint( trigTp, curRs.kind, amount, condAmount )
set curRs = curRs.next
endloop
call rsSet.destroy()
endif
set ResourceSet[ trigUnit ] = 0
endfunction
function SetTradeRoute_Button_Record takes player trigPlayer returns nothing
local integer trigPlayerId = GetPlayerId( trigPlayer )
local traderoute trigTr = PlayerTraderoute[ trigPlayerId ]
local unit trigUnit = trigTr.toOrder
local unit tpUnit = GetClosestUnitInRange( GetUnitX( trigUnit ), GetUnitY( trigUnit ), traderoute.TRADERANGE, true, Condition( function IsUnitTp ) )
local tradepoint trigTp
local resourcecollector rsSet
if tpUnit != null then
set trigTp = TradePoint[ tpUnit ]
set rsSet = resourcecollector.create( trigTp, trigUnit )
set ResourceSet[ trigUnit ] = rsSet
loop
exitwhen DistanceBetweenUnits( trigUnit, tpUnit ) > traderoute.TRADERANGE + 200
call TriggerSleepAction( 1 )
endloop
call IssueImmediateOrder( trigUnit, STOP_REMEMBER_ROUTE )
else
call TriggerSleepAction( 1 )
call IssueImmediateOrder( trigUnit, STOP_REMEMBER_ROUTE )
endif
endfunction
function ButtonHandler_Actions takes nothing returns nothing
local unit trigUnit = GetTriggerUnit()
local player trigPlayer = GetOwningPlayer( trigUnit )
local integer orderId = GetIssuedOrderId()
if orderId == START_TRADE_ROUTE_ORDER then
call StartTradeRoute_Button( trigPlayer )
elseif orderId == START_REMEMBER_ROUTE_ORDER then
call SetTradeRoute_Button_Record( trigPlayer )
elseif orderId == STOP_REMEMBER_ROUTE_ORDER then
call SetTradeRoute_Button_Save( trigPlayer )
elseif orderId == SHOW_ROUTE_ORDER then
call ShowTradeRoute_Button( trigPlayer )
elseif orderId == RESET_ROUTE_ORDER then
call ResetTradeRoute_Button( trigPlayer )
endif
endfunction
private function InitTRS takes nothing returns nothing
local integer index = 0
set SHOW_ROUTE_ORDER = OrderId( SHOW_ROUTE )
set RESET_ROUTE_ORDER = OrderId( RESET_ROUTE )
set START_TRADE_ROUTE_ORDER = OrderId( START_TRADE_ROUTE )
set START_REMEMBER_ROUTE_ORDER = OrderId( START_REMEMBER_ROUTE )
set STOP_REMEMBER_ROUTE_ORDER = OrderId( STOP_REMEMBER_ROUTE )
call TriggerRegisterAnyPlayerChatEvent( SetTradeRoute_Chat, "-buy", false )
call TriggerRegisterAnyPlayerChatEvent( SetTradeRoute_Chat, "-sell", false )
call TriggerRegisterAnyPlayerChatEvent( SetTradeRoute_Chat, "-trade", false )
call TriggerRegisterAnyPlayerChatEvent( StartTradeRoute_Chat, "-traderoute", true )
call TriggerRegisterAnyPlayerChatEvent( StartTradeRoute_Chat, "-trade route", true )
call TriggerRegisterAnyPlayerChatEvent( StartTradeRoute_Chat, "-start route", true )
call TriggerRegisterAnyPlayerChatEvent( StartTradeRoute_Chat, "-start trade", false)
call TriggerRegisterAnyPlayerChatEvent( ShowTradeRoute_Chat, "-show route", false )
call TriggerRegisterAnyPlayerChatEvent( ShowTradeRoute_Chat, "-show trade", false )
call TriggerRegisterAnyPlayerChatEvent( ShowTradeRoute_Chat, "-view route", false )
call TriggerRegisterAnyPlayerChatEvent( ShowTradeRoute_Chat, "-view trade", false )
call TriggerRegisterAnyPlayerChatEvent( ConfigTradeRoute, "-config", false )
call TriggerRegisterAnyPlayerChatEvent( ConfigTradeRoute, "-set", false )
call TriggerRegisterAnyPlayerChatEvent( ResetTradeRoute_Chat, "-reset trade", true )
call TriggerRegisterAnyPlayerChatEvent( ResetTradeRoute_Chat, "-reset route", true )
call TriggerRegisterAnyUnitEventBJ( ButtonHandler, EVENT_PLAYER_UNIT_ISSUED_ORDER )
call TriggerAddAction( ButtonHandler, function ButtonHandler_Actions )
call TriggerAddAction( SetTradeRoute_Chat, function SetTradeRoute_Chat_Actions )
call TriggerAddAction( StartTradeRoute_Chat, function StartTradeRoute_Chat_Actions )
call TriggerAddAction( ShowTradeRoute_Chat, function ShowTradeRoute_Chat_Actions )
call TriggerAddAction( ConfigTradeRoute, function ConfigTradeRoute_Actions )
call TriggerAddAction( ResetTradeRoute_Chat, function ResetTradeRoute_Chat_Actions )
set Trade = helpfile.create( "TRADING", "Trading is the action to sell or buy trade-resources. The price is computed via supply and demand.", 0 )
set Route = helpfile.create( "TRADEROUTE", "A route is a list of multiple trade commands, that will be executed in a given order.", Trade )
set Resource = helpfile.create( "RESOURCE", "Trade-resources are stackable items that can be bought or sold in tradepoints.
This can work either via the Warcraft 3 interface ( by selling / buying the item ), or via Traderoutes.
If you try to sell them to a non-tradepoint, nothing will happen.
See also: TRADEROUTE, TRADEPOINT", Trade )
set Tradepoint = helpfile.create( "TRADEPOINT", "Tradepoints are shops that offer resources and/or buy resources.
The price is calculated by comparing the Tradepoint's production to the Tradepoint's depot status.
Tradepoints can be conquered, when there are no enemy units around.", Trade )
set CreateRoute = helpfile.create( "ROUTE CREATION", "Traderoutes can be created via buttons or via chat commands.
When clicking on the \"Record\" button, the Traderoute will remember your trade-actions and save it to the route.
You can alternatively use \"-sell X RESOURCE\" and \"-buy X RESOURCE\" in the chat line.
See also: CHAT TRADEROUTE, TRADING", Route )
set ShowRoute = helpfile.create( "ROUTE VIEWING", "From times to times, you might want to lookup what you allready got in your traderoute.
To do this, either enter \"-view route\" in the chat, or use the button \"Show Traderoute\".", Route )
set RouteChat = helpfile.create( "CHAT TRADEROUTE", "route/trade/trade route can always be exchanged.
-show route/-view route: Shows your current trade route. The ID is allways the yellow number to the left of the command.
-buy X RESOURCE (Y)/-sell X RESOURCE (Y): Will buy/sell X of RESOURCE if the depot is to Y% full. When omitted, Y will be autocomputed.
-reset route: Deletes the whole traderoute.
-set ID (COMMAND) X (Y)/-config ID (COMMAND) X (Y): Sets the ID's amount to X.
COMMAND can be either buy or sell. When omitted, COMMAND will be set to the current command, and Y will be automatically set.", Route )
set RouteExecute = helpfile.create( "START ROUTE", "When a Traderoute is started, your trader will start to go from tradepoint to tradepoint, trying to do all the actions in the traderoute.
To start the traderoute, enter -start route in the chat line, or click on the corresponding tradebutton.", Route )
endfunction
endlibrary
//TESH.scrollpos=49
//TESH.alwaysfold=0
//! runtextmacro Attach( "ResourceEvent", "trigger", "integer", "-1" )
//! runtextmacro Attach( "ResourceAttachment", "trigger", "integer", "0" )
//! runtextmacro Attach( "Pings", "exresource", "integer", "0" )
library ResourceHandler initializer INIT needs TradepointUpgradeSystem, TriggerGroups
globals
private timer Ticker = CreateTimer()
private real SLEEP = 1
private triggergroup ResourceTriggers
constant integer EVENT_RESOURCE_OVERFLOW = 2
constant integer EVENT_RESOURCE_EMPTY = 1
constant integer EVENT_RESOURCE_ANY = 0
private integer CurAttachment
private integer CurEvent
private resource CurResource
private town CurTown
endglobals
function GetHandlerEvent takes nothing returns exresource
return CurEvent
endfunction
function GetHandlerResource takes nothing returns exresource
return CurResource
endfunction
function GetHandlerTown takes nothing returns exresource
return CurTown
endfunction
function GetHandlerAttachment takes nothing returns integer
return CurAttachment
endfunction
function TriggerRegisterResourceHandlerEvent takes trigger t, integer eventtype, integer attachment returns nothing
call TriggerGroupAdd( ResourceTriggers, t )
set ResourceEvent[ t ] = eventtype
set ResourceAttachment[ t ] = attachment
set t = null
endfunction
private function Execute_Callback takes nothing returns nothing
local trigger enumTrig = GetEnumTrigger()
if ResourceEvent[ enumTrig ] == EVENT_RESOURCE_ANY or ResourceEvent[ enumTrig ] == CurEvent then
if TriggerEvaluate( enumTrig ) then
call TriggerExecute( enumTrig )
set CurAttachment = ResourceAttachment[ enumTrig ]
endif
endif
set enumTrig = null
endfunction
private function Execute takes town trigTown, exresource trigRs, integer eventtype returns nothing
set CurTown = trigTown
set CurEvent = eventtype
set CurResource = trigRs
call ForTriggerGroup( ResourceTriggers, function Execute_Callback )
endfunction
function CheckResources takes town curTown returns nothing
local exresource curRs = curTown.deposits.first
local real state
local real x = GetUnitX( curTown.model )
local real y = GetUnitY( curTown.model )
loop
exitwhen curRs == 0
set state = ( curRs.amount * 100.0 ) / curRs.maxAmount
if Pings[ curRs ] <= 0 then
if state < 15 then
if IsUnitAlly( curTown.model, LOCAL_PLAYER ) then
call DisplayText( LOCAL_PLAYER, RED + curTown.name + " is running out of " + curRs.name + "!" )
call PingMinimapEx( x, y, 2 * SLEEP, 255, 51, 51, false )
endif
set CurEvent = EVENT_RESOURCE_EMPTY
set Pings[ curRs ] = 15
call Execute( curTown, curRs, CurEvent )
elseif state > 85 then
if IsUnitAlly( curTown.model, LOCAL_PLAYER ) then
call DisplayText( LOCAL_PLAYER, RED + curTown.name + "'s " + curRs.name + " deposits are owerflowing!" )
call PingMinimapEx( x, y, 2 * SLEEP, 51, 255, 51, false )
endif
set Pings[ curRs ] = 15
set CurEvent = EVENT_RESOURCE_OVERFLOW
call Execute( curTown, curRs, CurEvent )
endif
else
set Pings[ curRs ] = Pings[ curRs ] - 1
endif
set curRs = curRs.next
endloop
endfunction
private function CheckTowns takes nothing returns nothing
local integer i = tradepoint.count
loop
exitwhen i < 0
call CheckResources( GetTradepointTown( TradeSystem_Tradepoint[ i ] ) )
set i = i - 1
endloop
endfunction
private function INIT takes nothing returns nothing
//call TimerStart( Ticker, SLEEP, true, function CheckTowns )
set ResourceTriggers = CreateTriggerGroup()
endfunction
endlibrary
//TESH.scrollpos=56
//TESH.alwaysfold=1
//! runtextmacro Attach( "AttachedTrader", "timer", "aitrader", "0" )
library AITraders initializer INIT needs Utilities, CargoSystem, TradeSystem
private function CheckTradepointClose takes nothing returns nothing
local timer expTimer = GetExpiredTimer()
local aitrader trader = AttachedTrader[ expTimer ]
local unit tpUnit = GetClosestUnitInRange( GetUnitX( trader.trader ), GetUnitY( trader.trader ), tradepoint.LOOKUPRANGE, true, Condition( function IsFilterUnitTradePoint ) )
local tradepoint tp
if tpUnit != null then
set tp = TradePoint[ tpUnit ]
if IsUnitAlly( tpUnit, trader.owner ) then
call trader.doTrade( tp )
if tp == trader.target then
call trader.nextAction()
endif
elseif tp == trader.target then
call trader.nextAction()
endif
endif
set expTimer = null
endfunction
struct aitrader
unit trader
integer nextTownId = 0
tradepoint target
player owner
timer ticker
method issueToNext takes nothing returns nothing
call IssuePointOrder( .trader, "move", .target.x, .target.y )
call TimerStart( .ticker, 0.75, true, function CheckTradepointClose )
endmethod
method nextAction takes nothing returns nothing
set .nextTownId = .nextTownId + 1
if .nextTownId >= tradepoint.count then
set .nextTownId = 0
endif
set .target = tradepoint[ .nextTownId ]
if IsUnitAlly( .target.model, .owner ) then
call .issueToNext()
else
call .nextAction()
endif
endmethod
method doTrade takes tradepoint tradetarget returns nothing
local exresource curRs
local resource array invRs
local integer array invItemPos
local item slotItem
local item trigItem
local resource slotRs
local integer items = 0
local integer i = 0
local real x = GetUnitX( .trader )
local real y = GetUnitY( .trader )
local real state
local integer oldCargo
set TradeDB.InMSG = I2S( this ) //
loop
exitwhen i > MAX_INV_SLOT
set slotItem = UnitItemInSlot( .trader, i )
set slotRs = GetItemResource( slotItem )
if slotRs != 0 then
set invItemPos[ items ] = i
set invRs[ items ] = slotRs
set items = items + 1
endif
set i = i + 1
endloop
set curRs = tradetarget.first
loop
exitwhen curRs == 0
set state = I2R( curRs.amount ) / curRs.maxAmount
if state < 0.35 then
set i = 0
loop
exitwhen i >= items
if invRs[ i ] == curRs.kind then
call tradetarget.sellTo( .trader, UnitItemInSlot( .trader, invItemPos[ i ] ) )
set invRs [ i ] = invRs [ items - 1 ]
set invItemPos[ i ] = invItemPos[ items - 1 ]
set items = items - 1
exitwhen true
endif
set i = i + 1
endloop
elseif state > 0.65 then
set oldCargo = GetUnitCargo ( .trader )
set trigItem = CreateItem ( curRs.itemId, x, y )
call SetItemCharges ( trigItem, R2I( 0.9 * ( state - 0.5 ) * curRs.maxAmount ) )
call TradeDB.Debug ( I2S( GetItemCharges( trigItem ) ) )
call UnitAddItem ( .trader, trigItem )
call SetUnitCargo ( .trader, oldCargo )
call tradetarget.buyFrom( .trader, trigItem )
endif
set curRs = curRs.next
endloop
call TradeDB.Out( I2S( this ) ) //
set slotItem = null
set trigItem = null
endmethod
static method create takes unit trader, boolean levels returns aitrader
local aitrader this = .allocate()
if IsUnitType( trader, UNIT_TYPE_HERO ) then
set .owner = GetOwningPlayer( trader )
set .trader = trader
if GetPlayerController( .owner ) == MAP_CONTROL_USER then
call TradeDB.Debug( "Tried to assign AI Trader to non-AI Player!" ) //
call .destroy()
return 0
endif
set .ticker = CreateTimer()
set AttachedTrader[ .ticker ] = this
call SuspendHeroXP( trader, not levels )
call .nextAction()
else
call TradeDB.Debug( "Non-hero Trader assigned!" ) //
call .destroy()
return 0
endif
return this
endmethod
endstruct
private function INIT takes nothing returns nothing
endfunction
endlibrary
//TESH.scrollpos=222
//TESH.alwaysfold=0
// This is the static tradesystem.
// Tradepoints should be made invul in order to prevent bad things.
//! runtextmacro Attach( "ItemTypeResourceId", "integer", "integer", "-1" )
//! runtextmacro Attach( "Tradepoint", "unit", "tradepoint", "0" )
library TradeSystem initializer INIT needs Utilities, GetPlayerFeedback
globals
constant integer MAX_RESOURCE_ID = 5
constant boolean SHOW_TRADE_MESSAGES_DEFAULT = true
constant real MULTIPLIER_DEFAULT = 0.8
constant trigger TradeTrigger_Pawn = CreateTrigger()
constant trigger TradeTrigger_Sell = CreateTrigger()
boolean array ShowTradeMessages
public real array Multiplier
private integer array TMP_RES
private item array TMP_ITEM
private integer array TMP_GOLD
private integer array TMP_AMOUNT
private unit array TMP_TRIGUNIT
private integer array TMP_STARTAMOUNT
endglobals
private function GetCostIndex takes integer teamId, integer resid returns integer
return MAX_RESOURCE_ID * teamId + resid
endfunction
private function Finish_SellTo takes nothing returns nothing
local player trigPlayer = GetTriggerPlayer()
local integer trigId = GetPlayerId( trigPlayer )
local unit seller = TMP_TRIGUNIT[ trigId ]
local integer stack = TMP_AMOUNT [ trigId ]
local integer reward = TMP_GOLD[ trigId ]
local resource res = TMP_RES [ trigId ]
local integer teamId = Team[ trigId ].id
local item tosell
if GetPlayerFeedback( trigPlayer ) then
if ShowTradeMessages[ trigId ] then
call DisplayText( trigPlayer, GREEN + "Sold " + I2S( stack ) + " " + res.name + " (" + GOLD + I2S( reward ) + GREEN + ")" )
endif
call CreateBountyText( reward, seller, trigPlayer )
call AddHeroXP( seller, reward / 4, true )
call AddGold ( reward, trigId, TRANSFERTYPE_PLAYER_PLAYER, "Trading Income" )
// //! runtextmacro ChangePlayerState( "trigPlayer", "RESOURCE_GOLD", "reward" )
else
set tosell = UnitAddItemById( seller, res.itemId )
call SetItemCharges( tosell, stack )
set tosell = null
if ShowTradeMessages[ trigId ] then
call DisplayText( trigPlayer, RED + "Cancelled selling process." )
endif
endif
set seller = null
endfunction
private function Finish_BuyFrom takes nothing returns nothing
local player trigPlayer = GetTriggerPlayer()
local integer trigId = GetPlayerId( trigPlayer )
local integer start = TMP_STARTAMOUNT[ trigId ]
local unit buyer = TMP_TRIGUNIT[ trigId ]
local integer stack = TMP_AMOUNT [ trigId ]
local integer cost = TMP_GOLD[ trigId ]
local resource res = TMP_RES [ trigId ]
local item tobuy = TMP_ITEM[ trigId ]
local integer teamId = Team[ trigId ].id
if GetPlayerFeedback( trigPlayer ) then
if ShowTradeMessages[ trigId ] then
call DisplayText( trigPlayer, GREEN + "Bought " + I2S( stack ) + "/" + I2S( start ) + " " + res.name + " (" + GOLD + I2S( cost ) + GREEN + ")" )
endif
call CreateBountyText( -cost, buyer, trigPlayer )
call SetHeroXP( buyer, GetHeroXP( buyer ) - cost / 5, true )
call AddGold( -cost, trigId, TRANSFERTYPE_PLAYER_PLAYER, "Trading Expenses" )
// //! runtextmacro ChangePlayerState( "trigPlayer", "RESOURCE_GOLD", "-cost" )
else
call RemoveItem( tobuy )
if ShowTradeMessages[ trigId ] then
call DisplayText( trigPlayer, RED + "Cancelled buying process." )
endif
endif
set buyer = null
set tobuy = null
endfunction
struct resource
string name
integer id
integer itemId
integer array minCost[MAX_RESOURCE_ID]
integer array maxCost[MAX_RESOURCE_ID]
static integer count = 0
static method create takes string name, integer itemid returns resource
local resource this = .allocate()
set .id = .count
set .count = .count + 1
set .itemId = itemid
set .name = name
set tradepoint.res[ .id ] = this
call SetItemTypeResourceId( itemid, .id )
return this
endmethod
endstruct
struct tradepoint
player owner
string name
integer array cost [ 200 ]
unit repr
static resource array res [ MAX_RESOURCE_ID ]
static integer count = 0
static tradepoint array instance [ 40 ]
static method create takes string name, player owner, integer unitid, real x, real y returns tradepoint
local tradepoint this = .allocate()
local resource curRes
local integer id = 0
set .repr = CreateUnit( owner, unitid, x, y, 270 )
set .instance[ .count ] = this
set .count = .count + 1
set .name = name
set .owner = owner
set Tradepoint[ .repr ] = this
return this
endmethod
method getCost takes integer id, integer teamId returns integer
return .cost[GetCostIndex( teamId, id )]
endmethod
method setCost takes integer id, integer teamId, integer cost returns nothing
local integer i = 0
local integer tmp
local integer index = GetCostIndex( teamId, id )
local integer old = .cost[index]
local integer min = .res[id].minCost[teamId]
local integer max = .res[id].maxCost[teamId]
local integer cur
set .cost[index] = cost
if min > cost or min == 0 then
set .res[id].minCost[teamId] = cost
elseif min == old then
loop
exitwhen i > .count
set cur = .instance[i].cost[index]
if cur != 0 and cur < tmp then
set tmp = cur
endif
set i = i + 1
endloop
set .res[id].minCost[teamId] = tmp
endif
if max < cost then
set .res[id].maxCost[teamId] = cost
elseif max == old then
loop
exitwhen i > .count
set cur = .instance[i].cost[index]
if cur > tmp then
set tmp = cur
endif
set i = i + 1
endloop
set .res[id].maxCost[teamId] = tmp
endif
endmethod
method sellTo takes unit seller, item tosell returns nothing
local player trigPlayer = GetOwningPlayer( seller )
local integer stack = GetItemCharges( tosell )
local integer id = GetItemTypeResourceId( GetItemTypeId( tosell ) )
local integer reward
local integer trigId = GetPlayerId( trigPlayer )
local integer teamId = Team[ trigId ].id
local real goldPerItem
if id != -1 then
if stack == 0 then
set stack = 1
endif
set goldPerItem = ( Multiplier[ trigId ] * .getCost( id, teamId ) )
set reward = R2I( stack * ( goldPerItem - .res[id].minCost[teamId] ) +0.5)
call RemoveItem( tosell )
if reward < 0 then
set reward = 0
endif
if ShowTradeMessages[ trigId ] then
set TMP_GOLD[ trigId ] = reward
set TMP_RES [ trigId ] = .res[id]
set TMP_AMOUNT [ trigId ] = stack
set TMP_TRIGUNIT[ trigId ] = seller
call AskPlayerFeedback( trigPlayer, GREEN + "Sell for " + GOLD + I2S( reward ) + GREEN + " gold?" , function Finish_SellTo )
else
call CreateBountyText( reward, seller, trigPlayer )
call AddGold( reward, trigId, TRANSFERTYPE_PLAYER_PLAYER, "Trading Income" )
// //! runtextmacro ChangePlayerState( "trigPlayer", "RESOURCE_GOLD", "reward" )
endif
endif
set seller = null
set tosell = null
endmethod
method buyFrom takes unit buyer, item tobuy returns nothing
local player trigPlayer = GetOwningPlayer( buyer )
local integer startCost
local integer cost
local integer curGold = GetPlayerState( trigPlayer, PLAYER_STATE_RESOURCE_GOLD )
local integer trigId = GetPlayerId( trigPlayer )
local integer startStack = GetItemCharges( tobuy )
local integer stack
local integer id = GetItemTypeResourceId( GetItemTypeId( tobuy ) )
local integer teamId = Team[ trigId ].id
local integer weight = GetItemTypeWeight( GetItemTypeId( tobuy ) )
local integer costPerItem = .getCost( id, teamId ) - .res[id].minCost[teamId]
local integer freeCargo = GetUnitTypeMaxCargo( GetUnitTypeId( buyer ) ) - GetUnitCargo( buyer )
if startStack == 0 then
set startStack = 1
else
set startStack = freeCargo / weight
endif
set stack = startStack
set startCost = costPerItem * stack
set cost = startCost
loop
exitwhen stack == 0 or cost <= curGold
set stack = stack - 1
set cost = costPerItem * stack
endloop
if stack > 0 then
call SetItemCharges( tobuy, stack )
if cost == 0 then
if ShowTradeMessages[ trigId ] then
call DisplayText( trigPlayer, GREEN + "Bought " + I2S( stack ) + "/" + I2S( startStack ) + " " + .res[ id ].name + " (" + GOLD + "FREE" + GREEN + ")" )
endif
else
set TMP_ITEM[ trigId ] = tobuy
set TMP_GOLD[ trigId ] = cost
set TMP_RES [ trigId ] = .res[id]
set TMP_AMOUNT [ trigId ] = stack
set TMP_TRIGUNIT[ trigId ] = buyer
set TMP_STARTAMOUNT[ trigId ] = startStack
call AskPlayerFeedback( trigPlayer, GREEN + "Buy for " + GOLD + I2S( cost ) + GREEN + " gold?" , function Finish_BuyFrom )
endif
else
if ShowTradeMessages[ trigId ] then
if startStack == 0 then
call DisplayText( trigPlayer, RED + "Not enough free cargo to buy " + .res[ id ].name + " (" + GOLD + I2S( weight ) + RED + ")" )
else
call DisplayText( trigPlayer, RED + "Not enough gold to buy " + I2S( startStack ) + " " + .res[ id ].name + " (" + GOLD + I2S( startCost ) + RED + ")" )
endif
endif
call RemoveItem( tobuy )
endif
set buyer = null
set tobuy = null
endmethod
static method onInit takes nothing returns nothing
local integer id = 0
loop
exitwhen id > MAX_RESOURCE_ID
set .res[ id ] = 0
set id = id + 1
endloop
endmethod
endstruct
private function Pawn_Actions takes nothing returns nothing
local unit buyUnit = GetBuyingUnit()
local unit trigUnit = GetSellingUnit()
local item trigItem = GetSoldItem()
local integer trigItemId = GetItemTypeId( trigItem )
local integer stack = GetItemCharges( trigItem )
local tradepoint trigTp = Tradepoint[ buyUnit ]
if trigTp != 0 then
call trigTp.sellTo( trigUnit, trigItem )
else
call RemoveItem( trigItem )
set trigItem = UnitAddItemById( trigUnit, trigItemId )
call SetItemCharges( trigItem, stack )
endif
set buyUnit = null
set trigUnit = null
set trigItem = null
endfunction
private function Sell_Actions takes nothing returns nothing
local unit sellUnit = GetSellingUnit()
local unit trigUnit = GetBuyingUnit()
local item trigItem = GetSoldItem()
local tradepoint trigTp = Tradepoint[ sellUnit ]
if trigTp != 0 then
call trigTp.buyFrom( trigUnit, trigItem )
endif
set sellUnit = null
set trigUnit = null
set trigItem = null
endfunction
private function INIT takes nothing returns nothing
local integer id = 0
loop
exitwhen id > MAX_USER_SLOT
set ShowTradeMessages[ id ] = SHOW_TRADE_MESSAGES_DEFAULT
set Multiplier [ id ] = MULTIPLIER_DEFAULT
set id = id + 1
endloop
call TriggerAddAction( TradeTrigger_Pawn, function Pawn_Actions )
call TriggerAddAction( TradeTrigger_Sell, function Sell_Actions )
call TriggerRegisterAnyUnitEventBJ( TradeTrigger_Pawn, EVENT_PLAYER_UNIT_PAWN_ITEM )
call TriggerRegisterAnyUnitEventBJ( TradeTrigger_Sell, EVENT_PLAYER_UNIT_SELL_ITEM )
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope Inspect initializer INIT
globals
private constant integer SKILL_ID = 'A00A'
private constant trigger INSPECTOR = CreateTrigger()
private constant real LOOK_UP_RANGE = 650
private boolexpr IsFilterUnitTradepoint
endglobals
function GetTradepointText takes tradepoint tp, player viewer returns string
local string result
local string costColor
local string rewardColor
local resource curRes
local integer i = 0
local integer cost
local integer gold
local integer minCost
local integer maxCost
local integer diff
local integer id = GetPlayerId( viewer )
local integer teamId = Team[id].id
local integer reward
local real costVal
if IsPlayerAlly( tp.owner, viewer ) then
set result = GREEN + tp.name + " ( " + LIGHTGREY + GetPlayerName( tp.owner ) + GREEN + " )"
loop
set curRes = tp.res[ i ]
exitwhen curRes == 0
set cost = tp.getCost( curRes.id, teamId )
set gold = R2I( cost * TradeSystem_Multiplier[ id ] )
set minCost = curRes.minCost[teamId]
set maxCost = curRes.maxCost[teamId]
set diff = maxCost - minCost
set reward = gold - minCost
if diff == 0 then
set costVal = 0.5
else
set costVal = ( maxCost - cost + .0 )/ diff
endif
set costColor = State2Color( costVal )
if reward >= 0 then
set rewardColor = State2Color( 1 - costVal )
else
set reward = 0
set rewardColor = State2Color( 0 )
endif
set result = result + "\n " + GREEN + curRes.name + ": " + costColor + I2S( cost - minCost ) + GREEN + " / " + rewardColor + I2S( reward )
set i = i + 1
endloop
else
set result = RED + tp.name + " ( " + GREY + GetPlayerName( tp.owner ) + RED + " )"
endif
set viewer = null
return result
endfunction
private function IsFilterUnitTradepoint_Func takes nothing returns boolean
return Tradepoint[ GetFilterUnit() ] != 0
endfunction
private function Inspector_Condition takes nothing returns boolean
return GetSpellAbilityId() == SKILL_ID
endfunction
private function Inspector_Action takes nothing returns nothing
local unit trigUnit = GetTriggerUnit()
local unit curUnit
local real trigX = GetUnitX( trigUnit )
local real trigY = GetUnitY( trigUnit )
local player trigPlayer = GetOwningPlayer( trigUnit )
local texttag display
call GroupClear( GLOBAL_GROUP )
call GroupEnumUnitsInRange( GLOBAL_GROUP, trigX, trigY, LOOK_UP_RANGE, IsFilterUnitTradepoint )
loop
set curUnit = FirstOfGroup( GLOBAL_GROUP )
exitwhen curUnit == null
if IsUnitVisible( curUnit, trigPlayer ) then
set display = CreateTextTag()
call SetTextTagPos ( display, GetUnitX( curUnit ), GetUnitY( curUnit ), 0 )
call SetTextTagText ( display, GetTradepointText( Tradepoint[ curUnit ], trigPlayer ), BountyTextSize )
call SetTextTagPermanent( display, false )
call SetTextTagFadepoint( display, 10.0 )
call SetTextTagLifespan ( display, 15.0 )
endif
call GroupRemoveUnit( GLOBAL_GROUP, curUnit )
endloop
endfunction
private function INIT takes nothing returns nothing
call TriggerRegisterAnyUnitEventBJ( INSPECTOR, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddAction ( INSPECTOR, function Inspector_Action )
call TriggerAddCondition( INSPECTOR, Condition( function Inspector_Condition ) )
set IsFilterUnitTradepoint = Filter( function IsFilterUnitTradepoint_Func )
endfunction
endscope
//TESH.scrollpos=70
//TESH.alwaysfold=0
///// VER 03
library ShipChange initializer InitShipChange needs AntarcticaMapInit, Utilities, RevivalSystem
globals
private constant trigger ShipChanger = CreateTrigger()
endglobals
private function ShipChanger_Cond takes nothing returns boolean
return IsUnitType( GetSoldUnit(), UNIT_TYPE_HERO ) == true
endfunction
private function ShipChanger_Actions takes nothing returns nothing
local unit newHero = GetSoldUnit ( )
local player trigPlayer = GetOwningPlayer( newHero )
local integer trigPlayerId = GetPlayerId ( trigPlayer )
local unit oldHero = Hero [ trigPlayerId ]
local real x = GetUnitX ( oldHero )
local real y = GetUnitY ( oldHero )
local real facing = GetUnitFacing ( oldHero )
local integer oldHeroId = GetUnitTypeId( oldHero )
local integer newHeroId = GetUnitTypeId( newHero )
local string msg
local player localPlayer = LOCAL_PLAYER
local integer returnValue = R2I( 0.8 * GetUnitPointValue( oldHero ) )
local integer cost = GetUnitPointValue( newHero )
local boolean inTeam1 = IsPlayerAlly( trigPlayer , Players[ 0 ] )
local integer experience = GetHeroXP( oldHero )
local integer itemIndex = 0
local integer oldLevel = GetUnitTypeShipLevel( oldHeroId )
local integer newLevel = GetUnitTypeShipLevel( newHeroId )
local integer expCost = 1000 * ( newLevel * newLevel - oldLevel * oldLevel )
local boolean oldIsTrader = GetUnitTypeShipId( oldHeroId ) == SHIP_TYPE_TRADER
local boolean newIsTrader = GetUnitTypeShipId( newHeroId ) == SHIP_TYPE_TRADER
// 0 -> 1 : 1000
// 1 -> 2 : 3000
// 2 -> 3 : 5000
if PlayerUpgrades[ trigPlayerId ] > 0 then
call DisplayText( trigPlayer, RED + "You cannot change your ship while you are upgrading!" )
//! runtextmacro ChangePlayerState( "trigPlayer", "RESOURCE_GOLD", "cost" )
call RemoveUnit( newHero )
elseif GetUnitState( oldHero, UNIT_STATE_LIFE ) <= 0 then
call DisplayText( trigPlayer, RED + "You are currently dead. Ships cannot be changed while dead!" )
//! runtextmacro ChangePlayerState( "trigPlayer", "RESOURCE_GOLD", "cost" )
call RemoveUnit( newHero )
elseif not ShipRequirements[ newHeroId ].check( trigPlayer ) then
call DisplayText( trigPlayer, RED + "You don't meet the requirements!" )
call DisplayText( trigPlayer, RED + ShipRequirements[ newHeroId ].to_s( trigPlayerId ) )
//! runtextmacro ChangePlayerState( "trigPlayer", "RESOURCE_GOLD", "cost" )
call RemoveUnit( newHero )
elseif experience < expCost then
call DisplayText( trigPlayer, RED + "You need " + I2S( expCost ) + " experience!" )
//! runtextmacro ChangePlayerState( "trigPlayer", "RESOURCE_GOLD", "cost" )
call RemoveUnit( newHero )
elseif DistanceBetweenUnits( oldHero, newHero ) > 800 then
call DisplayText( trigPlayer, RED + "Too far away for changing your ship!" )
//! runtextmacro ChangePlayerState( "trigPlayer", "RESOURCE_GOLD", "cost" )
call RemoveUnit( newHero )
else
set msg = PlayerName[ trigPlayerId ] + LIGHTGREY + " has changed his/her ship to a " + GOLD + GetUnitName( newHero ) + LIGHTGREY + "." + EndTag
loop
exitwhen itemIndex > 5
call UnitAddItem( newHero , UnitItemInSlot( oldHero , itemIndex ) )
set itemIndex = itemIndex + 1
endloop
if localPlayer == trigPlayer then
call ClearSelection ( )
call SelectUnit ( newHero, true )
call PanCameraToTimed( x, y, 0.4 )
endif
//! runtextmacro ChangePlayerState( "trigPlayer", "RESOURCE_GOLD", "cost" )
call AddGold( returnValue, trigPlayerId, TRANSFERTYPE_PLAYER_PLAYER, "Ship sell" )
call Transfer( cost, trigPlayerId, bj_PLAYER_NEUTRAL_EXTRA, TRANSFERTYPE_PLAYER_PLAYER, "Ship buy" )
call RemoveUnit( oldHero )
call CreateBountyText( returnValue, GetSellingUnit(), trigPlayer )
call SetUnitX ( newHero, x )
call SetUnitY ( newHero, y )
call SetUnitFacing ( newHero, facing )
if IsPlayerAlly( localPlayer , trigPlayer ) and localPlayer != trigPlayer and ShowMessages[ GetPlayerId( LOCAL_PLAYER ) ] then
call DisplayText( localPlayer, msg )
endif
set Hero[ trigPlayerId ] = newHero
call RegisterHeroRevive( newHero )
call SetHeroXP( newHero, experience - expCost, false )
if oldIsTrader != newIsTrader then
call SwitchUpgrades.evaluate( newHero )
if newIsTrader then
set TradeSystem_Multiplier[ trigPlayerId ] = Profit[ ItemLevels[ trigPlayerId ][ REQ_PROFIT ] ]
else
set TradeSystem_Multiplier[ trigPlayerId ] = MULTIPLIER_DEFAULT
endif
endif
endif
set newHero = null
set oldHero = null
endfunction
private function InitShipChange takes nothing returns nothing
call TriggerAddAction ( ShipChanger , function ShipChanger_Actions )
call TriggerRegisterAnyUnitEventBJ( ShipChanger, EVENT_PLAYER_UNIT_SELL )
call TriggerAddCondition( ShipChanger, Condition( function ShipChanger_Cond ) )
endfunction
endlibrary