huykho192
The Warrior of Light
mọi người sem giúp sao cái spell này, trong máy nhà mình bản 1.21 thì dùng bình thường save map bình thường ko báo lỗi, nhưng khi ra ngoài quán nét bản 1.24 thì báo lỗi ầm ầm ko vào được cả map, phải vào WE tắt cái spell này đi thì mới vô được



Mã:
//**************************************
//**************************************
//
// Stone Wall
// 1.4
//
// Made for the Spell Making Session 04
// at wc3campaigns.net
//
// By: Nicholas Fraser (Vuen)
// [email protected]
//
// This spell follows the JESP standard.
//
//**************************************
//**************************************
//===========================================================================
//===========================================================================
//===========================================================================
// CONFIGURATION
//===========================================================================
//===========================================================================
//===========================================================================
//*********************
// REFERENCES
//*********************
function StoneWall_GameCache takes nothing returns gamecache
//if your map already has a gamecache,
//uncomment this line and put the appropriate variable:
//return udg_GameCache
//otherwise, leave this function as is.
if bj_lastCreatedGameCache == null then
set bj_lastCreatedGameCache = InitGameCache("StoneWall.w3v")
endif
return bj_lastCreatedGameCache
endfunction
//The rawcode for the Stone Wall ability
constant function StoneWall_SpellAbility takes nothing returns integer
return 'A020'
endfunction
//*********************
// STATS
//*********************
//Length of wall
function StoneWall_Length takes integer level returns real
return 1024.0 + 170.66 * level
endfunction
//Whether the wall blocks flying units
function StoneWall_BlocksAir takes integer level returns boolean
return false
endfunction
//Whether the wall blocks visibility
function StoneWall_BlocksVisibility takes integer level returns boolean
return true
endfunction
//Whether the spell is channeled (to turn off channeling
// you will also need to set the Follow Through Time
// on the ability to 1.)
function StoneWall_IsChannel takes integer level returns boolean
return true
endfunction
//Duration of wall (ignored if spell is channeled;
// channeling duration is set on the ability under
// Follow Through Time.)
function StoneWall_Duration takes integer level returns real
return 5.0 * level
endfunction
//*********************
// EFFECTS
//*********************
//Change this to change the height of the wall
//Note that this is not the actual height of the wall, it
// is a constant used in setting the height
function StoneWall_PeakHeightStep takes integer level returns real
return 30.0
endfunction
//The ground texture applied to the wall
function StoneWall_UberSplat takes location loc, integer level returns string
return "OMED" //Orc Medium
//Try this for an undead "Black Wall":
// "ULAR" //Undead Large
endfunction
//Make sure you use double backslashes, \\, instead of single
// backslashes, \, for the paths:
//Used along the base of the wall
function StoneWall_BaseEffect takes integer level returns string
return "war3mapImported\\CloudOfDust.mdx"
//The original cloud of fog; use this for cyan dust instead:
//"Abilities\\Spells\\Human\\CloudOfFog\\CloudOfFog.mdl"
endfunction
//The sound played when the wall is raised
function StoneWall_SoundRaise takes nothing returns string
return "Abilities\\Spells\\Orc\\EarthQuake\\EarthquakeRock.wav"
endfunction
//The sound played when the wall is lowered
function StoneWall_SoundLower takes nothing returns string
return "Abilities\\Spells\\NightElf\\Barkskin\\BarkSkinTarget1.wav"
endfunction
//*********************
// TWEAKS
//*********************
//For all practical purposes these values do not need to be
// changed.
//Sets the spacing of the peaks, where effects and blockers
// are placed. If this is set too high, the wall will have
// gaps in it!
function StoneWall_PeakSpacing takes integer level returns real
return 50.0
endfunction
//The radius of the terrain deformation on each peak.
function StoneWall_PeakRadius takes integer level returns real
return 175.0
endfunction
//The randomness to apply to the location of the terrain deformations.
function StoneWall_PeakRandomness takes integer level returns real
return 45.0
endfunction
//The amount of peaks from each cloud and splat to the next
function StoneWall_PeakEffectSpacing takes integer level returns integer
return GetRandomInt(4,6)
endfunction
//This is the end of the configuration options. Only
// modify code beyond this point if you know what you
// are doing!
//===========================================================================
//===========================================================================
//===========================================================================
// CODE
//===========================================================================
//===========================================================================
//===========================================================================
//Global utility functions
function StoneWall_H2I takes handle h returns integer
return h
return 0
endfunction
function StoneWall_GlobalTimer takes nothing returns timer
return GetStoredInteger(StoneWall_GameCache(), "StoneWall", "GlobalTimer")
return null
endfunction
function StoneWall_GetPathingBlockerType takes integer level returns integer
if StoneWall_BlocksAir(level) then
return 'YTfc' //large both
endif
return 'YTpc' //large ground
endfunction
function StoneWall_GetSightBlockerType takes integer level returns integer
return 'Ytlc' //large
endfunction
//Variables attached to timers
function StoneWall_GetLocation takes string tref, integer i returns location
return GetStoredInteger(StoneWall_GameCache(), tref, "Location" + I2S(i))
return null
endfunction
function StoneWall_GetPathingBlocker takes string tref, integer i returns destructable
return GetStoredInteger(StoneWall_GameCache(), tref, "PathingBlocker" + I2S(i))
return null
endfunction
function StoneWall_GetSightBlocker takes string tref, integer i returns destructable
return GetStoredInteger(StoneWall_GameCache(), tref, "SightBlocker" + I2S(i))
return null
endfunction
function StoneWall_GetSplat takes string tref, integer i returns ubersplat
return GetStoredInteger(StoneWall_GameCache(), tref, "Splat" + I2S(i))
return null
endfunction
function StoneWall_GetEffect takes string tref, string str, integer i returns effect
return GetStoredInteger(StoneWall_GameCache(), tref, str + I2S(i))
return null
endfunction
function StoneWall_GetDeform takes string tref, integer actionnum, integer i returns terraindeformation
return GetStoredInteger(StoneWall_GameCache(), tref, "Crater" + I2S(actionnum) + "_" + I2S(i))
return null
endfunction
function StoneWall_GetRect takes string tref returns rect
return GetStoredInteger(StoneWall_GameCache(), tref, "Rect")
return null
endfunction
function StoneWall_GetCaster takes string tref returns unit
return GetStoredInteger(StoneWall_GameCache(), tref, "Caster")
return null
endfunction
//A wall timer elapsed. (This happens every 0.1 seconds for each wall.)
function StoneWall_TimerElapsed takes nothing returns nothing
local timer t
local string tref
local unit caster
local location loc
local boolean stop = false
local integer i
local integer iend
local integer level
local integer action
local integer actionnum
local sound snd
set t = GetExpiredTimer()
set tref = I2S(StoneWall_H2I(t))
set caster = StoneWall_GetCaster(tref)
set level = GetStoredInteger(StoneWall_GameCache(), tref, "Level")
set action = GetStoredInteger(StoneWall_GameCache(), tref, "Action")
set actionnum = GetStoredInteger(StoneWall_GameCache(), tref, "ActionNum")
if action == 1 then //Rising
set i = GetStoredInteger(StoneWall_GameCache(), tref, "Start")
set iend = GetStoredInteger(StoneWall_GameCache(), tref, "End")
loop
exitwhen i >= iend
set loc = StoneWall_GetLocation(tref,i)
call StoreInteger( StoneWall_GameCache(), tref, "Crater" + I2S(actionnum) + "_" + I2S(i), StoneWall_H2I(TerrainDeformCrater( GetLocationX(loc), GetLocationY(loc), StoneWall_PeakRadius(level), -StoneWall_PeakHeightStep(level)/(actionnum+1), 90, true)) )
set i = i + 1
endloop
set actionnum = actionnum + 1
if actionnum > 10 then
set action = 2
set actionnum = 0
endif
elseif action == 2 then //Standing
set actionnum = actionnum + 1
if actionnum < 5 then
//make sure the wall stands for a little while to let terrain deforms finish
elseif StoneWall_IsChannel(level) then
if caster == null then //channeling caster was abnormally removed - end wall and flush caster data
set stop = true
call FlushStoredMission(StoneWall_GameCache(), "StoneWall" + I2S(GetStoredInteger(StoneWall_GameCache(), tref, "Caster")))
elseif GetStoredBoolean(StoneWall_GameCache(), tref, "Stop") then
set stop = true
endif
elseif TimerGetElapsed(StoneWall_GlobalTimer()) > StoneWall_Duration(level) + GetStoredReal(StoneWall_GameCache(), tref, "Time") then //out of time
set stop = true
endif
if stop then
set i = GetStoredInteger(StoneWall_GameCache(), tref, "Start")
set iend = GetStoredInteger(StoneWall_GameCache(), tref, "End")
loop
exitwhen i >= iend
set loc = StoneWall_GetLocation(tref,i)
call RemoveDestructable( StoneWall_GetPathingBlocker(tref,i) )
if StoneWall_BlocksVisibility(level) then
call RemoveDestructable( StoneWall_GetSightBlocker(tref,i) )
endif
call DestroyEffect( StoneWall_GetEffect(tref,"Cloud",i) )
set actionnum = 0
loop
call TerrainDeformStop(StoneWall_GetDeform(tref, actionnum, i), 0)
set actionnum = actionnum + 1
exitwhen actionnum > 10
endloop
set i = i + 1
endloop
set loc = StoneWall_GetLocation(tref,0)
set snd = CreateSound( StoneWall_SoundLower(), false, true, true, 10, 10, "SpellsEAX" )
call SetSoundPosition( snd, GetLocationX(loc), GetLocationY(loc), 0)
call SetSoundVolume(snd, 95)
call SetSoundDistanceCutoff(snd, 2500)
call StartSound(snd)
call KillSoundWhenDone(snd)
set snd = null
set action = 3
set actionnum = 0
endif
elseif action == 3 then //Falling
set i = GetStoredInteger(StoneWall_GameCache(), tref, "Start")
set iend = GetStoredInteger(StoneWall_GameCache(), tref, "End")
loop
exitwhen i >= iend
set loc = StoneWall_GetLocation(tref,i)
call StoreInteger( StoneWall_GameCache(), tref, "Crater" + I2S(actionnum) + "_" + I2S(i), StoneWall_H2I(TerrainDeformCrater( GetLocationX(loc), GetLocationY(loc), StoneWall_PeakRadius(level), StoneWall_PeakHeightStep(level)/(actionnum+1), 90, true)) )
if actionnum == 0 then
//this is done here instead of the stop action to synchronize it with the terrain drop
call DestroyUbersplat( StoneWall_GetSplat(tref,i) )
endif
set i = i + 1
endloop
set actionnum = actionnum + 1
//For some odd reason, hills do not deform as much as craters. Blame Blizzard.
if actionnum > 8 then
set action = 4
set actionnum = 0
endif
elseif action == 4 then
set actionnum = actionnum + 1
if actionnum < 5 then
//make sure the wall stands for a little while to let terrain deforms finish
else
//Wall is completely done; flush everything.
set i = GetStoredInteger(StoneWall_GameCache(), tref, "Start")
set iend = GetStoredInteger(StoneWall_GameCache(), tref, "End")
loop
exitwhen i >= iend
set loc = StoneWall_GetLocation(tref,i)
call RemoveLocation(loc)
set actionnum = 0
loop
call TerrainDeformStop(StoneWall_GetDeform(tref, actionnum, i), 0)
set actionnum = actionnum + 1
exitwhen actionnum > 10
endloop
set i = i + 1
endloop
call DestroyTimer(t)
call FlushStoredMission(StoneWall_GameCache(), tref)
//set t = null
set tref = null
set snd = null
set caster = null
set loc = null
return
endif
endif
call StoreInteger( StoneWall_GameCache(), tref, "Action", action )
call StoreInteger( StoneWall_GameCache(), tref, "ActionNum", actionnum )
//set t = null
set tref = null
set snd = null
set caster = null
set loc = null
endfunction
//A unit cast Stone Wall.
function StoneWall_SpellCast takes nothing returns nothing
local integer level
local real angle
local unit caster
local timer t
local string tref
local location source
local location target
local location loc
local location locrandom
local integer i
local integer e = 0
local ubersplat splat
local sound snd
local rect bounds
if not(GetSpellAbilityId() == StoneWall_SpellAbility()) then
return
endif
set caster = GetSpellAbilityUnit()
set level = GetUnitAbilityLevelSwapped(StoneWall_SpellAbility(), caster)
set source = GetUnitLoc(caster)
set target = GetSpellTargetLoc()
set angle = AngleBetweenPoints(source, target) + 90
set bounds = GetWorldBounds()
//Create our timer. All variables related to the wall
// will be attached to it.
set t = CreateTimer()
set tref = I2S(StoneWall_H2I(t))
call TimerStart(t, 0.1, true, function StoneWall_TimerElapsed)
//Here we create the wall by projecting and storing
// the location of each peak, and creating a pathing
// blocker at each peak.
set i = -R2I(StoneWall_Length(level) / 2 / StoneWall_PeakSpacing(level))
//store lowest integer (to start looping)
call StoreInteger( StoneWall_GameCache(), tref, "Start", i )
loop
exitwhen StoneWall_PeakSpacing(level) * i * 2 > StoneWall_Length(level)
//Here we have two locations. The 'loc's lie in a perfect straight line
// to lay out the pathing blockers, ensuring no holes. The 'locrandom's
// are randomly shifted about to make the deformation appear more natural.
set loc = PolarProjectionBJ(target, StoneWall_PeakSpacing(level) * i, angle)
set locrandom = Location(GetLocationX(loc) + GetRandomReal(-StoneWall_PeakRandomness(level), StoneWall_PeakRandomness(level)), GetLocationY(loc) + GetRandomReal(-StoneWall_PeakRandomness(level), StoneWall_PeakRandomness(level)))
//check if loc and locrandom are on the map
if RectContainsLoc(bounds, loc) and RectContainsLoc(GetWorldBounds(), locrandom) then
//store the 'locrandom's for deformation
call StoreInteger( StoneWall_GameCache(), tref, "Location" + I2S(i), StoneWall_H2I(locrandom) )
//create pathing blockers along the 'loc's
call StoreInteger( StoneWall_GameCache(), tref, "PathingBlocker" + I2S(i), StoneWall_H2I(CreateDestructableLoc( StoneWall_GetPathingBlockerType(level), loc, GetRandomDirectionDeg(), 1, 0 )) )
if StoneWall_BlocksVisibility(level) then
call StoreInteger( StoneWall_GameCache(), tref, "SightBlocker" + I2S(i), StoneWall_H2I(CreateDestructableLoc( StoneWall_GetSightBlockerType(level), loc, GetRandomDirectionDeg(), 1, 0 )) )
endif
//create splat, effect and sound along the 'locrandom's
set splat = CreateUbersplat(GetLocationX(locrandom), GetLocationY(locrandom), StoneWall_UberSplat(locrandom,level), 255, 255, 255, 255, false, false)
call StoreInteger( StoneWall_GameCache(), tref, "Splat" + I2S(i), StoneWall_H2I(splat) )
if e == 0 then
call StoreInteger( StoneWall_GameCache(), tref, "Cloud" + I2S(i), StoneWall_H2I(AddSpecialEffectLoc( StoneWall_BaseEffect(level), locrandom )) )
call SetUbersplatRenderAlways( splat, true )
set snd = CreateSound( StoneWall_SoundRaise(), false, true, true, 10, 10, "SpellsEAX" )
call SetSoundPosition( snd, GetLocationX(locrandom), GetLocationY(locrandom), 0)
call SetSoundVolume(snd, 127)
call SetSoundDistanceCutoff(snd, 2500)
call StartSound(snd)
call KillSoundWhenDone(snd)
set e = StoneWall_PeakEffectSpacing(level)
else
//yes, i realize i'm creating unnecessary splats, but they need to be created
// otherwise it doesn't work. no splats leak, so it's not a problem.
call SetUbersplatRenderAlways( splat, false )
endif
set e = e - 1
endif
call RemoveLocation(loc) //since it's no longer needed
set i = i + 1
endloop
call StoreInteger( StoneWall_GameCache(), tref, "Caster", StoneWall_H2I(caster) )
if StoneWall_IsChannel(level) then
call StoreInteger( StoneWall_GameCache(), "StoneWall" + I2S(StoneWall_H2I(caster)), "Timer", StoneWall_H2I(t) )
endif
call StoreInteger( StoneWall_GameCache(), tref, "End", i )
call StoreInteger( StoneWall_GameCache(), tref, "Level", level )
call StoreInteger( StoneWall_GameCache(), tref, "Action", 1 )
call StoreInteger( StoneWall_GameCache(), tref, "ActionNum", 0 )
call StoreReal ( StoneWall_GameCache(), tref, "Time", TimerGetElapsed(StoneWall_GlobalTimer()) )
call RemoveRect(bounds)
set bounds = null
set caster = null
//set t = null
set tref = null
call RemoveLocation(source)
call RemoveLocation(target)
set source = null
set target = null
set loc = null
set locrandom = null
set splat = null
set snd = null
endfunction
//A unit stopped channeling.
function StoneWall_SpellEnd takes nothing returns nothing
local integer tid
if not(GetSpellAbilityId() == StoneWall_SpellAbility()) then
return
endif
//If the unit never started casting it or if the spell is
// not channeling, nothing will be attached.
set tid = GetStoredInteger(StoneWall_GameCache(), "StoneWall" + I2S(StoneWall_H2I(GetSpellAbilityUnit())), "Timer")
if not(tid == 0) then
call StoreBoolean( StoneWall_GameCache(), I2S(tid), "Stop", true )
call FlushStoredMission(StoneWall_GameCache(), "StoneWall" + I2S(StoneWall_H2I(GetSpellAbilityUnit())))
endif
endfunction
//Initialize the spell.
function StoneWall_Go takes nothing returns nothing
local trigger castDetector
local trigger endDetector
local timer permanentTimer
local sound snd
//Create Triggers:
set castDetector = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( castDetector, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddAction( castDetector, function StoneWall_SpellCast )
set endDetector = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( endDetector, EVENT_PLAYER_UNIT_SPELL_ENDCAST )
call TriggerAddAction( endDetector, function StoneWall_SpellEnd )
//Create Other Objects:
set permanentTimer = CreateTimer()
call TimerStart( permanentTimer, 10000000.00, false, null )
call StoreInteger(StoneWall_GameCache(), "StoneWall", "GlobalTimer", StoneWall_H2I(permanentTimer))
//Preload an Ubersplat for each level, since the filename depends on the tileset
call DestroyUbersplat(CreateUbersplat(0.0, 0.0, StoneWall_UberSplat(null,1), 255, 255, 255, 255, false, false))
call DestroyUbersplat(CreateUbersplat(0.0, 0.0, StoneWall_UberSplat(null,2), 255, 255, 255, 255, false, false))
call DestroyUbersplat(CreateUbersplat(0.0, 0.0, StoneWall_UberSplat(null,3), 255, 255, 255, 255, false, false))
call DestroyUbersplat(CreateUbersplat(0.0, 0.0, StoneWall_UberSplat(null,4), 255, 255, 255, 255, false, false))
call DestroyUbersplat(CreateUbersplat(0.0, 0.0, StoneWall_UberSplat(null,5), 255, 255, 255, 255, false, false))
//Preplay Sounds, since for some reason preloading doesn't work
call TriggerSleepAction(0)
set snd = CreateSound( StoneWall_SoundRaise(), false, false, false, 10, 10, "SpellsEAX" )
call SetSoundVolume(snd, 0)
call StartSound(snd)
call KillSoundWhenDone(snd)
set snd = CreateSound( StoneWall_SoundLower(), false, false, false, 10, 10, "SpellsEAX" )
call SetSoundVolume(snd, 0)
call StartSound(snd)
call KillSoundWhenDone(snd)
set castDetector = null
set endDetector = null
set permanentTimer = null
set snd = null
endfunction
function InitTrig_StoneWall takes nothing returns nothing
set gg_trg_StoneWall = CreateTrigger()
call TriggerAddAction( gg_trg_StoneWall, function StoneWall_Go )
//Preload:
call Preload(StoneWall_BaseEffect(1))
call Preload(StoneWall_BaseEffect(2))
call Preload(StoneWall_BaseEffect(3))
call Preload(StoneWall_BaseEffect(4))
call Preload(StoneWall_BaseEffect(5))
call Preload(StoneWall_SoundRaise())
call Preload(StoneWall_SoundLower())
endfunction


