| 11-10-2008, 11:52 PM | #1 |
Greed is a game mode that was included in Starcraft. To win, players should gather and accumulate resources to a certain amount, or beat all other players. All functionalities can be used by just copying and pasting only two libraries. To start, call Init functions instead of melee initialization functions. For Init function references, refer to script head comments. A sample map is included. (original map made by Blizzard Entertainment) * Updated to 1.1.0; now supports non-melee InitCustom function. Greed:// ------------------------------------------------------------ // Greed // // Version: 1.1.0 // Author: Touko-Aozaki // Contact: [email protected] // http://touko.pe.kr // ------------------------------------------------------------ // How to use: // call Greed_Init(gold, lumber, show_multiboard) directly. // this will start game in greed mode with specified parameters // -OR- // call Greed_InitBasic() // this will allow one player to select predefined settings // -OR- // call Greed_InitCustom(gold, lumber, show_multiboard, victory_cb) // while Greed_Init starts game as melee, Greed_InitCustom doesn't. // last parameter is used to inform when a player wins, // so appropriate measures can be done. // ------------------------------------------------------------ // CHANGELOG // [1.1.0] // Added Greed_InitCustom. // ------------------------------------------------------------ library Greed initializer greed_INIT requires PlayerColor // function interface for callback function interface VictoryCallback takes player winner returns nothing globals // callback private VictoryCallback victory_cb = 0 // state private boolean initialized = false private boolean instantiated = false private boolean is_custom = false // triggers private trigger resources_changed = null // objectives private integer obj_gold = -1 private integer obj_lumber = -1 // multiboard private multiboard mb_resources = null // player list private player array players private integer player_count // resource multiplier private real array multiplier // timers private timer mb_reset_timer = null // constants private constant string MB_RESOURCES_TITLE = "Greed" private constant string MB_RESOURCES_ITEM_GOAL = "Goal" private constant string MB_RESOURCES_ICON_GOLD = "UI\\Feedback\\Resources\\ResourceGold.blp" private constant string MB_RESOURCES_ICON_LUMBER = "UI\\Feedback\\Resources\\ResourceLumber.blp" private constant real MB_RESOURCES_NAME_WIDTH = 0.11 private constant real MB_RESOURCES_VALUE_WIDTH = 0.05 // basic init constants, dialog and buttons private constant integer BASIC_COUNT = 6 private constant integer BASIC_PHASE_NONE = 0 private constant integer BASIC_PHASE_GOLD = 1 private constant integer BASIC_PHASE_LUMBER = 2 private constant integer BASIC_PHASE_DONE = 3 private constant string BASIC_TITLE_GOLD = "Winning Gold Amount" private constant string BASIC_TITLE_LUMBER = "Winning Lumber Amount" private constant string BASIC_MSG_GOLD_WAIT = "Winning gold amount is being set. Please wait..." private constant string BASIC_MSG_LUMBER_WAIT = "Winning lumber amount is being set. Please wait..." private constant string BASIC_MSG_START_WAIT_FIVE = "Starting in |cffff00005|r seconds." private constant string BASIC_MSG_START_WAIT_FOUR = "Starting in |cffff00004|r seconds." private constant string BASIC_MSG_START_WAIT_THREE = "Starting in |cffff00003|r seconds." private constant string BASIC_MSG_START_WAIT_TWO = "Starting in |cffff00002|r seconds." private constant string BASIC_MSG_START_WAIT_ONE = "Starting in |cffff00001|r second." private constant string BASIC_MSG_SET_GOLD = "Please set winning gold amount." private constant string BASIC_MSG_SET_LUMBER = "Please set winning lumber amount." private constant string BASIC_TICK_SOUND = "Sound\\Interface\\BattleNetTick.wav" private trigger basic_dialog_clicked = null private trigger basic_player_left = null private sound basic_tick = null private dialog basic_init_dialog = null private button array basic_init_button[BASIC_COUNT] private integer array basic_amount[BASIC_COUNT] private player master = null private integer basic_gold = -1 private integer basic_lumber = -1 private integer basic_phase = BASIC_PHASE_NONE endglobals // initializes a melee game private function MeleeInit takes nothing returns nothing call MeleeStartingVisibility( ) call MeleeStartingHeroLimit( ) call MeleeGrantHeroItems( ) call MeleeStartingResources( ) call MeleeClearExcessUnits( ) call MeleeStartingUnits( ) call MeleeStartingAI( ) call MeleeInitVictoryDefeat( ) endfunction private function InitPlayers takes nothing returns nothing local integer i = 0 local player p = null set player_count = 0 loop set p = Player(i) if GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING and not IsPlayerObserver(p) then if GetPlayerController(p) == MAP_CONTROL_USER or GetPlayerController(p) == MAP_CONTROL_COMPUTER then set players[player_count] = p set multiplier[i] = 1.0 if GetPlayerController(p) == MAP_CONTROL_COMPUTER then if GetAIDifficulty(p) == AI_DIFFICULTY_NEWBIE then set multiplier[i] = 0.5 elseif GetAIDifficulty(p) == AI_DIFFICULTY_INSANE then set multiplier[i] = 2.0 endif endif set player_count = player_count + 1 endif endif set i = i + 1 exitwhen i == bj_MAX_PLAYER_SLOTS endloop set p = null endfunction private function Victory takes player p returns nothing local integer i = 0 loop if PlayersAreCoAllied(p, Player(i)) == false then call MakeUnitsPassiveForPlayer(Player(i)) endif set i = i + 1 exitwhen i == bj_MAX_PLAYER_SLOTS endloop call MeleeCheckForLosersAndVictors() endfunction private function CheckVictory takes player p returns nothing if not is_custom then // melee-based mode if bj_meleeDefeated[GetPlayerId(p)] or bj_meleeGameOver then // skip return endif endif // check victory if GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD) >= obj_gold * multiplier[GetPlayerId(p)] then // separated to two ifs for readability. if GetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER) >= obj_lumber * multiplier[GetPlayerId(p)] then // victory condition! call victory_cb.execute(p) endif endif endfunction private function GetFirstPlayer takes nothing returns player local integer i = 0 loop if GetPlayerController(Player(i)) == MAP_CONTROL_USER and GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING then return Player(i) endif set i = i + 1 exitwhen i == bj_MAX_PLAYER_SLOTS endloop return null endfunction private function UpdateBasicInitDialog takes boolean show returns nothing if basic_phase == BASIC_PHASE_GOLD then call DialogSetMessage(basic_init_dialog, BASIC_TITLE_GOLD) elseif basic_phase == BASIC_PHASE_LUMBER then call DialogSetMessage(basic_init_dialog, BASIC_TITLE_LUMBER) else return endif set master = GetFirstPlayer() call DialogDisplay(GetLocalPlayer(), basic_init_dialog, false) call DialogDisplay(master, basic_init_dialog, show) endfunction private function UpdateBasicInitButtons takes boolean include_zero returns nothing local integer i = 0 if include_zero == false then set basic_init_button[0] = null set i = 1 endif call DialogClear(basic_init_dialog) loop set basic_init_button[i] = DialogAddButton(basic_init_dialog, I2S(basic_amount[i]), 0) set i = i + 1 exitwhen i >= basic_amount.size endloop call UpdateBasicInitDialog(false) endfunction private function UpdateMultiboard takes nothing returns nothing local multiboarditem mb_item local integer i = 0 // iterate through players and update resources loop set mb_item = MultiboardGetItem(mb_resources, i+1, 1) call MultiboardSetItemValue(mb_item, I2S(R2I(GetPlayerState(players[i], PLAYER_STATE_RESOURCE_GOLD)/multiplier[GetPlayerId(players[i])]))) call MultiboardReleaseItem(mb_item) set mb_item = MultiboardGetItem(mb_resources, i+1, 2) call MultiboardSetItemValue(mb_item, I2S(R2I(GetPlayerState(players[i], PLAYER_STATE_RESOURCE_LUMBER)/multiplier[GetPlayerId(players[i])]))) call MultiboardReleaseItem(mb_item) set i = i + 1 exitwhen i == player_count endloop set mb_item = null endfunction private function BasicPlayerLeft takes nothing returns nothing if GetTriggerPlayer() != master then return endif call UpdateBasicInitDialog(true) if GetLocalPlayer() == master then if basic_phase == BASIC_PHASE_GOLD then call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 300, BASIC_MSG_SET_GOLD) elseif basic_phase == BASIC_PHASE_LUMBER then call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 300, BASIC_MSG_SET_LUMBER) endif endif endfunction private function ShowMultiboard takes boolean show returns nothing call MultiboardDisplay(mb_resources, show) endfunction private function ResetMultiboard takes nothing returns nothing call ShowMultiboard(true) endfunction private function SetupMultiboard takes nothing returns nothing local multiboarditem mb_item local integer i local integer row_count = 1 + player_count set mb_resources = CreateMultiboard() // create multiboard layout call MultiboardSetTitleText(mb_resources, MB_RESOURCES_TITLE) call MultiboardSetRowCount(mb_resources, row_count) call MultiboardSetColumnCount(mb_resources, 3) call MultiboardSetItemsWidth(mb_resources, MB_RESOURCES_VALUE_WIDTH) call MultiboardSetItemsStyle(mb_resources, true, true) // set up the first row set mb_item = MultiboardGetItem(mb_resources, 0, 0) call MultiboardSetItemStyle(mb_item, true, false) call MultiboardSetItemValueColor(mb_item, 255, 204, 51, 255) call MultiboardSetItemValue(mb_item, MB_RESOURCES_ITEM_GOAL) call MultiboardSetItemWidth(mb_item, MB_RESOURCES_NAME_WIDTH) call MultiboardReleaseItem(mb_item) set mb_item = MultiboardGetItem(mb_resources, 0, 1) call MultiboardSetItemValue(mb_item, I2S(obj_gold)) call MultiboardSetItemIcon(mb_item, MB_RESOURCES_ICON_GOLD) call MultiboardReleaseItem(mb_item) set mb_item = MultiboardGetItem(mb_resources, 0, 2) call MultiboardSetItemValue(mb_item, I2S(obj_lumber)) call MultiboardSetItemIcon(mb_item, MB_RESOURCES_ICON_LUMBER) call MultiboardReleaseItem(mb_item) // set up other rows set i = 0 loop set mb_item = MultiboardGetItem(mb_resources, i+1, 0) call MultiboardSetItemValue(mb_item,GetPlayerName(players[i])) call MultiboardSetItemStyle(mb_item, true, false) call MultiboardSetItemValueColor(mb_item, PlayerColor_GetRed(players[i]), PlayerColor_GetGreen(players[i]), PlayerColor_GetBlue(players[i]), 255) call MultiboardSetItemWidth(mb_item, 0.1) call MultiboardReleaseItem(mb_item) set mb_item = MultiboardGetItem(mb_resources, i+1, 1) call MultiboardSetItemIcon(mb_item, MB_RESOURCES_ICON_GOLD) call MultiboardReleaseItem(mb_item) set mb_item = MultiboardGetItem(mb_resources, i+1, 2) call MultiboardSetItemIcon(mb_item, MB_RESOURCES_ICON_LUMBER) call MultiboardReleaseItem(mb_item) set i = i + 1 exitwhen i == player_count endloop set mb_reset_timer = CreateTimer() call UpdateMultiboard() call MultiboardMinimize(mb_resources, false) call TimerStart(mb_reset_timer, 10, true, function ResetMultiboard) set mb_item = null endfunction private function ResourcesChanged takes nothing returns nothing call UpdateMultiboard() call CheckVictory(GetTriggerPlayer()) endfunction public function Init takes integer gold, integer lumber, boolean showMultiboard returns boolean if initialized == false or instantiated == true then return false endif // instantiate the game // update objectives set obj_gold = gold set obj_lumber = lumber // disable resource exchange call SetMapFlag(MAP_LOCK_RESOURCE_TRADING, true) // start a melee game call MeleeInit() // initialize players call InitPlayers() // set callback set victory_cb = Victory // enable trigger call EnableTrigger(resources_changed) if showMultiboard then // set up multiboard call SetupMultiboard() call ShowMultiboard(true) endif set instantiated = true return true endfunction public function InitBasic takes nothing returns nothing if initialized == false or instantiated == true then return endif // completely cover the screen call CinematicFadeBJ(bj_CINEFADETYPE_FADEOUT, 0, "ReplaceableTextures\\CameraMasks\\White_mask.blp", 0, 0, 0, 0) // 0 sec delay; prevent issues when called from Map Initialization call TriggerSleepAction(0) // update phase set basic_phase = BASIC_PHASE_GOLD // enable trigger call EnableTrigger(basic_player_left) // update and show dialog // NOTE: To diable option of 0, just change parameter of // UpdateBasicInitButtons from true to false. call UpdateBasicInitButtons(true) call UpdateBasicInitDialog(true) // display message if GetLocalPlayer() == master then call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 300, BASIC_MSG_SET_GOLD) else call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 300, BASIC_MSG_GOLD_WAIT) endif endfunction function InitCustom takes integer gold, integer lumber, boolean show_mb, VictoryCallback cb returns boolean if initialized == false or instantiated == true then return false endif // instantiate the game // update objectives set obj_gold = gold set obj_lumber = lumber // disable resource exchange call SetMapFlag(MAP_LOCK_RESOURCE_TRADING, true) // initialize players call InitPlayers() if cb != 0 then // set callback set victory_cb = cb // set flag set is_custom = true // enable trigger call EnableTrigger(resources_changed) endif if show_mb then // set up multiboard call SetupMultiboard() call ShowMultiboard(true) endif set instantiated = true return true endfunction private function BasicButtonClicked takes nothing returns nothing local integer i = 0 loop exitwhen GetClickedButton() == basic_init_button[i] set i = i + 1 if i == basic_init_button.size then // there must be some mistake. return endif endloop if basic_phase == BASIC_PHASE_GOLD then set basic_gold = basic_amount[i] if i == 0 then // one of the objectives must be greater than 0; // disable lumber option of 0. call UpdateBasicInitButtons(false) endif set basic_phase = BASIC_PHASE_LUMBER call UpdateBasicInitDialog(true) call ClearTextMessages() if GetLocalPlayer() == master then call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 300, BASIC_MSG_SET_LUMBER) else call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 300, BASIC_MSG_LUMBER_WAIT) endif elseif basic_phase == BASIC_PHASE_LUMBER then set basic_lumber = basic_amount[i] set basic_phase = BASIC_PHASE_DONE set master = null call DisableTrigger(basic_player_left) call ClearTextMessages() call TriggerSleepAction(1) call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, BASIC_MSG_START_WAIT_FIVE) call StartSound(basic_tick) call TriggerSleepAction(1) call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, BASIC_MSG_START_WAIT_FOUR) call StartSound(basic_tick) call TriggerSleepAction(1) call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, BASIC_MSG_START_WAIT_THREE) call StartSound(basic_tick) call TriggerSleepAction(1) call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, BASIC_MSG_START_WAIT_TWO) call StartSound(basic_tick) call TriggerSleepAction(1) call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, BASIC_MSG_START_WAIT_ONE) call StartSound(basic_tick) call TriggerSleepAction(1) call KillSoundWhenDone(basic_tick) call Init(basic_gold, basic_lumber, true) // show the screen call CinematicFadeBJ(bj_CINEFADETYPE_FADEIN, 0.2, "ReplaceableTextures\\CameraMasks\\White_mask.blp", 0, 0, 0, 0) call ClearTextMessages() endif endfunction public function IsInitialized takes nothing returns boolean return initialized endfunction public function IsInstantiated takes nothing returns boolean return instantiated endfunction public function IsCustom takes nothing returns boolean return is_custom endfunction // library initializer private function greed_INIT takes nothing returns nothing local integer i set resources_changed = CreateTrigger() call TriggerAddAction(resources_changed, function ResourcesChanged) set i = 0 // add events loop call TriggerRegisterPlayerStateEvent(resources_changed, Player(i), PLAYER_STATE_RESOURCE_GOLD, NOT_EQUAL, -1) call TriggerRegisterPlayerStateEvent(resources_changed, Player(i), PLAYER_STATE_RESOURCE_LUMBER, NOT_EQUAL, -1) set i = i + 1 exitwhen i == bj_MAX_PLAYER_SLOTS endloop call DisableTrigger(resources_changed) // basic init initialization // initialize amounts // note that index 0 is reserved for disabling (objective value of 0). // if you want to remove option 0, edit InitBasic function. set basic_amount[0] = 0 // RESERVED! DO NOT EDIT!! set basic_amount[1] = 5000 set basic_amount[2] = 10000 set basic_amount[3] = 15000 set basic_amount[4] = 20000 set basic_amount[5] = 25000 // initialize dialog set basic_init_dialog = DialogCreate() set basic_dialog_clicked = CreateTrigger() call TriggerAddAction(basic_dialog_clicked, function BasicButtonClicked) call TriggerRegisterDialogEvent(basic_dialog_clicked, basic_init_dialog) set basic_player_left = CreateTrigger() call TriggerAddAction(basic_player_left, function BasicPlayerLeft) set i = 0 loop call TriggerRegisterPlayerEvent(basic_player_left, Player(i), EVENT_PLAYER_LEAVE) set i = i + 1 exitwhen i == bj_MAX_PLAYER_SLOTS endloop call DisableTrigger(basic_player_left) // initialize sound set basic_tick = CreateSound(BASIC_TICK_SOUND, false, false, true, 12700, 12700, "") set initialized = true endfunction endlibrary PlayerColor:// ------------------------------------------------------------ // PlayerColor // // Version: 1.0.0 // Author: Touko-Aozaki // Contact: [email protected] // http://touko.pe.kr // ------------------------------------------------------------ // Player color utility functions. // ------------------------------------------------------------ library PlayerColor initializer init globals private integer array red [12] private integer array green [12] private integer array blue [12] endglobals public function GetColoredString takes player p, string str returns string local integer index = GetPlayerId(p) if index == 0 then set str="|cffFF0202"+str+"|r" elseif index == 1 then set str="|cff0041FF"+str+"|r" elseif index == 2 then set str="|cff1BE6B8"+str+"|r" elseif index == 3 then set str="|cff530080"+str+"|r" elseif index == 4 then set str="|cffFFFC00"+str+"|r" elseif index == 5 then set str="|cffFE890D"+str+"|r" elseif index == 6 then set str="|cff1FBF00"+str+"|r" elseif index == 7 then set str="|cffE55AAF"+str+"|r" elseif index == 8 then set str="|cff949596"+str+"|r" elseif index == 9 then set str="|cff7DBEF1"+str+"|r" elseif index == 10 then set str="|cff0F6145"+str+"|r" elseif index == 11 then set str="|cff4D2903"+str+"|r" else set str="|cff000000"+str+"|r" endif return str endfunction public function GetRed takes player p returns integer local integer i = GetPlayerId(p) if i >= 0 and i < 12 then return red[i] endif return 0x00 endfunction public function GetGreen takes player p returns integer local integer i = GetPlayerId(p) if i >= 0 and i < 12 then return green[i] endif return 0x00 endfunction public function GetBlue takes player p returns integer local integer i = GetPlayerId(p) if i >= 0 and i < 12 then return blue[i] endif return 0x00 endfunction private function init takes nothing returns nothing set red[0]=0xFF set red[1]=0x00 set red[2]=0x1B set red[3]=0x53 set red[4]=0xFF set red[5]=0xFE set red[6]=0x1F set red[7]=0xE5 set red[8]=0x94 set red[9]=0x7D set red[10]=0x0F set red[11]=0x4D set green[0]=0x02 set green[1]=0x41 set green[2]=0xE6 set green[3]=0x00 set green[4]=0xFC set green[5]=0x89 set green[6]=0xBF set green[7]=0x5A set green[8]=0x95 set green[9]=0xBE set green[10]=0x61 set green[11]=0x29 set blue[0]=0x02 set blue[1]=0xFF set blue[2]=0xB8 set blue[3]=0x80 set blue[4]=0x00 set blue[5]=0x0D set blue[6]=0x00 set blue[7]=0xAF set blue[8]=0x96 set blue[9]=0xF1 set blue[10]=0x45 set blue[11]=0x03 endfunction endlibrary |
| 11-11-2008, 06:57 AM | #2 |
I think they end up in the same section anyway (see PUI and ABC, scripts but... also see Parabolic function, like 5 lines of code). This looks more like a system. I like the configurable levels of it, though. |
| 11-11-2008, 08:58 AM | #3 |
Due to how specific usage it is, and its standalone nature, I'd say system. So this doesn't allow for asymetric amounts? And can only be used if you want a melee game? Doesn't seem very useful to me. |
| 11-11-2008, 09:37 AM | #4 | |
Quote:
As Greed_Init takes two amount parameters for each type of resources, asymmetric amounts are allowed. Actually, dialog of Greed_InitBasic asks twice for each types. Currently it is based on melee games for seamless integration. However, you can still add additional systems and it would work fine. For instance, a system that takes a percent of resources away for each buildings destroyed can be applied. Actually it was what I tried to integrate at first, but gave up and removed for general application. Current version would work fine for most cases. However, I'm planning to add non-melee support in a future version. |
| 11-11-2008, 12:44 PM | #5 | ||
Quote:
I meant between players. Quote:
Seemless integration into melee, perhaps. Impossible integration into anything else without rewriting your code. As it is, it's simply far too specific to really be of any use. |
| 11-11-2008, 12:54 PM | #6 | |
Quote:
I find this resource very interesting, and I am quite sure it would fit my map CCFE in perfection, since it is a "melee map". I may yet import this if it gets approved. Just to demonstrate my opinion. One question though, is the player Color thing really needed ? My map already has something of its own to handle player colours. |
| 11-11-2008, 02:20 PM | #7 | |||
Quote:
I don't think that is really necessary. Considering the very nature of the mode, how would having inconsistent goals be meaningful? What if in a melee game, one player can win the game by just destroying a few buildings while you have to destroy all? That would be an unfair advantage. Furthermore, is it possible to set up a fair criteria for fairly assigning different amounts? I don't think there is such a way to determine it. Also, It doesn't even fall into the definition of greed mode. If someone needs such functionality, he should look for another one; this library is out of the question. Quote:
I'm considering a few options. Once the interface of new InitCustom function gets ready, it wouldn't take an hour to implement that. Quote:
If yours can handle color components, it's totally fine to use that. Just make sure you edit the code: where the multiboard is set up. However, it is not recommended to use string color formatting instead of multiboard item color. Those formatting characters are counted as characters and would cause truncation. |
| 11-19-2008, 01:23 AM | #8 |
How's it coming? Following the new rules, if you don't update or respond to this thread within 7 days, this will be graveyarded. |
| 11-19-2008, 03:45 AM | #9 | |
Quote:
Actually I've updated it a few days ago, but forgot to bump :) |
| 01-01-2009, 07:30 PM | #10 |
I've tested it, and it looks fine, moved to samples because it's not generally used, but interesting in code. |
