- Joined
- Jan 11, 2009
- Messages
- 3,414
Hey guys! In one of my maps, there is a periodic event where a sunken city would appear in the ocean. Approaching it triggers a Cthulhu "boss" spawn and a small cinematic. The problem is that triggering this event causes a pretty nasty server split. Can anyone help me find what is causing it?
Here is the function related to the spawning:
And here is the rest of the script:
Finally, here are the functions controling the cinematic functions:
+rep to anyone who can help me out!
Here is the function related to the spawning:
JASS:
static method spawn takes nothing returns nothing
local real x = GetUnitX(.rlyeh)
local real y = GetUnitY(.rlyeh)
local integer i = 0
local trigger t = null
if .rlyeh == null then
return
endif
call .endEvent()
set t = CreateTrigger()
set .darklord = CreateUnit(Player(11), 'cthu', x, y, 0)
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, COLOR_RED+"The presence of humans has awoken the mighty Cthulhu from his slumber!")
call PlayThematicMusic("Sound\\Music\\mp3Music\\Doom.mp3")
call cineMode(true)
call endCineModeTimed(6)
loop
exitwhen i > 11
call UnitShareVision(.darklord, Player(i), true)
set i = i+1
endloop
call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, 1800, 0)
call SetCameraTargetController(.darklord, 0, 0, false)
call .setTarget()
call TriggerRegisterUnitEvent(t, .darklord, EVENT_UNIT_DEATH)
call TriggerAddCondition(t, Condition(function thistype.onDeath))
call TimerStart(.cooldown, 10, true, function thistype.onConvertUnit)
call TimerStart(.tick, 3, true, function thistype.update)
set t = null
endmethod
And here is the rest of the script:
JASS:
struct cthulhu extends array
static trigger spawnTrigger
static group subjects
static unit darklord = null
static unit rlyeh = null
static region r
static rect rct
static timer cooldown
static timer tick
static timer expire
static boolean dead = false
static real tx
static real ty
static integer array oldOwner
static method endEvent takes nothing returns nothing
call PauseTimer(.tick)
call PauseTimer(.expire)
call RegionClearRect(.r, .rct)
//call DisableTrigger(.spawnTrigger)
call KillUnit(.rlyeh)
set .rlyeh = null
endmethod
static method filterRandomUnit takes nothing returns boolean
local unit u = GetFilterUnit()
local integer p = GetPlayerId(GetOwningPlayer(u))
local boolean flag = p < 11 and IsUnitType(u, UNIT_TYPE_STRUCTURE) == false and GetUnitAbilityLevel(u, 'Avul') == 0 and GetUnitAbilityLevel(u, 'Aloc') == 0 and GetWidgetLife(u) > 0.5
set u = null
return flag
endmethod
static method convertUnit takes unit u returns nothing
local integer p = GetPlayerId(GetOwningPlayer(u))
set .oldOwner[GetUnitId(u)] = p
call SetUnitOwner(u, Player(11), true)
call GroupAddUnit(.subjects, u)
call UnitAddAbility(u, 'mcob')
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, COLOR_YELLOW+GetUnitName(u)+":|r Ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn!")
endmethod
static method onConvertUnit takes nothing returns nothing
call GroupEnumUnitsInRange(ENUM_GROUP, GetUnitX(.darklord), GetUnitY(.darklord), 600, Filter(function thistype.filterRandomUnit))
if FirstOfGroup(ENUM_GROUP) != null then
call .convertUnit(FirstOfGroup(ENUM_GROUP))
endif
call GroupClear(ENUM_GROUP)
endmethod
static method releaseConvertedUnits takes nothing returns nothing
local unit u = GetEnumUnit()
local integer p = .oldOwner[GetUnitId(u)]
call SetUnitOwner(u, Player(p), true)
call UnitRemoveAbility(u, 'mcob')
set u = null
endmethod
static method filterTarget takes nothing returns boolean
return IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) and GetWidgetLife(GetFilterUnit()) > 0.5
endmethod
static method setTarget takes nothing returns nothing
local integer i = 0
local integer p = -1
local unit target
loop
exitwhen i > 10
set i = i+1
if (GetRandomInt(1, i) == 1 or p == -1) and playerDefeated[i] == false then
set p = i
endif
endloop
call GroupEnumUnitsOfPlayer(ENUM_GROUP, Player(p), Filter(function thistype.filterTarget))
set target = GroupPickRandomUnit(ENUM_GROUP)
set .tx = GetUnitX(target)
set .ty = GetUnitY(target)
set target = null
endmethod
static method update takes nothing returns nothing
local real dx = GetUnitX(.darklord) - .tx
local real dy = GetUnitY(.darklord) - .ty
if (dx*dx)+(dy*dy) < 500*500 then
call .setTarget()
endif
call GroupPointOrder(.subjects, "attack", GetUnitX(.darklord), GetUnitY(.darklord))
call IssuePointOrder(.darklord, "attack", .tx, .ty)
endmethod
static method onEventTimeout takes nothing returns nothing
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, COLOR_GREEN+"BREAKING NEWS:|r The mysterious city has resubmerged into the ocean - it appears we will not learn its mysteries yet for some time.")
call StartSound(gg_snd_Warning)
call .endEvent()
endmethod
static method onDeath takes nothing returns boolean
set .dead = true
set .darklord = null
call PauseTimer(.cooldown)
call PauseTimer(.tick)
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, COLOR_GREEN+"BREAKING NEWS:|r The mightly Cthulhu has fallen back to the depths! Humanity is once again safe, for now..")
call StartSound(gg_snd_Rescue)
call ForGroup(.subjects, function thistype.releaseConvertedUnits)
call GroupClear(.subjects)
return false
endmethod
static method spawn takes nothing returns nothing
local real x = GetUnitX(.rlyeh)
local real y = GetUnitY(.rlyeh)
local integer i = 0
local trigger t = null
if .rlyeh == null then
return
endif
call .endEvent()
set t = CreateTrigger()
set .darklord = CreateUnit(Player(11), 'cthu', x, y, 0)
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, COLOR_RED+"The presence of humans has awoken the mighty Cthulhu from his slumber!")
call PlayThematicMusic("Sound\\Music\\mp3Music\\Doom.mp3")
call cineMode(true)
call endCineModeTimed(6)
loop
exitwhen i > 11
call UnitShareVision(.darklord, Player(i), true)
set i = i+1
endloop
call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, 1800, 0)
call SetCameraTargetController(.darklord, 0, 0, false)
call .setTarget()
call TriggerRegisterUnitEvent(t, .darklord, EVENT_UNIT_DEATH)
call TriggerAddCondition(t, Condition(function thistype.onDeath))
call TimerStart(.cooldown, 10, true, function thistype.onConvertUnit)
call TimerStart(.tick, 3, true, function thistype.update)
set t = null
endmethod
static method onEnter takes nothing returns boolean
local unit target = GetTriggerUnit()
if GetUnitAbilityLevel(target, 'Avul') == 0 and GetUnitAbilityLevel(target, 'Aloc') == 0 then
call .spawn()
endif
set target = null
return false
endmethod
static method startEvent takes nothing returns nothing
local real x = 0
local real y = 0
local integer roll = GetRandomInt(0, 3)
if roll == 0 then
set x = GetRandomReal(GetRectMinX(gg_rct_NorthAtlantic), GetRectMaxX(gg_rct_NorthAtlantic))
set y = GetRandomReal(GetRectMinY(gg_rct_NorthAtlantic), GetRectMaxY(gg_rct_NorthAtlantic))
elseif roll == 1 then
set x = GetRandomReal(GetRectMinX(gg_rct_SouthAtlantic), GetRectMaxX(gg_rct_SouthAtlantic))
set y = GetRandomReal(GetRectMinY(gg_rct_SouthAtlantic), GetRectMaxY(gg_rct_SouthAtlantic))
elseif roll == 2 then
set x = GetRandomReal(GetRectMinX(gg_rct_PacificOcean), GetRectMaxX(gg_rct_PacificOcean))
set y = GetRandomReal(GetRectMinY(gg_rct_PacificOcean), GetRectMaxY(gg_rct_PacificOcean))
else
set x = GetRandomReal(GetRectMinX(gg_rct_IndianOcean), GetRectMaxX(gg_rct_IndianOcean))
set y = GetRandomReal(GetRectMinY(gg_rct_IndianOcean), GetRectMaxY(gg_rct_IndianOcean))
endif
set .rlyeh = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), 'rlye', x, y, 0)
call DestroyEffect(AddSpecialEffectTarget("Objects\\Spawnmodels\\Naga\\NagaDeath\\NagaDeath.mdl", .rlyeh, "origin"))
call MoveRectTo(.rct, x, y)
call RegionAddRect(.r, .rct)
call EnableTrigger(.spawnTrigger)
call UnitShareVision(.rlyeh, GetLocalPlayer(), true)
call PingMinimap(x, y, 10)
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, COLOR_GREEN+"BREAKING NEWS:|r A mysterious city has surfaced in the middle of the ocean. Who knows what secrets it might hide?")
call StartSound(gg_snd_Warning)
call TimerStart(.expire, 220, false, function thistype.onEventTimeout)
endmethod
static method onConsiderEvent takes nothing returns nothing
if .darklord == null and .rlyeh == null and not .dead then
if GetRandomInt(0, 4) == 1 then
call .startEvent()
endif
endif
endmethod
static method onInit takes nothing returns nothing
local integer i = 0
set .subjects = CreateGroup()
set .cooldown = CreateTimer()
set .tick = CreateTimer()
set .expire = CreateTimer()
set .r = CreateRegion()
set .rct = Rect(-600, -600, 600, 600)
set .spawnTrigger = CreateTrigger()
call TriggerRegisterEnterRegion(.spawnTrigger, .r, null)
call TriggerAddCondition(.spawnTrigger, Condition(function thistype.onEnter))
endmethod
endstruct
Finally, here are the functions controling the cinematic functions:
JASS:
function setGameCamera takes boolean flag returns nothing
if flag then
call ResetToGameCamera(1)
call TimerStart(cameraTimer, 0.04, true, function onLoop)
else
call PauseTimer(cameraTimer)
endif
endfunction
function cineMode takes boolean flag returns nothing
call setGameCamera(not flag)
call EnableUserControl(not flag)
call EnableOcclusion(not flag)
call ShowInterface(not flag, 1.5)
call setGameCamera(not flag)
endfunction
private function onEndCineMode takes nothing returns nothing
call ReleaseTimer(GetExpiredTimer())
call cineMode(false)
endfunction
function endCineModeTimed takes real duration returns nothing
call TimerStart(NewTimer(), duration, false, function onEndCineMode)
endfunction
+rep to anyone who can help me out!