| 12-05-2008, 04:09 AM | #1 |
i made this code for my map. it allows players to 'browse' through a shop/dispenser - a unit - by attributing to it different 'pages'. each page is actually a different unit that replaces the old one. works with item vendors, mercenary camps, hero taverns, etc. each player for which the dispenser is enabled is able to interact with his 'face'-dispenser only; so that multiple players can browse the 'shop' at different pages simulatenously. ...dunno about how to apply item cooldown for all other players when one player buys it at his 'face'... suggestions? it only requires 2 abilities - both based-of any non-targetable ability. criticism? JASS:library DynamicDispenser initializer test globals private constant integer PREVIOUS_PAGE_ABILITY_ID = 'A006' private constant integer NEXT_PAGE_ABILITY_ID = 'A007' private constant boolean FLIP_TO_OTHER_END = false endglobals struct DynamicDispenser private real rX private real rY private real rFacing private integer array intPageUnitId[10] private integer intCountPage = 1 private unit array uFace[16] private player array p[16] private integer intCountFace = 0 private integer array intPageIndex[16] public static method Create takes integer prime, real x, real y, real facing returns DynamicDispenser local DynamicDispenser New = DynamicDispenser.allocate() set New.rX = x set New.rY = y set New.rFacing = facing set New.intPageUnitId[0] = prime set New.intInstIndex = DynamicDispenser.intCountInst set DynamicDispenser.Inst[DynamicDispenser.intCountInst] = New set DynamicDispenser.intCountInst = DynamicDispenser.intCountInst + 1 return New endmethod public method Destroy takes nothing returns nothing loop exitwhen .intCountFace == 0 call GroupRemoveUnit(DynamicDispenser.ugDispenser, .uFace[.intCountFace]) call RemoveUnit(.uFace[.intCountFace]) set .uFace[.intCountFace] = null set .p[.intCountFace] = null set .intCountFace = .intCountFace - 1 endloop set DynamicDispenser.intCountInst = DynamicDispenser.intCountInst - 1 set DynamicDispenser.Inst[DynamicDispenser.intCountInst].intInstIndex = .intInstIndex set DynamicDispenser.Inst[.intInstIndex] = DynamicDispenser.Inst[DynamicDispenser.intCountInst] set DynamicDispenser.Inst[DynamicDispenser.intCountInst] = 0 endmethod public method SetPosition takes real x, real y, real facing returns nothing local integer INT_Index = 0 set .rX = x set .rY = y set .rFacing = facing loop exitwhen INT_Index == .intCountFace call SetUnitX(.uFace[INT_Index], .rX) call SetUnitY(.uFace[INT_Index], .rY) call SetUnitFacing(.uFace[INT_Index], .rFacing) set INT_Index = INT_Index + 1 endloop endmethod public method EnableForPlayer takes player p returns nothing set .p[.intCountFace] = p set .intPageIndex[.intCountFace] = 0 set .uFace[.intCountFace] = CreateUnit(p, .intPageUnitId[.intPageIndex[.intCountFace]], .rX, .rY, .rFacing) if GetUnitAbilityLevel(.uFace[.intCountFace], PREVIOUS_PAGE_ABILITY_ID) == 0 then call UnitAddAbility(.uFace[.intCountFace], PREVIOUS_PAGE_ABILITY_ID) endif if GetUnitAbilityLevel(.uFace[.intCountFace], NEXT_PAGE_ABILITY_ID) == 0 then call UnitAddAbility(.uFace[.intCountFace], NEXT_PAGE_ABILITY_ID) endif call GroupAddUnit(DynamicDispenser.ugDispenser, .uFace[.intCountFace]) if GetLocalPlayer() != .p[.intCountFace] then call SetUnitVertexColor(.uFace[.intCountFace], 0, 0, 0, 0) endif set .intCountFace = .intCountFace + 1 endmethod public method DisableForPlayer takes player p returns boolean local integer INT_FaceIndex = 0 loop exitwhen INT_FaceIndex >= .intCountFace if .p[INT_FaceIndex] == p then call GroupRemoveUnit(DynamicDispenser.ugDispenser, .uFace[INT_FaceIndex]) call RemoveUnit(.uFace[INT_FaceIndex]) set .uFace[INT_FaceIndex] = null loop exitwhen INT_FaceIndex == .intCountFace set .p[INT_FaceIndex] = .p[INT_FaceIndex + 1] set INT_FaceIndex = INT_FaceIndex + 1 endloop set .intCountFace = .intCountFace - 1 return true endif set INT_FaceIndex = INT_FaceIndex + 1 endloop return false endmethod public method AddPage takes integer id returns nothing set .intPageUnitId[.intCountPage] = id set .intCountPage = .intCountPage + 1 endmethod public method RemovePage takes integer id returns boolean local integer INT_PageIndex = 0 local integer INT_Index = 0 loop exitwhen INT_PageIndex >= .intCountPage if .intPageUnitId[INT_PageIndex] == id then loop exitwhen INT_Index == .intCountPage set .intPageUnitId[INT_Index] = .intPageUnitId[INT_Index + 1] set INT_Index = INT_Index + 1 endloop set .intCountPage = .intCountPage - 1 if .intCountPage == 0 then call .Destroy() endif set INT_Index = 0 loop exitwhen INT_Index == .intCountFace if .intPageIndex[INT_Index] == INT_PageIndex then call .TurnPage(INT_Index, 1) call .TurnPage(INT_Index, -1) endif set INT_Index = INT_Index + 1 endloop return true endif set INT_PageIndex = INT_PageIndex + 1 endloop return false endmethod private method TurnPage takes integer faceIndex, integer increment returns nothing local player P = GetOwningPlayer(.uFace[faceIndex]) call GroupRemoveUnit(DynamicDispenser.ugDispenser, .uFace[faceIndex]) call RemoveUnit(.uFace[faceIndex]) set .intPageIndex[faceIndex] = .intPageIndex[faceIndex] + increment if .intPageIndex[faceIndex] < 0 then if FLIP_TO_OTHER_END then set .intPageIndex[faceIndex] = .intCountPage - 1 else set .intPageIndex[faceIndex] = 0 endif elseif .intPageIndex[faceIndex] >= .intCountPage then if FLIP_TO_OTHER_END then set .intPageIndex[faceIndex] = 0 else set .intPageIndex[faceIndex] = .intCountPage - 1 endif endif set .uFace[faceIndex] = CreateUnit(P, .intPageUnitId[.intPageIndex[faceIndex]], .rX, .rY, .rFacing) if GetUnitAbilityLevel(.uFace[faceIndex], PREVIOUS_PAGE_ABILITY_ID) == 0 then call UnitAddAbility(.uFace[faceIndex], PREVIOUS_PAGE_ABILITY_ID) endif if GetUnitAbilityLevel(.uFace[faceIndex], NEXT_PAGE_ABILITY_ID) == 0 then call UnitAddAbility(.uFace[faceIndex], NEXT_PAGE_ABILITY_ID) endif call GroupAddUnit(DynamicDispenser.ugDispenser, .uFace[faceIndex]) if GetLocalPlayer() != .p[faceIndex] then call SetUnitVertexColor(.uFace[faceIndex], 0, 0, 0, 0) endif if GetLocalPlayer() == .p[faceIndex] then call SelectUnit(.uFace[faceIndex], true) endif set P = null endmethod private static method IsExecuteTurnPage takes nothing returns boolean return (GetSpellAbilityId() == PREVIOUS_PAGE_ABILITY_ID or GetSpellAbilityId() == NEXT_PAGE_ABILITY_ID) and IsUnitInGroup(GetTriggerUnit(), DynamicDispenser.ugDispenser) endmethod private static method ExecuteTurnPage takes nothing returns nothing local unit U = GetTriggerUnit() local integer INT_AbilityId = GetSpellAbilityId() local integer INT_InstIndex = 0 local integer INT_FaceIndex loop set INT_FaceIndex = 0 loop exitwhen DynamicDispenser.Inst[INT_InstIndex].uFace[INT_FaceIndex] == U or INT_FaceIndex == DynamicDispenser.Inst[INT_InstIndex].intCountFace set INT_FaceIndex = INT_FaceIndex + 1 endloop exitwhen DynamicDispenser.Inst[INT_InstIndex].uFace[INT_FaceIndex] == U set INT_InstIndex = INT_InstIndex + 1 endloop if INT_AbilityId == PREVIOUS_PAGE_ABILITY_ID then call DynamicDispenser.Inst[INT_InstIndex].TurnPage(INT_FaceIndex, -1) elseif INT_AbilityId == NEXT_PAGE_ABILITY_ID then call DynamicDispenser.Inst[INT_InstIndex].TurnPage(INT_FaceIndex, 1) endif set U = null endmethod private static trigger trigToggle = CreateTrigger() private static group ugDispenser = CreateGroup() public static method DynamicDispenserInit takes nothing returns nothing call TriggerRegisterAnyUnitEventBJ(DynamicDispenser.trigToggle, EVENT_PLAYER_UNIT_SPELL_EFFECT) call TriggerAddCondition(DynamicDispenser.trigToggle, Condition(function DynamicDispenser.IsExecuteTurnPage)) call TriggerAddAction(DynamicDispenser.trigToggle, function DynamicDispenser.ExecuteTurnPage) endmethod private integer intInstIndex private static DynamicDispenser array Inst[8190] private static integer intCountInst = 0 endstruct private function test takes nothing returns nothing local DynamicDispenser a = DynamicDispenser.Create('Hpal',0,0,0) call DynamicDispenser.DynamicDispenserInit() call a.EnableForPlayer(Player(0)) call a.AddPage('Hamg') call a.AddPage('Hmkg') call a.AddPage('Hblm') endfunction endlibrary |
| 12-05-2008, 10:36 PM | #2 |
JASS:if GetLocalPlayer() != .p[faceIndex] then call SetUnitVertexColor(.uFace[faceIndex], 0, 0, 0, 0) endif Wouldn't this cause a desync? |
| 12-05-2008, 10:57 PM | #3 |
No. SetUnitVertexColor only changes a unit's visual appearance which doesn't have to be the same for all players in order to maintain a synchronised gamestate. |
