| 02-02-2009, 03:29 AM | #1 |
EDIT Test map also changed. (use the peasant at the bottom of the map. it has 7 menus) It now works with multiple workers each with its own set of menus. no 2 'worker conglomerate' can make use of the same 'worker object' (unitId worker) or chaosId. SCRIPT JASS:library AdvancedBuildMenu initializer Init private keyword WorkerMenus globals private constant integer MAX_INSTANCES = 8190 private constant integer MAX_MENUS_PER_INSTANCE = 7 //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII// //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII// //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII// //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII// private unit array gU_Excluded[8190] private integer gINT_CountExcluded = 0 //Temporary variables. private group gUG = CreateGroup() private unit gU = null private WorkerMenus gWM = 0 endglobals //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII// //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII// function CreateWorkerMenu takes integer primeWorkerId, integer primeChaosId returns WorkerMenus return WorkerMenus.Create(primeWorkerId, primeChaosId) endfunction function WorkerRegisterMenu takes integer primeWorkerId, integer dummyButtonId, integer workerId, integer chaosId returns boolean local WorkerMenus WM = WorkerMenus.Get(primeWorkerId) return WM.AddMenu(dummyButtonId, workerId, chaosId) endfunction //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII// //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII// private struct WorkerMenus[MAX_INSTANCES] public integer array intDummyButtonId[MAX_MENUS_PER_INSTANCE] public integer array intWorkerId[MAX_MENUS_PER_INSTANCE] public integer array intChaosId[MAX_MENUS_PER_INSTANCE] public integer intCountMenu = 1 public static method Create takes integer primeWorkerId, integer primeChaosId returns WorkerMenus if WorkerMenus.intCountInst < MAX_INSTANCES then set WorkerMenus.Inst[WorkerMenus.intCountInst] = WorkerMenus.allocate() set WorkerMenus.Inst[WorkerMenus.intCountInst].intDummyButtonId[0] = 0 set WorkerMenus.Inst[WorkerMenus.intCountInst].intWorkerId[0] = primeWorkerId set WorkerMenus.Inst[WorkerMenus.intCountInst].intChaosId[0] = primeChaosId set WorkerMenus.intCountInst = WorkerMenus.intCountInst + 1 return WorkerMenus.Inst[WorkerMenus.intCountInst - 1] endif return 0 endmethod public method AddMenu takes integer dummyButtonId, integer workerId, integer chaosId returns boolean local integer INT_Index = 0 local integer INT_Index2 if dummyButtonId != 0 and workerId != 0 and chaosId != 0 then loop exitwhen INT_Index == WorkerMenus.intCountInst set INT_Index2 = 0 loop exitwhen INT_Index2 == WorkerMenus.Inst[INT_Index].intCountMenu if WorkerMenus.Inst[INT_Index].intWorkerId[INT_Index2] == workerId or WorkerMenus.Inst[INT_Index].intChaosId[INT_Index2] == chaosId then return false endif set INT_Index2 = INT_Index2 + 1 endloop set INT_Index = INT_Index + 1 endloop set .intDummyButtonId[.intCountMenu] = dummyButtonId set .intWorkerId[.intCountMenu] = workerId set .intChaosId[.intCountMenu] = chaosId set .intCountMenu = .intCountMenu + 1 return true endif return false endmethod public static WorkerMenus array Inst[MAX_INSTANCES] public static integer intCountInst = 0 public static method Get takes integer unitId returns WorkerMenus local integer INT_Index = 0 local integer INT_Index2 loop exitwhen INT_Index == WorkerMenus.intCountInst set INT_Index2 = 0 loop exitwhen INT_Index2 == WorkerMenus.Inst[INT_Index].intCountMenu if WorkerMenus.Inst[INT_Index].intWorkerId[INT_Index2] == unitId then return WorkerMenus.Inst[INT_Index] endif set INT_Index2 = INT_Index2 + 1 endloop set INT_Index = INT_Index + 1 endloop return 0 endmethod public method GetExtraMenuIndex takes integer dummyButtonId returns integer local integer INT_Index = 1 loop exitwhen INT_Index == WorkerMenus.Inst[INT_Index].intCountMenu if WorkerMenus.Inst[INT_Index].intDummyButtonId[INT_Index] == dummyButtonId then return INT_Index endif set INT_Index = INT_Index + 1 endloop return -1 endmethod endstruct private function IsUnitContingentSubject takes nothing returns boolean local integer INT_Index = 0 set gU = GetFilterUnit() loop exitwhen INT_Index == gINT_CountExcluded if gU_Excluded[INT_Index] == gU then set gINT_CountExcluded = gINT_CountExcluded - 1 set gU_Excluded[INT_Index] = gU_Excluded[gINT_CountExcluded] set gU_Excluded[gINT_CountExcluded] = null return false endif set INT_Index = INT_Index + 1 endloop return IsUnitType(gU, UNIT_TYPE_PEON) and IsUnitSelected(gU, GetOwningPlayer(gU)) endfunction private function OpenFirstMenu takes nothing returns nothing local integer INT_UnitId call GroupEnumUnitsInRect(gUG, bj_mapInitialPlayableArea, Filter(function IsUnitContingentSubject)) loop set gU = FirstOfGroup(gUG) exitwhen gU == null set INT_UnitId = GetUnitTypeId(gU) set gWM = WorkerMenus.Get(INT_UnitId) if gWM != 0 and INT_UnitId != gWM.intWorkerId[0] then call UnitAddAbility(gU, gWM.intChaosId[0]) endif call GroupRemoveUnit(gUG, gU) endloop call GroupClear(gUG) set gU = null set gWM = 0 endfunction private function OpenExtraMenu takes nothing returns nothing local integer INT_Index set gU = GetTriggerUnit() set gWM = WorkerMenus.Get(GetUnitTypeId(gU)) set INT_Index = gWM.GetExtraMenuIndex(GetSpellAbilityId()) if INT_Index != -1 then if GetUnitTypeId(gU) != gWM.intWorkerId[INT_Index] then call UnitAddAbility(gU, gWM.intChaosId[INT_Index]) endif set gU_Excluded[gINT_CountExcluded] = gU set gINT_CountExcluded = gINT_CountExcluded + 1 if GetLocalPlayer() == GetOwningPlayer(gU) then call ForceUIKey("B") endif endif set gU = null set gWM = 0 endfunction private function Init takes nothing returns nothing local trigger TRIG = CreateTrigger() call TriggerRegisterGameEvent(TRIG, EVENT_GAME_BUILD_SUBMENU) call TriggerAddAction(TRIG, function OpenFirstMenu) set TRIG = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(TRIG, EVENT_PLAYER_UNIT_SPELL_EFFECT) call TriggerAddAction(TRIG, function OpenExtraMenu) set TRIG = null endfunction endlibrary Test JASS:library Test initializer Init requires AdvancedBuildMenu private function Init takes nothing returns nothing call CreateWorkerMenu('h001','S000') call WorkerRegisterMenu('h001', 'A000','h00C', 'S001') call WorkerRegisterMenu('h001', 'A001','h00D', 'S002') call WorkerRegisterMenu('h001', 'A002','h00E', 'S003') call WorkerRegisterMenu('h001', 'A003','h00F', 'S004') call WorkerRegisterMenu('h001', 'A004','h00G', 'S005') call WorkerRegisterMenu('h001', 'A005','h00H', 'S006') endfunction endlibrary |
| 02-02-2009, 01:46 PM | #2 |
It seems to work better with EVENT_PLAYER_UNIT_SPELL_CAST. Added: isn't group with API better than loop iteration with arrays? I think just a single group and IsUnitInGroup native would be enough. Added 2: two (mayby identical) questions: does EVENT_GAME_BUILD_SUBMENU fire for every players? is this multiplayer-ready? |
| 02-02-2009, 11:58 PM | #3 |
for some reason, if spell cast is used, it fires twice; because they are issued some order first then 'chaos'd then issued it again after chaos. it was at first a GroupAddUNit() IsUnitInGroup() GroupRemoveUnit() operation. but later i regarded some post i read somewhere saying that looping is better than 'group'ing - or maybe i just made this up in my head... verification? it works in multiplayer, or at least i trhink it does. the game event does fire for ALL players but it doesnt matter if the other players' peasants are altered as well since they will, by this script, be able to access any build menu still. i have not been able to think of a way to determine which unit's build menu was opened. suggestions? a concern i have is that the workers may be silenced... |
