scope OrganicHemisection initializer init import Statistics import Units import Cinematic import SoundControl import RegisterPlayerUnitEvent import Players struct DuplicateDat real uX real uY real face real timeLeft unit image0 unit image1 unit image2 unit tU end constant string IMAGE_SOUND = "Abilities\\Spells\\Orc\\MirrorImage\\MirrorImage.wav" constant integer HEMISECTION_ID = 'A00G' constant integer BEAST_ILLUSION_ID = 'h00E' constant real DURATION = .5 constant real OFFSET = 64. constant real PHASE_OFF = 16. constant real CLOCK_PERIOD = 1. / 30. constant real PHASE_MULTIPLIER = 16. * bj_PI DuplicateDat array ddStack integer ddIndex = -1 timer clock = CreateTimer() function ddPeriodic takes nothing returns nothing integer index = 0 integer id player owner DuplicateDat tempDat real phaseOffset real angle real life loop exitwhen index > ddIndex tempDat = ddStack[index] phaseOffset = PHASE_OFF* Cos(tempDat.timeLeft * PHASE_MULTIPLIER) angle = tempDat.face * bj_DEGTORAD + bj_PI / 2. SetUnitX(tempDat.image0, tempDat.uX + (OFFSET / 2. + phaseOffset)*Cos(angle)) SetUnitX(tempDat.image1, tempDat.uX + ( phaseOffset)*Cos(angle)) SetUnitX(tempDat.image2, tempDat.uX + (OFFSET / -2. + phaseOffset)*Cos(angle)) SetUnitY(tempDat.image0, tempDat.uY + (OFFSET / 2. + phaseOffset)*Sin(angle)) SetUnitY(tempDat.image1, tempDat.uY + ( phaseOffset)*Sin(angle)) SetUnitY(tempDat.image2, tempDat.uY + (OFFSET / -2. + phaseOffset)*Sin(angle)) tempDat.timeLeft = tempDat.timeLeft - CLOCK_PERIOD if tempDat.timeLeft <= 0. then RemoveUnit(tempDat.image0) RemoveUnit(tempDat.image1) RemoveUnit(tempDat.image2) Statistics.beastsAlive++ owner = GetOwningPlayer(tempDat.tU) id = GetPlayerId(owner) Units.hero[id] = CreateUnit(owner, Units.LESSER_BEAST_ID, tempDat.uX + OFFSET*Cos(tempDat.face * bj_DEGTORAD - bj_PI / 2.), tempDat.uY + OFFSET*Sin(tempDat.face * bj_DEGTORAD - bj_PI / 2.), tempDat.face) Units.subHero[id] = CreateUnit(owner, Units.LESSER_BEAST_ID, tempDat.uX + OFFSET*Cos(tempDat.face * bj_DEGTORAD + bj_PI / 2.), tempDat.uY + OFFSET*Sin(tempDat.face * bj_DEGTORAD + bj_PI / 2.), tempDat.face) Units.initializeBeast(Units.hero[id]) Units.initializeBeast(Units.subHero[id]) if Players.locl == owner and not Cinematic.enabled then SelectUnit(Units.hero[id], true) SelectUnit(Units.subHero[id], true) end life = GetWidgetLife(tempDat.tU) / 2. SetWidgetLife(Units.hero[id], life) SetWidgetLife(Units.subHero[id], life) RemoveUnit(tempDat.tU) destroy tempDat ddStack[index] = ddStack[ddIndex] ddIndex-- index-- if ddIndex == -1 then PauseTimer(clock) end end index++ end end function act takes nothing returns nothing DuplicateDat dd player owner if GetSpellAbilityId() == HEMISECTION_ID then dd = new DuplicateDat() dd.tU = GetTriggerUnit() dd.timeLeft = DURATION owner = GetOwningPlayer(dd.tU) dd.uX = GetUnitX(dd.tU) dd.uY = GetUnitY(dd.tU) dd.face = GetUnitFacing(dd.tU) dd.image0 = CreateUnit(owner, BEAST_ILLUSION_ID, dd.uX + (OFFSET / 2.)*Cos(dd.face * bj_DEGTORAD - bj_PI / 2.), dd.uY + (OFFSET / 2.)*Sin(dd.face * bj_DEGTORAD - bj_PI / 2.), dd.face) dd.image1 = CreateUnit(owner, BEAST_ILLUSION_ID, dd.uX, dd.uY, dd.face) dd.image2 = CreateUnit(owner, BEAST_ILLUSION_ID, dd.uX + (OFFSET / 2.)*Cos(dd.face * bj_DEGTORAD + bj_PI / 2.), dd.uY + (OFFSET / 2.)*Sin(dd.face * bj_DEGTORAD + bj_PI / 2.), dd.face) SoundControl.play3D(IMAGE_SOUND, 1., dd.uX, dd.uY, 0.) SetUnitVertexColor(dd.image0, 255, 255, 255, 128) SetUnitVertexColor(dd.image1, 255, 255, 255, 128) SetUnitVertexColor(dd.image2, 255, 255, 255, 128) SetUnitTimeScale(dd.image0, 0.) SetUnitTimeScale(dd.image1, 0.) SetUnitTimeScale(dd.image2, 0.) Units.dischargeBall(dd.tU) Units.dischargeBall(dd.tU) Units.dischargeBall(dd.tU) SetUnitFlyHeight(dd.tU, 1000., 0.) SetUnitVertexColor(dd.tU, 0, 0, 0, 0) PauseUnit(dd.tU, true) ddIndex++ ddStack[ddIndex] = dd if ddIndex == 0 then TimerStart(clock, CLOCK_PERIOD, true, function ddPeriodic) end end end function init takes nothing returns nothing registerPlayerUnitEvent(EVENT_PLAYER_UNIT_SPELL_EFFECT, function act) SoundControl.preload(IMAGE_SOUND) end endscope