//TESH.scrollpos=998
//TESH.alwaysfold=0
//*******************************************************************************************
//*
//* Handle Variables Functions
//*
//* -------------------------------
//* Enables the usage of game cache
//* to transphere local variables
//* between functions
//* -------------------------------
//*
//* Requires:
//* ¯¯¯¯¯¯¯¯¯
//* - Global variable with type "Game Cache" and name "cache"
//* Note that this codes MUST BE PLACED BEFORE ANYTHING here.
//**************************************************************************************************
function LocalVars takes nothing returns gamecache
if udg_cache==null then
set udg_cache=InitGameCache("cache")
endif
return udg_cache
endfunction
// START OF HANDLE <=> INDEX FUNCTIONS //
//-------------------------------------------------
function H2I takes handle h returns integer
return h
return 0
endfunction
function H2U takes handle h returns unit
return h
return null
endfunction
function H2E takes handle h returns effect
return h
return null
endfunction
function H2L takes handle h returns lightning
return h
return null
endfunction
function I2H takes integer i returns handle
return i
return null
endfunction
function I2U takes integer i returns unit
return i
return null
endfunction
function I2E takes integer i returns effect
return i
return null
endfunction
function I2T takes integer i returns timer
return i
return null
endfunction
// -------------
// SET Functions
// -------------
function SetHandleInt takes handle subject, string name, integer value returns nothing
if value==0 then
call FlushStoredInteger(LocalVars(),I2S(H2I(subject)),name)
else
call StoreInteger(LocalVars(), I2S(H2I(subject)), name, value)
endif
endfunction
//-------------------------------------------------
function SetHandleReal takes handle subject, string name, real value returns nothing
if value==0 then
call FlushStoredReal(LocalVars(), I2S(H2I(subject)), name)
else
call StoreReal(LocalVars(), I2S(H2I(subject)), name, value)
endif
endfunction
//-------------------------------------------------
function SetHandleHandle takes handle subject, string name, handle value returns nothing
if value==null then
call FlushStoredInteger(LocalVars(),I2S(H2I(subject)),name)
else
call StoreInteger(LocalVars(), I2S(H2I(subject)), name, H2I(value))
endif
endfunction
//-------------------------------------------------
function SetHandleString takes handle subject, string name, string value returns nothing
if value==null then
call FlushStoredString(LocalVars(), I2S(H2I(subject)), name)
else
call StoreString(LocalVars(), I2S(H2I(subject)), name, value)
endif
endfunction
//-------------------------------------------------
function SetHandleBoolean takes handle subject, string name, boolean value returns nothing
if value==false then
call FlushStoredBoolean(LocalVars(),I2S(H2I(subject)),name)
else
call StoreBoolean(LocalVars(), I2S(H2I(subject)), name, value)
endif
endfunction
// -------------
// GET Functions
// -------------
function GetHandleBoolean takes handle subject, string name returns boolean
return GetStoredBoolean(LocalVars(), I2S(H2I(subject)), name)
endfunction
//-------------------------------------------------
function GetHandleInt takes handle subject, string name returns integer
return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
endfunction
//-------------------------------------------------
function GetHandleReal takes handle subject, string name returns real
return GetStoredReal(LocalVars(), I2S(H2I(subject)), name)
endfunction
//-------------------------------------------------
function GetHandleHandle takes handle subject, string name returns handle
return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
return null
endfunction
//-------------------------------------------------
function FlushHandleLocals takes handle subject returns nothing
call FlushStoredMission(LocalVars(), I2S(H2I(subject)) )
endfunction
//-------------------------------------------------
function GetHandleString takes handle subject, string name returns string
return GetStoredString(LocalVars(), I2S(H2I(subject)), name)
endfunction
//-------------------------------------------------
function GetHandleUnit takes handle subject, string name returns unit
return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
return null
endfunction
//-------------------------------------------------
function GetHandleTimer takes handle subject, string name returns timer
return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
return null
endfunction
//-------------------------------------------------
function GetHandleTrigger takes handle subject, string name returns trigger
return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
return null
endfunction
//-------------------------------------------------
function GetHandleEffect takes handle subject, string name returns effect
return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
return null
endfunction
//-------------------------------------------------
function GetHandleLoc takes handle subject, string name returns location
return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
return null
endfunction
//-------------------------------------------------
function GetHandleLocation takes handle subject, string name returns location
return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
return null
endfunction
//-------------------------------------------------
function GetHandleGroup takes handle subject, string name returns group
return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
return null
endfunction
//-------------------------------------------------
function GetHandleLight takes handle subject, string name returns lightning
return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
return null
endfunction
//-------------------------------------------------
function GetHandleSound takes handle subject, string name returns sound
return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
return null
endfunction
//-------------------------------------------------
function GetHandleLightning takes handle subject, string name returns lightning
return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
return null
endfunction
//-------------------------------------------------
function GetHandleWidget takes handle subject, string name returns widget
return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
return null
endfunction
//-------------------------------------------------
function GetHandleItem takes handle subject, string name returns item
return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
return null
endfunction
//-------------------------------------------------
function GetHandleTextTag takes handle subject, string name returns texttag
return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
return null
endfunction
//-------------------------------------------------
function GetHandleTriggerAction takes handle subject, string name returns triggeraction
return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
return null
endfunction
//-------------------------------------------------
function GetHandleQuestItem takes handle subject, string name returns questitem
return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
return null
endfunction
// END OF HANDLE <=> INDEX FUNCTIONS //
// -----------------------------
// Begin of MoCo Functions
// -----------------------------
function MoCo_PreloadSounds takes nothing returns nothing
call Preload("marine-pop-sky-pop-.mp3")
call Preload("level-complete.mp3")
call Preload("boss-battle.mp3")
call SetAltMinimapIcon("war3mapPreview.tga")
endfunction
// Tag Creation | displays floating text on unit
function MoCo_CreateTagOnUnit takes unit TargetUnit, string Text returns nothing
local texttag t = CreateTextTag()
local string value
set Text = "|c00" + udg_PlayerColors[GetConvertedPlayerId(GetOwningPlayer(TargetUnit))] + Text + "|r"
call SetTextTagColor(t, 182, 91, 234, 255)
// call SetTextTagText(t, Text, 0.025)
call SetTextTagText(t, Text, 0.0184)
// call SetTextTagTextBJ(t, Text, 8.00 )
call SetTextTagPos(t, GetUnitX(TargetUnit), GetUnitY(TargetUnit), 0.00)
call SetTextTagVelocity(t, 0, 0.03)
call SetTextTagVisibility(t, true)
call SetTextTagFadepoint(t, 3)
call SetTextTagLifespan(t, 4)
call SetTextTagPermanent(t, false)
set t = null
endfunction
function MoCo_CreateDamageTagOnUnit takes unit TargetUnit, integer Damage, boolean isCritical, boolean onRage returns nothing
local texttag t = CreateTextTag()
local string value
local real textSize
// scale size depending of the amount of damage dealt
set textSize = 0.018 + ((Damage/50) * 0.001)
set value = I2S(Damage)
call SetTextTagColor(t, 255, 0, 0, 255)
// Crits
if ( isCritical == true) then
set value = value+"!"
endif
// onRage
if ( onRage == true) then
call SetTextTagColor(t, 255, 112, 49, 255)
endif
call SetTextTagText(t, value, textSize)
call SetTextTagVelocity(t, 0, 0.03)
call SetTextTagPos(t, GetUnitX(TargetUnit), GetUnitY(TargetUnit), 128.00)
call SetTextTagVisibility(t, true)
call SetTextTagFadepoint(t, 3)
call SetTextTagLifespan(t, 4)
call SetTextTagPermanent(t, false)
set t = null
endfunction
// Displays a message on screen from a specific unit
function MoCo_DisplayUnitMessage takes unit TalkingUnit, string Message, real Duration, player SpecificPlayer, boolean ShowAll returns nothing
local string UnitName
// Talking unit has to be alive of course
if ( IsUnitAliveBJ(TalkingUnit) == true ) then
// Set Unit's Name (use hero name if it's a hero)
if ( IsUnitType(TalkingUnit, UNIT_TYPE_HERO) == true ) then
set UnitName = GetHeroProperName(TalkingUnit)
else
set UnitName = GetUnitName(TalkingUnit)
endif
// Set Unit's Name Color and add a :
set UnitName = "|cff" + udg_PlayerColors[GetConvertedPlayerId(GetOwningPlayer(TalkingUnit))] + UnitName + ":|r "
// If no player is specified, show to all players
if ShowAll == true then
call DisplayTimedTextToForce( udg_Players, Duration, UnitName + Message )
call DisplayTimedTextToForce( udg_Players, Duration, " " )
call SelectUnit( TalkingUnit, false )
else
call DisplayTimedTextToPlayer( SpecificPlayer, 0, 0, Duration, UnitName + Message )
call DisplayTimedTextToPlayer( SpecificPlayer, 0, 0, Duration, " " )
call SelectUnitForPlayerSingle( TalkingUnit, SpecificPlayer )
endif
endif
endfunction
// START OF TIMER ATTACH FUNCTIONS //
function TimerAttach takes timer t, real time, real value, code func returns nothing
call TimerStart(t, value, false, null)
call PauseTimer(t)
call TimerStart(t, time, false, func)
endfunction
// ONLY call on an expired timer.
function GetTimerInt takes timer t returns integer
return R2I(TimerGetRemaining(t) + 0.5)
endfunction
// END OF TIMER ATTACH FUNCTIONS //
// THIS IS JUST A USEFUL FUNCTION FOR DESTROYING EFFECTS //
function DestroyEffectTimedEx takes nothing returns nothing
call DestroyEffect(I2E(GetTimerInt(GetExpiredTimer())))
call DestroyTimer(GetExpiredTimer())
endfunction
function DestroyEffectTimed takes effect e, real d returns nothing
if e != null then
call TimerAttach(CreateTimer(), d, H2I(e), function DestroyEffectTimedEx)
endif
endfunction
// END OF A USEFUL FUNCTION FOR DESTROYING EFFECTS //
// START OF CG CADS CUSTOM FUNCTIONS //
// - PUBLIC FUNCTIONS - //
// Elemental damage bonus table
// Use it to influence damage.
// u1 = casting unit, u2 = target unit.
// That already shown is just example/test code.
function DamageTypeBonus takes string sid, unit u1, unit u2 returns real
local string dt = GetStoredString(udg_gc, sid, "damagetype")
local real db = 1
if dt == "holy" then
if GetUnitRace(u2) == RACE_UNDEAD then
set db = db * 2
endif
elseif dt == "fire" then
set db = db * (1 + GetUnitAbilityLevel(u2, 'A006'))
elseif dt == "dark" then
elseif dt == "arcane" then
endif
return db
endfunction
// Change this to change the created text tags.
// Just delete all the stuff except the function declaration and endfunction
// if you do not want any.
function CauseDamageText takes unit u2, string value, boolean damage returns nothing
local texttag t = CreateTextTag()
// Let's only display damage/healing if it's not 0 (added by MoCo)
if ( not ( value == "0" ) ) then
if damage then // If it is damage...
call SetTextTagColor(t, 255, 26, 26, 255)
else // If it is healing...
call SetTextTagColor(t, 178, 233, 142, 255)
endif
call SetTextTagText(t, value, 0.03)
call SetTextTagPos(t, GetUnitX(u2), GetUnitY(u2), 128.00)
call SetTextTagVelocity(t, 0, 0.03)
call SetTextTagVisibility(t, true)
call SetTextTagFadepoint(t, 2)
call SetTextTagLifespan(t, 3)
call SetTextTagPermanent(t, false)
endif
set t = null
endfunction
// This function controls the random factor. You may wish it to be dynamic.
function GetRandomDamage takes real d, integer id, string sid, unit u1, unit u2 returns real
// return d * GetRandomReal(0.5, 1.5)
return d * 1.0
endfunction
function GetRandomDoTDamage takes real d, string sid, unit u1, unit u2 returns real
return d
endfunction
// - PRIVATE FUNCTIONS - //
// Not recommended to touch anything below here.
// However, you may wish to call some of these for other triggered spells, etc.
function CauseDamage takes unit u1, unit u2, real d, integer aType, integer dType returns nothing
local real h = GetWidgetLife(u2)
local attacktype a = ConvertAttackType(aType)
if d >= 0 then
if dType == -1 then
call UnitDamageTarget(u1, u2, d, true, false, a, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)
else
call UnitDamageTarget(u1, u2, d, true, false, a, ConvertDamageType(dType), WEAPON_TYPE_WHOKNOWS)
endif
call CauseDamageText(u2, I2S(R2I(h - GetWidgetLife(u2))), true)
else
if dType == -1 then
call UnitDamageTarget(u1, u2, d, true, false, a, DAMAGE_TYPE_UNKNOWN, WEAPON_TYPE_WHOKNOWS)
else
call UnitDamageTarget(u1, u2, d, true, false, a, ConvertDamageType(dType), WEAPON_TYPE_WHOKNOWS)
endif
call CauseDamageText(u2, I2S(R2I(GetWidgetLife(u2) - h)), false)
endif
endfunction
// Note: not ALL damage comes through here.
// I think DoTeffectAoE and DoTeffect are the only ones which do not.
function DealDamage takes unit u1, unit u2, integer id, string sid returns nothing
local real d
local integer dType
if HaveStoredReal(udg_gc, sid + ";" + I2S(GetUnitTypeId(u1)), "dmgbase") then
set sid = sid + ";" + I2S(GetUnitTypeId(u1))
endif
set d = GetStoredReal(udg_gc, sid, "dmglevel") * GetUnitAbilityLevel(u1, id) + GetStoredReal(udg_gc, sid, "dmgbase")
set d = d + GetHeroStr(u1, true) * GetStoredReal(udg_gc, sid, "dmgstr") + GetHeroAgi(u1, true) * GetStoredReal(udg_gc, sid, "dmgagi")
set d = (d + GetHeroInt(u1, true) * GetStoredReal(udg_gc, sid, "dmgint"))
set d = d * DamageTypeBonus("A" + I2S(id), u1, u2)
set d = GetRandomDamage(d, id, sid, u1, u2)
if HaveStoredInteger(udg_gc, sid, "dType") then
set dType = GetStoredInteger(udg_gc, sid, "dType")
else
set dType = -1
endif
call CauseDamage(u1, u2, d, GetStoredInteger(udg_gc, sid, "aType"), dType)
endfunction
function InCone takes real angle1, real angle2, real x2, real y2, unit u returns boolean
local real angle = bj_RADTODEG * Atan2(GetUnitY(u) - y2, GetUnitX(u) - x2)
local real tempReal
if angle1 > angle2 then
set tempReal = angle1
set angle1 = angle2
set angle2 = tempReal
endif
return angle >= angle1 and angle <= angle2
endfunction
function aoeAny takes nothing returns boolean
return GetWidgetLife(GetFilterUnit()) >= 0.405
endfunction
function aoeAlly takes nothing returns boolean
return IsPlayerAlly(GetOwningPlayer(GetFilterUnit()), bj_groupEnumOwningPlayer) and GetWidgetLife(GetFilterUnit()) >= 0.405
endfunction
function aoeEnemy takes nothing returns boolean
return IsPlayerEnemy(GetOwningPlayer(GetFilterUnit()), bj_groupEnumOwningPlayer) and GetWidgetLife(GetFilterUnit()) >= 0.405
endfunction
function aoeBool takes string bType, player p returns boolexpr
set bj_groupEnumOwningPlayer = p
if bType == "ally" then
return Condition(function aoeAlly)
elseif bType == "enemy" then
return Condition(function aoeEnemy)
else
return Condition(function aoeAny)
endif
endfunction
function DoTeffectAoE takes nothing returns nothing
local integer i = GetTimerInt(GetExpiredTimer())
local string s = I2S(i)
local unit u = I2U(GetStoredInteger(udg_gc, s, "unit"))
local unit uloop
local string sid = GetStoredString(udg_gc, s, "sid")
local real x = GetStoredReal(udg_gc, s, "x")
local real y = GetStoredReal(udg_gc, s, "y")
local integer lvl = GetStoredInteger(udg_gc, s, "lvl")
local integer c = GetStoredInteger(udg_gc, s, "c")
local real gap = GetStoredReal(udg_gc, s, "gap")
local group g = CreateGroup()
local string bType = GetStoredString(udg_gc, sid, "dotaoetype")
local boolexpr b = aoeBool(bType, GetOwningPlayer(u))
local real r = GetStoredReal(udg_gc, sid, "aoebase") + lvl * GetStoredReal(udg_gc, sid, "aoelevel")
local real d = GetStoredReal(udg_gc, sid, "dotaoedmgbase") + lvl * GetStoredReal(udg_gc, sid, "dotaoedmglevel")
local real dloop
local integer aType = GetStoredInteger(udg_gc, sid, "aType")
local integer dType
set d = d + GetHeroAgi(u, true) * GetStoredReal(udg_gc, sid, "dotaoedmgagi") + GetHeroInt(u, true) * GetStoredReal(udg_gc, sid, "dotaoedmgint") + GetHeroStr(u, true) * GetStoredReal(udg_gc, sid, "dotaoedmgstr")
if HaveStoredInteger(udg_gc, sid, "dType") then
set dType = GetStoredInteger(udg_gc, sid, "dType")
else
set dType = -1
endif
call GroupEnumUnitsInRange(g, x, y, r, b)
loop
set uloop = FirstOfGroup(g)
exitwhen uloop == null
set dloop = d * DamageTypeBonus(sid, u, uloop)
set dloop = GetRandomDoTDamage(dloop, sid, u, uloop)
if bType == "invert" and d > 0 and IsPlayerAlly(GetOwningPlayer(u), GetOwningPlayer(uloop)) then
call CauseDamage(u, uloop, 0 - d, aType, dType)
else
call CauseDamage(u, uloop, dloop, aType, dType)
endif
if HaveStoredString(udg_gc, sid, "effectmodeldotaoe") then
call DestroyEffectTimed(AddSpecialEffectTarget(GetStoredString(udg_gc, sid, "effectmodeldotaoe"), uloop, GetStoredString(udg_gc, sid, "effectattachdotaoe")), gap)
endif
call GroupRemoveUnit(g, uloop)
endloop
if c <= 1 then
call PauseTimer(GetExpiredTimer())
call DestroyTimer(GetExpiredTimer())
call FlushStoredMission(udg_gc, s)
else
call StoreInteger(udg_gc, s, "c", c - 1)
call TimerAttach(GetExpiredTimer(), gap, i, function DoTeffectAoE)
endif
call DestroyGroup(g)
call DestroyBoolExpr(b)
set g = null
set u = null
set b = null
set uloop = null
endfunction
function DoTeffect takes nothing returns nothing
local integer i = GetTimerInt(GetExpiredTimer())
local string s = I2S(i)
local unit u1 = I2U(GetStoredInteger(udg_gc, s, "u1"))
local unit u2 = I2U(GetStoredInteger(udg_gc, s, "u2"))
local string sid = GetStoredString(udg_gc, s, "sid")
local integer lvl = GetStoredInteger(udg_gc, s, "lvl")
local integer c = GetStoredInteger(udg_gc, s, "c")
local string typ = GetStoredString(udg_gc, s, "typ")
local real gap = GetStoredReal(udg_gc, s, "gap")
local real d = GetStoredReal(udg_gc, sid, "dot" + typ + "dmgbase") + lvl * GetStoredReal(udg_gc, sid, "dot" + typ + "dmglevel")
local integer dType
set d = d + GetHeroAgi(u1, true) * GetStoredReal(udg_gc, sid, "dot" + typ + "dmgagi") + GetHeroInt(u1, true) * GetStoredReal(udg_gc, sid, "dot" + typ + "dmgint") + GetHeroStr(u1, true) * GetStoredReal(udg_gc, sid, "dot" + typ + "dmgstr")
set d = GetRandomDoTDamage(d, sid, u1, u2)
if HaveStoredInteger(udg_gc, sid, "dType") then
set dType = GetStoredInteger(udg_gc, sid, "dType")
else
set dType = -1
endif
if GetWidgetLife(u2) < 0.405 then
call PauseTimer(GetExpiredTimer())
call DestroyTimer(GetExpiredTimer())
call FlushStoredMission(udg_gc, s)
set u1 = null
set u2 = null
return
endif
set d = d * DamageTypeBonus(sid, u1, u2)
call CauseDamage(u1, u2, d, GetStoredInteger(udg_gc, sid, "aType"), dType)
if HaveStoredString(udg_gc, sid, "effectmodeldot" + typ) then
call DestroyEffectTimed(AddSpecialEffectTarget(GetStoredString(udg_gc, sid, "effectmodeldot" + typ), u2, GetStoredString(udg_gc, sid, "effectattachdot" + typ)), gap)
endif
if c <= 1 then
call PauseTimer(GetExpiredTimer())
call DestroyTimer(GetExpiredTimer())
call FlushStoredMission(udg_gc, s)
else
call StoreInteger(udg_gc, s, "c", c - 1)
call TimerAttach(GetExpiredTimer(), gap, i, function DoTeffect)
endif
set u1 = null
set u2 = null
endfunction
// END OF CG CADS CUSTOM FUNCTIONS //
// -------------------------------
// MoCo's 2D Jump & Run System 1.0
// -------------------------------
// Version: 1.0
// Last changed: 2008-01-02
// Author: MoCo
// Contact: [email protected]
// This system uses Dragonblood Creations' Jump System with permission, made by Waldbaer.
// You may choose to use a different system for the jumping stuff.
// But if you use this system, you must give credit to Waldbaer too for this.
// All functions for the Jump & Run System itself are at the top of this page
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//x x
//x O Dragonblood Creations' Jump System x
//x _ - /Y- Version 2.01 x
//x - / \ © Waldbaer@Dragonblood Creations, December 22nd, 2007 x
//x- x
//x Check www.dragonblood-creations.com for the latest update! x
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//
//___________________________________________________________________________
//|You have to give credits, if you use anything of this system for your |
//|map, either whole functions or only parts of them. You are allowed to |
//|change this system, if you still give credits to Dragonblood Creations. |
//|If you think that changes by you are so useful in a way that they should |
//|be implemented in the official version for everybody's use, send an |
//|e-mail to |
//|[email protected] |
//|and write us your changes in it, as well as a description of what their |
//|exact effect is. If we decide to implement them really, you will of |
//|course also be credited. |
//|Special thanks go to Doomhammer.
//|_________________________________________________________________________|
//Constant Functions for easy editing of basic preferences
//--------------------------------------------------------
constant function DCJS_LoopFrequence takes nothing returns real
return 0.03 //This is the time period in seconds between the position corrections of the unit.
endfunction
constant function DCJS_Jumpers takes nothing returns group
return udg_DCJS_Jumpers //You can change this variable's name here if you want it to have another name.
endfunction
constant function PathChecker takes nothing returns integer
return 'uske' //The preset unit for pathchecking is the undead skeleton. If you want to use another ground unit, replace 'uske' with its rawcode.
endfunction
constant function DCJS_DataArrayCount takes nothing returns integer
return 9 //The number of variables saved in the Data-Array for each unit. If you edit the system itself and want to add anything, this may make your edits easier.
endfunction
//Used Secondary Functions of the system
//--------------------------------------
constant function DCJS_FlyTrick takes nothing returns integer
return 'Amrf'
endfunction
function DCJS_H2I takes handle h returns integer
return h
return 0
endfunction
function DCJS_I2U takes integer i returns unit
return i
return null
endfunction
function IsLocPathable takes location target returns boolean
local unit u = CreateUnitAtLoc( Player(13), PathChecker(), target, 0 )
local real x = GetUnitX( u ) - GetLocationX( target )
local real y = GetUnitY( u ) - GetLocationY( target )
if x < 1 and x > -1 and y < 1 and y > -1 then
call RemoveUnit(u)
set u = null
return true
endif
call RemoveUnit(u)
set u = null
return false
endfunction
function GetNearestPathableLoc takes location source returns location
local unit u = CreateUnitAtLoc( Player(13), PathChecker(), source, 0 )
local location pathable = GetUnitLoc( u )
call RemoveUnit(u)
set u = null
return pathable
endfunction
//Main Functions of the system
//----------------------------
function DCJS_Jump takes unit u, location target, real height, real ttime returns nothing
local location uPos = GetUnitLoc(u)
local real startz = GetLocationZ( uPos )
local real x = GetLocationX( target )
local real y = GetLocationY( target )
local real m = (GetLocationZ( target ) - startz) / ttime
local integer number = GetStoredInteger( udg_DCJS_GC, "Units", "Count" )
local integer i = number * DCJS_DataArrayCount()
local real zcorrect1 = SquareRoot(4 * height / ttime / ttime)
local real zcorrect2
local real zcorrect3
if GetUnitFlyHeight(u) > 0 then
set startz = startz + GetUnitFlyHeight(u)
endif
set zcorrect2 = zcorrect1 * ttime / -2 - m / 2 / zcorrect1
set zcorrect3 = zcorrect2 * zcorrect2 + startz
call SetUnitPathing( u, false )
call UnitAddAbility( u, DCJS_FlyTrick() )
call UnitRemoveAbility( u, DCJS_FlyTrick() )
//Save all needed variables in GameCache and the data array and add unit to the Jumpers group
set udg_DCJS_Data[i] = x
set udg_DCJS_Data[i+1] = y
set udg_DCJS_Data[i+2] = (x - GetLocationX(uPos)) / ttime * DCJS_LoopFrequence()
set udg_DCJS_Data[i+3] = (y - GetLocationY(uPos)) / ttime * DCJS_LoopFrequence()
set udg_DCJS_Data[i+4] = zcorrect1
set udg_DCJS_Data[i+5] = zcorrect2
set udg_DCJS_Data[i+6] = zcorrect3
set udg_DCJS_Data[i+7] = 0
set udg_DCJS_Data[i+8] = ttime
call StoreInteger( udg_DCJS_GC, I2S(DCJS_H2I(u)), "Number", number )
call StoreInteger( udg_DCJS_GC, I2S(number), "Unit", DCJS_H2I(u) )
call StoreInteger( udg_DCJS_GC, "Units", "Count", number + 1 )
call GroupAddUnit( DCJS_Jumpers(), u )
call RemoveLocation( uPos )
set uPos = null
endfunction
function DCJS_JumpSpeed takes unit u, location target, real height, real speed returns nothing
local location uPos = GetUnitLoc(u)
call DCJS_Jump( u, target, height, DistanceBetweenPoints( uPos, target ) / speed )
call RemoveLocation( uPos )
set uPos = null
endfunction
function DCJS_Bounce takes unit u, location newtarget returns nothing
local location uPos = GetUnitLoc(u)
local integer i
local real ttime
local real dtime
local real rise
local real zcorrect1
//only do anything if the unit is actually jumping
if IsUnitInGroup( u, udg_DCJS_Jumpers ) then
set i = GetStoredInteger( udg_DCJS_GC, I2S(DCJS_H2I(u)), "Number" ) * DCJS_DataArrayCount()
set ttime = udg_DCJS_Data[i+8]
set dtime = ttime - udg_DCJS_Data[i+7]
set rise = ( GetLocationZ( newtarget ) - GetLocationZ( uPos ) ) / dtime
set zcorrect1 = udg_DCJS_Data[i+4]
set udg_DCJS_Data[i] = GetLocationX( newtarget )
set udg_DCJS_Data[i+1] = GetLocationY( newtarget )
set udg_DCJS_Data[i+2] = (udg_DCJS_Data[i] - GetLocationX(uPos)) / dtime * DCJS_LoopFrequence()
set udg_DCJS_Data[i+3] = (udg_DCJS_Data[i+1] - GetLocationY(uPos)) / dtime * DCJS_LoopFrequence()
set udg_DCJS_Data[i+5] = zcorrect1 * ttime / -2 - rise / 2 / zcorrect1
set udg_DCJS_Data[i+6] = udg_DCJS_Data[i+5] * udg_DCJS_Data[i+5] + GetLocationZ( uPos ) - rise * udg_DCJS_Data[i+7]
endif
call RemoveLocation( uPos )
set uPos = null
endfunction
function DCJS_EndJump takes unit u, boolean StopHeightChange returns nothing
local string s = I2S(DCJS_H2I(u))
local unit last
local integer count
local integer number = GetStoredInteger( udg_DCJS_GC, s, "Number" )
local integer i = 0
//only do anything if the unit is actually jumping
if IsUnitInGroup( u, udg_DCJS_Jumpers ) then
if StopHeightChange then
call GroupRemoveUnit( DCJS_Jumpers(), u )
set count = GetStoredInteger( udg_DCJS_GC, "Units", "Count" ) - 1
set last = DCJS_I2U( GetStoredInteger( udg_DCJS_GC, I2S(count), "Unit" ) )
call FlushStoredInteger( udg_DCJS_GC, I2S(count), "Unit" )
call StoreInteger( udg_DCJS_GC, I2S(DCJS_H2I(last)), "Number", number )
call StoreInteger( udg_DCJS_GC, "Units", "Count", count )
set number = number * DCJS_DataArrayCount()
set count = count * DCJS_DataArrayCount()
loop
set udg_DCJS_Data[number + i] = udg_DCJS_Data[count + i]
set i = i + 1
exitwhen i == DCJS_DataArrayCount()
endloop
call FlushStoredInteger( udg_DCJS_GC, s, "Number" )
call SetUnitPathing( u, true )
else
set udg_DCJS_Data[ number * DCJS_DataArrayCount() + 2 ] = 0
set udg_DCJS_Data[ number * DCJS_DataArrayCount() + 3 ] = 0
endif
endif
set last = null
endfunction
function DCJS_LoopEnum takes nothing returns nothing
local unit u = GetEnumUnit()
local integer number = GetStoredInteger( udg_DCJS_GC, I2S(DCJS_H2I(u)), "Number" )
local integer i = number * DCJS_DataArrayCount()
local real x = GetUnitX(u) + udg_DCJS_Data[i+2]
local real y = GetUnitY(u) + udg_DCJS_Data[i+3]
local location nextposition = Location(x, y)
local real z = GetLocationZ(nextposition)
local real zcorrect1 = udg_DCJS_Data[i+4]
local real zcorrect2 = udg_DCJS_Data[i+5]
local real zcorrect3 = udg_DCJS_Data[i+6]
local real time = udg_DCJS_Data[i+7] + DCJS_LoopFrequence()
local real ttime = udg_DCJS_Data[i+8]
local real flyheight
local real tmp = zcorrect1 * time + zcorrect2
local integer count
local unit last
if time < ttime then
//Jumper is still in air
set flyheight = -tmp * tmp + zcorrect3 - z
call SetUnitFlyHeight(u, flyheight, 0 )
call SetUnitPosition( u, x, y )
set udg_DCJS_Data[i+7] = time
else
if RAbsBJ(udg_DCJS_Data[i+2]) + RAbsBJ(udg_DCJS_Data[i+3]) > 0 then
//Move unit to target position
call SetUnitPosition( u, udg_DCJS_Data[i], udg_DCJS_Data[i+1] )
endif
call SetUnitFlyHeight(u, 0, 0 )
//End jump and reset values
call GroupRemoveUnit( DCJS_Jumpers(), u )
set count = GetStoredInteger( udg_DCJS_GC, "Units", "Count" ) - 1
set last = DCJS_I2U( GetStoredInteger( udg_DCJS_GC, I2S(count), "Unit" ) )
call FlushStoredInteger( udg_DCJS_GC, I2S(count), "Unit" )
call StoreInteger( udg_DCJS_GC, I2S(DCJS_H2I(last)), "Number", number )
call StoreInteger( udg_DCJS_GC, "Units", "Count", count )
set i = 0
set number = number * DCJS_DataArrayCount()
set count = count * DCJS_DataArrayCount()
loop
set udg_DCJS_Data[number + i] = udg_DCJS_Data[count + i]
set i = i + 1
exitwhen i == DCJS_DataArrayCount()
endloop
call FlushStoredInteger( udg_DCJS_GC, I2S(DCJS_H2I(u)), "Number" )
call SetUnitPathing( u, true )
endif
set u = null
set last = null
call RemoveLocation( nextposition )
set nextposition = null
endfunction
function DCJS_Loop takes nothing returns nothing
call ForGroup(DCJS_Jumpers(), function DCJS_LoopEnum )
endfunction
function Init_DCJumpSystem takes nothing returns nothing
set udg_DCJS_Loop = CreateTrigger( )
call TriggerRegisterTimerEvent( udg_DCJS_Loop, DCJS_LoopFrequence(), true )
call TriggerAddAction( udg_DCJS_Loop, function DCJS_Loop )
set udg_DCJS_GC = InitGameCache( "jumpsystem.w3v" )
call FlushGameCache( udg_DCJS_GC )
call SaveGameCache( udg_DCJS_GC )
set udg_DCJS_GC = InitGameCache( "jumpsystem.w3v" )
call StoreInteger( udg_DCJS_GC, "Units", "Count", 0 )
endfunction
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// Jump & Run System functions
// ---------------------------------------------------------------------
// Moves a unit (by a specified distance, and of course in X direction only)
function JumpRunSys_Unit_MoveRight takes unit whichUnit returns nothing
local location PointToMove
// set PointToMove = Location(GetLocationX(GetUnitLoc(whichUnit)) + moveDistance, GetLocationY(GetUnitLoc(whichUnit)))
set PointToMove = udg_LevelEndings[udg_CurrentLevel]
call IssuePointOrderLoc( whichUnit, "move", PointToMove )
set PointToMove = null
endfunction
function JumpRunSys_Unit_MoveLeft takes unit whichUnit returns nothing
local location PointToMove
// set PointToMove = Location(GetLocationX(GetUnitLoc(whichUnit)) + moveDistance, GetLocationY(GetUnitLoc(whichUnit)))
set PointToMove = udg_LevelStarts[udg_CurrentLevel]
call IssuePointOrderLoc( whichUnit, "move", PointToMove )
set PointToMove = null
endfunction
// Fire something
function JumpRunSys_Unit_Shoot takes unit whichUnit, string order, real fireDistance returns nothing
local location PointToShoot
if ( GetUnitFacing(whichUnit) > 90 and GetUnitFacing(whichUnit) < 270 ) then
set PointToShoot = Location(GetLocationX(GetUnitLoc(whichUnit)) - fireDistance, GetLocationY(GetUnitLoc(whichUnit)))
else
set PointToShoot = Location(GetLocationX(GetUnitLoc(whichUnit)) + fireDistance, GetLocationY(GetUnitLoc(whichUnit)))
endif
call IssuePointOrderLoc( whichUnit, order, PointToShoot )
set PointToShoot = null
endfunction
// Jumpin
function JumpRunSys_Unit_Jump takes unit whichUnit, real jumpDistance returns nothing
local location PointToJump
local location PointToMove
if ( GetUnitFacing(whichUnit) > 90 and GetUnitFacing(whichUnit) < 270 ) then
set PointToJump = Location(GetLocationX(GetUnitLoc(whichUnit)) - jumpDistance, GetLocationY(GetUnitLoc(whichUnit)))
else
set PointToJump = Location(GetLocationX(GetUnitLoc(whichUnit)) + jumpDistance, GetLocationY(GetUnitLoc(whichUnit)))
endif
set PointToJump = GetNearestPathableLoc(PointToJump)
// call DCJS_JumpSpeed(whichUnit, PointToJump, DistanceBetweenPoints(GetUnitLoc(whichUnit), PointToJump) / 2, GetUnitMoveSpeed(whichUnit))
call DCJS_Jump(whichUnit, PointToJump, 128, 0.8)
call TriggerSleepAction(0.05)
call SetUnitAnimationByIndex( whichUnit, 6 )
call SetUnitTimeScalePercent( whichUnit, 30.00 )
call TriggerSleepAction(0.6) // 0.65
call ResetUnitAnimation(whichUnit)
call SetUnitTimeScalePercent( whichUnit, 100.00 )
if ( udg_MovingForwards[GetConvertedPlayerId(GetOwningPlayer(whichUnit))] == true ) then
set PointToMove = udg_LevelEndings[udg_CurrentLevel]
call IssuePointOrderLoc( whichUnit, "move", PointToMove )
endif
if ( udg_MovingBackwards[GetConvertedPlayerId(GetOwningPlayer(whichUnit))] == true ) then
set PointToMove = udg_LevelStarts[udg_CurrentLevel]
call IssuePointOrderLoc( whichUnit, "move", PointToMove )
endif
set PointToJump = null
set PointToMove = null
endfunction
// Collect Item
function JumpRunSys_AutoCollectItem takes unit CollectingHero, unit Item returns nothing
local texttag t = CreateTextTag()
local effect e
// Set custom value of item to 1
// (This makes sure it can't be collected again, because it remains a bit longer for the death anim
call SetUnitUserData( Item, 1 )
// Create Floating Text
call SetTextTagPos(t, GetUnitX(CollectingHero), GetUnitY(CollectingHero), 64.00)
call SetTextTagVelocity(t, 0, 0.04)
call SetTextTagVisibility(t, true)
call SetTextTagFadepoint(t, 3)
call SetTextTagLifespan(t, 4)
call SetTextTagPermanent(t, false)
// Gold Coin
if ( GetUnitTypeId(GetTriggerUnit()) == 'e000' ) then
call SetUnitAnimationByIndex( Item, 2 )
call PlaySoundOnUnitBJ( gg_snd_ReceiveGold, 100, CollectingHero )
call SetTextTagColor(t, 255, 239, 149, 255)
// call SetTextTagText(t, "+" + I2S(GetPlayerState(GetOwningPlayer(CollectingHero), PLAYER_STATE_RESOURCE_GOLD)), 0.03)
call SetTextTagText(t, "+ 1", 0.03)
call SetPlayerState(GetOwningPlayer(CollectingHero), PLAYER_STATE_RESOURCE_GOLD, GetPlayerState(GetOwningPlayer(CollectingHero), PLAYER_STATE_RESOURCE_GOLD) + 1)
call TriggerSleepAction( 1.00 )
// Healing Poition
elseif ( GetUnitTypeId(GetTriggerUnit()) == 'e002' ) then
call SetUnitAnimationByIndex( Item, 1 )
call PlaySoundOnUnitBJ( gg_snd_HealingWave, 100, CollectingHero )
call SetTextTagColor(t, 147, 248, 144, 255)
call SetTextTagText(t, "+ 250", 0.03)
call SetUnitState(CollectingHero, UNIT_STATE_LIFE, GetUnitState(CollectingHero, UNIT_STATE_LIFE) + 250)
set e = AddSpecialEffectTarget("Abilities\\Spells\\Items\\HealingSalve\\HealingSalveTarget.mdl", CollectingHero, "origin")
// Mana Potion
elseif ( GetUnitTypeId(GetTriggerUnit()) == 'e001' ) then
call SetUnitAnimationByIndex( Item, 1 )
call PlaySoundOnUnitBJ( gg_snd_HealingWave, 100, CollectingHero )
call SetTextTagColor(t, 142, 202, 248, 255)
call SetTextTagText(t, "+ 100", 0.03)
call SetUnitState(CollectingHero, UNIT_STATE_MANA, GetUnitState(CollectingHero, UNIT_STATE_MANA) + 100)
set e = AddSpecialEffectTarget("Abilities\\Spells\\Human\\Invisibility\\InvisibilityTarget.mdl", CollectingHero, "origin")
endif
call RemoveUnit( Item )
call DestroyEffect(e)
set t = null
set e = null
endfunction
function MoCo_SpawnCreep takes integer CreepID, location position returns nothing
local effect e
set bj_lastCreatedUnit = CreateUnitAtLoc(Player(PLAYER_NEUTRAL_AGGRESSIVE), CreepID, position, bj_UNIT_FACING)
set e = AddSpecialEffectTarget("Abilities\\Spells\\Undead\\AnimateDead\\AnimateDeadTarget.mdl", bj_lastCreatedUnit, "origin")
call DestroyEffect(e)
set e = null
endfunction
function MoCo_FillEmptyPlayerSlot takes player whichPlayer, mapcontrol control returns nothing
local integer playerIndex = GetPlayerId(whichPlayer)
call CheckInitPlayerSlotAvailability()
set bj_slotControlUsed[playerIndex] = true
set bj_slotControl[playerIndex] = MAP_CONTROL_COMPUTER
endfunction
function MoCo_IsHostile takes nothing returns boolean
return ( GetOwningPlayer(GetFilterUnit()) == Player(PLAYER_NEUTRAL_AGGRESSIVE) )
endfunction
function MoCo_GetClosestEnemyUnit takes unit Hero returns unit
local group g
local unit u
local unit closestUnit
local boolean facingLeft = false
local real distance
set closestUnit = null
// First, let's check the facing direction of the hero
if ( GetUnitFacing(GetSpellAbilityUnit()) > 90 and GetUnitFacing(GetSpellAbilityUnit()) < 270 ) then
set facingLeft = true
endif
// This should create a group with hostile units around the hero
set g = GetUnitsInRangeOfLocMatching(256.00, GetUnitLoc(Hero), Condition(function MoCo_IsHostile))
loop
set u = FirstOfGroup(g)
exitwhen u == null
set distance = DistanceBetweenPoints(GetUnitLoc(Hero), GetUnitLoc(u))
// First, the unit has to be alive
if GetUnitState(u, UNIT_STATE_LIFE) > 0 then
// Second, we use different distances for targetting units and buildings
if ( distance <= 150 ) or ( IsUnitType(u, UNIT_TYPE_STRUCTURE) == true ) then
// Facing Left
if ( facingLeft == true ) then
// make sure the unit does not stand behind the hero
if ( GetLocationX(GetUnitLoc(u)) < GetLocationX(GetUnitLoc(Hero)) ) then
if closestUnit == null then
// call DisplayTextToForce( GetPlayersAll(), GetUnitName(u) )
set closestUnit = u
else
if ( GetLocationX(GetUnitLoc(u)) > GetLocationX(GetUnitLoc(closestUnit)) ) then
set closestUnit = u
endif
endif
endif
// Facing Right
else
if ( GetLocationX(GetUnitLoc(u)) > GetLocationX(GetUnitLoc(Hero)) ) then
if closestUnit == null then
set closestUnit = u
else
if ( GetLocationX(GetUnitLoc(u)) < GetLocationX(GetUnitLoc(closestUnit)) ) then
set closestUnit = u
endif
endif
endif
endif
endif
endif
call GroupRemoveUnit(g, u)
endloop
return closestUnit
endfunction
Name | Type | is_array | initial_value |
ActiveCreeps | group | No | |
ActiveShrine | unit | No | |
AI_Active | boolean | No | false |
Bosses | unit | Yes | |
BossFight | boolean | No | |
BossFightCount | integer | Yes | |
cache | gamecache | No | |
CameraDistance | real | No | |
CameraHeight | real | No | |
CameraPosition | location | Yes | |
CreepBuildingsAlive | boolean | Yes | |
CreepCount | integer | Yes | |
CreepGroups | group | Yes | |
CreepRespawnPositions | location | Yes | |
CreepRespawnTypes | unitcode | Yes | |
CurrentLevel | integer | No | |
DCJS_Data | real | Yes | |
DCJS_GC | gamecache | No | |
DCJS_Jumpers | group | No | |
DCJS_Loop | trigger | No | |
Debug_Mode | boolean | No | |
DifficultyFactor | real | No | |
Druid | unit | No | |
FallDown | boolean | No | |
FireDistance | real | No | |
Force3PlayersGame | boolean | No | |
GameON | boolean | No | |
gc | gamecache | No | |
HeroArray | unit | Yes | |
Heroes | group | No | |
ItemPositions | location | Yes | |
Items | unitcode | Yes | |
ItemTypes | unitcode | Yes | |
JumpDistance | real | No | |
Kobolds | integer | No | 0 |
LeadingHero | unit | No | |
Left | boolean | No | |
LevelAreas | rect | Yes | |
LevelEndings | location | Yes | |
LevelEndPathBlockers | destructable | Yes | |
Levels2ndTime | boolean | Yes | false |
LevelsCount | integer | No | |
LevelsFinished | boolean | Yes | |
LevelStarts | location | Yes | |
Mage | unit | No | |
MaxCreepCount | integer | Yes | |
MaxFixedUnitsPerLevel | integer | No | |
MovingBackwards | boolean | Yes | |
MovingForwards | boolean | Yes | |
PathingBlockerPositions | location | Yes | |
PlayerColors | string | Yes | |
Players | force | No | |
Point | location | No | |
RespawnableCreepsCount | integer | Yes | |
RespawnableItemsCount | integer | Yes | |
RespawnablesStartValues | integer | Yes | |
Right | boolean | No | |
RuntimeCreatedDestructibles | destructable | Yes | |
RuntimeDestructiblesCount | integer | No | |
TagDebug | string | No | |
TagEvent | string | No | |
TagHint | string | No | |
TempID | integer | No | |
TempInt | integer | No | |
TempInt2 | integer | No | |
TempPlayer | player | No | |
TempPoint | location | No | |
TempReal | real | No | |
TempRegion | rect | No | |
TempString | string | No | |
TempUnit | unit | No | |
TempUnitGroup | group | No | |
Up | boolean | No | |
Warrior | unit | No | |
XP_Factor | real | No |
//TESH.scrollpos=44
//TESH.alwaysfold=0
-------------------------------
MoCo's 2D Jump & Run System
-------------------------------
Version: 1.0
Last changed: 2008-02-02
Author: MoCo
Contact: [email protected]
If you use this system, you must give credit to the author!
Also, this system uses Dragonblood Creations' Jump System with permission, made by Waldbaer.
You may choose to use a different system for the jumping stuff.
But if you use the included system, you must give credit to Waldbaer too for this.
If you have any questions, please do not contact me per mail.
Please use the forum at http://wc3campaigns.net.
Enjoy being creative!
-------------------------------
WELCOME TO THE JUMP & RUN SYSTEM!
- What does it do?
This is a template, that shows, how a 2d scrolling jump & run game
can be created within the WC3 engine.
It provides a framework and allows you to make your own jump & run
basing on this system.
- What it is not:
It is not a fully set up jump & run game so that you only have to change
a few things by yourself to get a cool game.
It is just the first brick in the wall and gives you the base,
to create your game. But you probably have to make some modifications
to the system to make it fit your needs.
- What do you need to use it?
Basic knowledge of jass is recommend.
I also heavily suggest to get the JassNewGen Pack before using this system
and playing around with jass in general. Get it here: http://wc3campaigns.net/showthread.php?t=90999
Features:
- camera system
- movement system
- a complete demo stage
- gold coins (example for automatically collected items in general)
- Waldbaers Jump-System included
- a simple death/revive system
Installation:
This is not the kind of system, that is supposed to be implented into an existing map.
The easiest way is to start your map basing on this one.
Keep in mind, that you still can change tileset, mapsize etc.
If you really have to import the system into an existing map,
you have to copy all triggers to your map (just copy the whole category).
Make sure that 'automatically create unknown variables..' in the Preferences->General options is checked.
You have to copy all the code in the custom script section to your map too
(The custom script section is at top of the trigger editor, the entry named as the maps name).
Usage:
- Look through all triggers and try to understand how they work and what they do
- Use the variable CurrentLevel to store the current level
- Use pathing-blocker doodads to limit the walkable path in each level (as done in the demo level)
- Make all other doodas non-blocking (give them the same pathing texture as the shrub,
actually I have already done this for most of them)
- Use regions to define level-startpoints, endpoints and save areas (the area that are not dangerous)
-
Known Bugs:
- The jumping
If you have any questions, suggestions or bugs, please feel free to report them to me!
Thanks!
Now I hope this system will help you! Enjoy creating your map!
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_Hero_Dies_Actions takes nothing returns nothing
local unit DeadHero
set DeadHero = GetDyingUnit()
call TriggerSleepAction( 2 )
call ReviveHeroLoc( DeadHero, udg_LevelStarts[udg_CurrentLevel], true )
call SelectUnitForPlayerSingle( DeadHero, GetOwningPlayer(DeadHero) )
call SetUnitAnimationByIndex( udg_ActiveShrine, 2 )
call TriggerSleepAction( 1 )
call SetUnitAnimationByIndex( udg_ActiveShrine, 1 )
set DeadHero = null
endfunction
//===========================================================================
function InitTrig_Revive_Heroes takes nothing returns nothing
set gg_trg_Revive_Heroes = CreateTrigger( )
call TriggerRegisterPlayerUnitEventSimple( gg_trg_Revive_Heroes, Player(0), EVENT_PLAYER_UNIT_DEATH )
call TriggerRegisterPlayerUnitEventSimple( gg_trg_Revive_Heroes, Player(1), EVENT_PLAYER_UNIT_DEATH )
call TriggerRegisterPlayerUnitEventSimple( gg_trg_Revive_Heroes, Player(2), EVENT_PLAYER_UNIT_DEATH )
call TriggerAddAction( gg_trg_Revive_Heroes, function Trig_Hero_Dies_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
// Darkwulfv Experience System
// ---------------------------
constant function DES_XPRadius takes nothing returns real
return 1400. //Heroes within this radius will be checked for and given XP according
//to how many allied heroes are in this radius.
endfunction
constant function DES_EXPSplit takes nothing returns boolean
return true //Set this to true to make it so the EXP granted, after bonuses, is divided
//by the number of heroes.
endfunction
constant function DES_DistanceEffect takes nothing returns boolean
return true //If you do not want the distance from the killing hero to factor how
//much XP your heroes get, make this value false.
endfunction
constant function DES_Close takes nothing returns real
return 600. //This is what designates "close" and gives the full XP amount
endfunction
constant function DES_Medium takes nothing returns real
return 1000. //This is what designates "medium distance" and gives lesser the XP amount
endfunction
constant function DES_Far takes nothing returns real
return 1400. //This is what designates "far" and gives even lesser the XP amount. This should equal
//the overall radius set in DES_XPRadius
endfunction
constant function DES_MediumFactor takes nothing returns real
return .5 //This is the amount the XP given to units in the "Medium" Radius is mutliplied by.
//It's currently half.
endfunction
constant function DES_FarFactor takes nothing returns real
return .25 //This is the same as DES_MediumFactor, except it's for units in the Far Radius.
//It's currently one fourth.
endfunction
constant function DES_UnitXP takes nothing returns integer
return 10 //This is multiplied by the level of the unit.
endfunction
constant function DES_HeroXP takes nothing returns integer
return 10 //This is the same as DES_UnitXP, but for heroes, not units.
//It should probably be higher, but that's your choice.
endfunction
constant function DES_XPPerHero takes nothing returns integer
return 0 //This is a bonus. It is multiplied by the number of heroes in the radius(es)
//specified, then added to the XP amount.
//Positive number is bonus
//Negative number is lesser
//0 is no bonus.
endfunction
constant function DES_Formula takes integer XPfactor, integer unitlevel, integer heroesinradius, integer bonus returns integer
return (XPfactor * unitlevel) + (heroesinradius * bonus)
//This is the function that determines how XP is calculted.
//Unless you have a different method, don't touch this.
endfunction
//Edit this function for your conditions; Example: Unit is alive, unit is a hero, unit is an ally
//Whatever you want. Just put an "and" between the new one and the previous one.
function DES_Filter takes nothing returns boolean
return (GetWidgetLife(GetFilterUnit()) > .405) == true and (IsUnitType(GetFilterUnit(), UNIT_TYPE_HERO) == true) and IsUnitAlly(GetFilterUnit(), GetOwningPlayer(GetKillingUnit())) == true
endfunction
// added by MoCo | shows a little floating text for XP
function DES_MOCO_CreateXPTag takes integer XPGained, unit XPGainingUnit, string XPMod returns nothing
local texttag t = CreateTextTag()
local string value
set value = "+"+I2S(XPGained)+"XP"+XPMod
call SetTextTagColor(t, 182, 91, 234, 255)
call SetTextTagText(t, value, 0.03)
call SetTextTagPos(t, GetUnitX(XPGainingUnit), GetUnitY(XPGainingUnit), 128.00)
call SetTextTagVelocity(t, 0, 0.03)
call SetTextTagVisibility(t, true)
call SetTextTagFadepoint(t, 2)
call SetTextTagLifespan(t, 3)
call SetTextTagPermanent(t, false)
set t = null
endfunction
// This changes and adds XP
// It modifies XP depending on the difference between the hero's and
// the killed unit's level
function DES_MOCO_AddXP takes integer add, unit Hero, integer KilledUnitLevel returns nothing
local integer FinalXPAdd
local string XPMod // added by MoCo
set FinalXPAdd = R2I(add * udg_XP_Factor)
// 0% for 3 chapters difference
if ( GetHeroLevel(Hero) > ((KilledUnitLevel*15)-1) ) then
// set FinalXPAdd = 0
// call AddHeroXP(Hero, FinalXPAdd, true)
set XPMod = " |c00FF0000noXP|r"
// call DES_MOCO_CreateXPTag(FinalXPAdd,Hero,XPMod)
// 25% for 2 chapters difference
elseif ( GetHeroLevel(Hero) > ((KilledUnitLevel*10)-1) ) then
set FinalXPAdd = R2I(add * 0.25)
call AddHeroXP(Hero, FinalXPAdd, true)
set XPMod = " |c00C6C6C6-75%|r"
call DES_MOCO_CreateXPTag(FinalXPAdd,Hero,XPMod)
// 50% for 1 chapter difference
elseif ( GetHeroLevel(Hero) > ((KilledUnitLevel*5)-1) ) then
set FinalXPAdd = R2I(add * 0.50)
call AddHeroXP(Hero, FinalXPAdd, true)
set XPMod = " |c00C6C6C6-50%|r"
call DES_MOCO_CreateXPTag(FinalXPAdd,Hero,XPMod)
// no difference
else
set FinalXPAdd = add
call AddHeroXP(Hero, FinalXPAdd, true)
set XPMod = ""
call DES_MOCO_CreateXPTag(FinalXPAdd,Hero,XPMod)
endif
endfunction
function DES_MOCO_AddDirectXP takes integer add, unit Hero returns nothing
local string XPMod // added by MoCo
set add = R2I(add * udg_XP_Factor)
call AddHeroXP(Hero, add, true)
set XPMod = ""
call DES_MOCO_CreateXPTag(add,Hero,XPMod)
endfunction
//This applies the XP accordingly.
function DES_GiveXP takes nothing returns nothing
local unit u = GetDyingUnit()
local unit f
local unit Killer = GetKillingUnit()
local player p = GetOwningPlayer(Killer)
local integer add
local integer finalAdd
local integer KilledUnitLevel
local integer unitNum = 0
local group g = CreateGroup()
local real x = GetUnitX(Killer)
local real y = GetUnitY(Killer)
local real distance
local string XPMod // added by MoCo
set bj_groupCountUnits = 0
call GroupEnumUnitsInRange(g, x, y, DES_XPRadius(), Condition(function DES_Filter))
call ForGroup(g, function CountUnitsInGroupEnum)
set unitNum = bj_groupCountUnits
//============================================================
if IsUnitAlly(u, p) == false then
if IsUnitType(u, UNIT_TYPE_HERO) == true then
set KilledUnitLevel = GetHeroLevel(u)
set add = DES_Formula(DES_HeroXP(), KilledUnitLevel, unitNum, DES_XPPerHero())
elseif IsUnitType(u, UNIT_TYPE_HERO) == false then
set KilledUnitLevel = GetUnitLevel(u)
set add = DES_Formula(DES_HeroXP(), KilledUnitLevel, unitNum, DES_XPPerHero())
endif
endif
if DES_EXPSplit() then
set add = R2I(add / unitNum)
endif
//============================================================
if DES_DistanceEffect() then
loop
set f = FirstOfGroup(g)
exitwhen f == null
set distance = ((GetUnitX(Killer)-GetUnitX(f)) * (GetUnitX(Killer)-GetUnitX(f))) + ((GetUnitY(Killer)-GetUnitY(f)) * (GetUnitY(Killer)-GetUnitY(f)))
//Far Away Units
if distance > DES_Medium()*DES_Medium() and distance < DES_Far()*DES_Far() then
call SetPlayerHandicapXP(GetOwningPlayer(f), 1.00)
set finalAdd = R2I(add * DES_FarFactor())
call DES_MOCO_AddXP(finalAdd,f,KilledUnitLevel)
// call AddHeroXP(f, finalAdd, true)
// call DES_CreateXPTag(finalAdd,f,XPMod) // added by MoCo
call SetPlayerHandicapXP(GetOwningPlayer(f), 0.00)
call GroupRemoveUnit(g, f)
//Medium Distance Units
elseif distance > DES_Close()*DES_Close() and distance < DES_Medium()*DES_Medium() then
call SetPlayerHandicapXP(GetOwningPlayer(f), 1.00)
set finalAdd = R2I(add * DES_MediumFactor())
call DES_MOCO_AddXP(finalAdd,f,KilledUnitLevel)
// call AddHeroXP(f, finalAdd, true)
// call DES_CreateXPTag(finalAdd,f,XPMod) // added by MoCo
call SetPlayerHandicapXP(GetOwningPlayer(f), 0.00)
call GroupRemoveUnit(g, f)
//Close Range Units
elseif distance < DES_Close()*DES_Close() then
call SetPlayerHandicapXP(GetOwningPlayer(f), 1.00)
call DES_MOCO_AddXP(add,f,KilledUnitLevel)
// call AddHeroXP(f, add, true)
// call DES_CreateXPTag(add,f,XPMod) // added by MoCo
call SetPlayerHandicapXP(GetOwningPlayer(f), 0.00)
call GroupRemoveUnit(g, f)
endif
endloop
elseif not(DES_DistanceEffect()) then
loop
set f = FirstOfGroup(g)
exitwhen f == null
call SetPlayerHandicapXP(GetOwningPlayer(f), 1.00)
call DES_MOCO_AddXP(add,f,KilledUnitLevel)
// call AddHeroXP(f, add, true)
// call DES_CreateXPTag(add,f,XPMod) // added by MoCo
call SetPlayerHandicapXP(GetOwningPlayer(f), 0.00)
call GroupRemoveUnit(g, f)
endloop
endif
call DestroyGroup(g)
set g = null
set u = null
set Killer = null
set f = null
endfunction
//This trigger stops players from gaining XP when they shouldn't be.
function Cut_XP_Gain takes nothing returns nothing
local integer i = 0
loop
exitwhen i > 13
call SetPlayerHandicapXP(Player(i), 0.00)
set i = i + 1
endloop
call DestroyTimer(GetExpiredTimer())
endfunction
//===========================================================================
function InitTrig_DEXP_System takes nothing returns nothing
local trigger t = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_DEATH )
call TriggerAddAction(t, function DES_GiveXP )
call TimerStart(CreateTimer(), .04, false, function Cut_XP_Gain)
set t = null
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_Jump_Conditions takes nothing returns boolean
if ( not ( GetSpellAbilityId() == 'A068' ) ) then
return false
endif
return true
endfunction
function Trig_Jump_Actions takes nothing returns nothing
local unit JumpUnit = GetSpellAbilityUnit()
if ( udg_MovingBackwards[GetConvertedPlayerId(GetOwningPlayer(GetSpellAbilityUnit()))] == false ) and ( udg_MovingForwards[GetConvertedPlayerId(GetOwningPlayer(GetSpellAbilityUnit()))] == false ) then
call JumpRunSys_Unit_Jump( JumpUnit, 0 )
else
call JumpRunSys_Unit_Jump( JumpUnit, udg_JumpDistance )
endif
set JumpUnit = null
endfunction
//===========================================================================
function InitTrig_Jump takes nothing returns nothing
set gg_trg_Jump = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Jump, EVENT_PLAYER_UNIT_SPELL_CAST )
call TriggerAddCondition( gg_trg_Jump, Condition( function Trig_Jump_Conditions ) )
call TriggerAddAction( gg_trg_Jump, function Trig_Jump_Actions )
endfunction
//TESH.scrollpos=6
//TESH.alwaysfold=0
function Trig_Heroic_Strike_Conditions takes nothing returns boolean
if ( not ( GetSpellAbilityId() == 'A069' ) ) then
return false
endif
return true
endfunction
function Trig_Heroic_Strike_Actions takes nothing returns nothing
local integer damage
local unit targetUnit = null
local effect e
local integer tempInt
local boolean crit = false
local boolean rage = false
set targetUnit = MoCo_GetClosestEnemyUnit(GetSpellAbilityUnit())
if ( not ( targetUnit == null ) ) then
// Calculate Damage
set tempInt = GetRandomInt(5, 25)
set damage = 5 * GetHeroStr( GetSpellAbilityUnit(), true ) + tempInt
// ~20% crit chance
set tempInt = GetRandomInt(1, 10)
if ( tempInt > 8 ) and ( IsUnitType(targetUnit, UNIT_TYPE_STRUCTURE) == false ) then
set crit = true
set damage = damage * 2
call SetUnitExploded( targetUnit, true )
endif
// Rage
if (GetUnitAbilityLevel(GetSpellAbilityUnit(), 'B00K') > 0) then
set damage = damage * 2
set rage = true
endif
call UnitDamageTarget( GetSpellAbilityUnit(), targetUnit, I2R(damage), true, false, ATTACK_TYPE_MELEE, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
call MoCo_CreateDamageTagOnUnit(targetUnit, damage, crit, rage)
if ( IsUnitType(targetUnit, UNIT_TYPE_STRUCTURE) == false ) then
set e = AddSpecialEffectTarget("Objects\\Spawnmodels\\Human\\HumanBlood\\HumanBloodFootman.mdl", targetUnit, "origin")
endif
call SetUnitExploded( targetUnit, false )
endif
call DestroyEffect(e)
set e = null
set targetUnit = null
endfunction
//===========================================================================
function InitTrig_Heroic_Strike takes nothing returns nothing
set gg_trg_Heroic_Strike = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Heroic_Strike, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_Heroic_Strike, Condition( function Trig_Heroic_Strike_Conditions ) )
call TriggerAddAction( gg_trg_Heroic_Strike, function Trig_Heroic_Strike_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_Active_Creeps_Func001A takes nothing returns nothing
call IssuePointOrderLocBJ( GetEnumUnit(), "attack", GetUnitLoc(gg_unit_H001_0013) )
endfunction
function Trig_Active_Creeps_Actions takes nothing returns nothing
call ForGroupBJ( udg_ActiveCreeps, function Trig_Active_Creeps_Func001A )
endfunction
//===========================================================================
function InitTrig_Active_Creeps takes nothing returns nothing
set gg_trg_Active_Creeps = CreateTrigger( )
call TriggerRegisterTimerEventPeriodic( gg_trg_Active_Creeps, 5.00 )
call TriggerAddAction( gg_trg_Active_Creeps, function Trig_Active_Creeps_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_Spawn_Kobolds_Conditions takes nothing returns boolean
if ( not ( udg_LevelsFinished[1] == false ) ) then
return false
endif
return true
endfunction
function Trig_Spawn_Kobolds_Actions takes nothing returns nothing
local rect TempRegion
local location TempPoint
local integer TempInt
set TempInt = GetRandomInt(1,10)
set TempRegion = RectFromCenterSizeBJ(GetUnitLoc(udg_LeadingHero), 1024.00, 64.00)
set TempPoint = GetRandomLocInRect(TempRegion)
if ( udg_Kobolds < 5 ) and ( not (RectContainsLoc(gg_rct_Level_1_Boss_Area, TempPoint) == true ) ) then
if ( TempInt > 7 ) then
call MoCo_SpawnCreep( 'nkog', TempPoint )
else
call MoCo_SpawnCreep( 'nkob', TempPoint )
endif
set udg_Kobolds = udg_Kobolds + 1
endif
set TempPoint = null
set TempRegion = null
call RemoveLocation(TempPoint)
call RemoveRect(TempRegion)
endfunction
//===========================================================================
function InitTrig_Level_1_Spawn_Kobolds takes nothing returns nothing
set gg_trg_Level_1_Spawn_Kobolds = CreateTrigger( )
call TriggerRegisterTimerEventPeriodic( gg_trg_Level_1_Spawn_Kobolds, 10.00 )
call TriggerAddCondition( gg_trg_Level_1_Spawn_Kobolds, Condition( function Trig_Spawn_Kobolds_Conditions ) )
call TriggerAddAction( gg_trg_Level_1_Spawn_Kobolds, function Trig_Spawn_Kobolds_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function StoreSound takes string missionKey, string key, string fileName returns nothing
call StoreString(udg_gc, missionKey, key, fileName)
call Preload(fileName)
endfunction
function Trig_CG_CADS_Init_Actions takes nothing returns nothing
local string s
if udg_gc == null then
set udg_gc = InitGameCache("jass.w3v")
endif
// ========================
// ABILITY SET UP
// ========================
// -------
// Warrior
// -------
// Heroic Strike - Unit
set s = "A" + I2S('A07E')
call StoreString(udg_gc, s, "target", "unit")
call StoreReal(udg_gc, s, "dmgbase", 50)
call StoreReal(udg_gc, s, "dmglevel", 5)
call StoreString(udg_gc, s, "damagetype", "normal")
call StoreSound(s, "soundcaster", "Sound\\Units\\Combat\\MetalHeavySliceMetal3.wav")
call StoreString(udg_gc, s, "effectattach", "origin")
call StoreString(udg_gc, s, "effectmodel", "Objects\\Spawnmodels\\Human\\HumanBlood\\HumanBloodFootman.mdl")
call StoreString(udg_gc, s, "effectattachdot", "origin")
call StoreString(udg_gc, s, "effectmodeldot", "Objects\\Spawnmodels\\Human\\HumanBlood\\HumanBloodFootman.mdl")
call StoreReal(udg_gc, s, "dmgstr", 3)
call StoreReal(udg_gc, s, "dmgagi", 0)
call StoreReal(udg_gc, s, "dmgint", 0)
call StoreInteger(udg_gc, s, "dotwaves", 3)
call StoreReal(udg_gc, s, "dotbreak", 3)
call StoreReal(udg_gc, s, "dotdmgbase", 0)
call StoreReal(udg_gc, s, "dotdmglevel", 5)
call StoreReal(udg_gc, s, "dotdmgstr", 3)
call StoreReal(udg_gc, s, "dotdmgagi", 0)
call StoreReal(udg_gc, s, "dotdmgint", 0)
// Shield Slam - Unit
set s = "A" + I2S('A06E')
call StoreString(udg_gc, s, "target", "unit")
call StoreReal(udg_gc, s, "dmgbase", 30)
call StoreReal(udg_gc, s, "dmglevel", 5)
call StoreString(udg_gc, s, "damagetype", "normal")
call StoreReal(udg_gc, s, "dmgstr", 2)
call StoreReal(udg_gc, s, "dmgagi", 0)
call StoreReal(udg_gc, s, "dmgint", 0)
// ----
// Monk
// ----
// Healing Touch - Unit
set s = "A" + I2S('A06G')
call StoreString(udg_gc, s, "target", "unit")
call StoreString(udg_gc, s, "aoetype", "ally") // What is targeted (ally/enemy/any)
call StoreString(udg_gc, s, "damagetype", "holy")
call StoreReal(udg_gc, s, "dmgbase", 0) // Damage base
call StoreReal(udg_gc, s, "dmglevel", 0) // Damage per ability level
call StoreReal(udg_gc, s, "dmgstr", 0) // Strength factor
call StoreReal(udg_gc, s, "dmgagi", 0) // Agility factor
call StoreReal(udg_gc, s, "dmgint", -5) // Intelligence factor; note the negative for healing
// Holy Nova - Instant
set s = "A" + I2S('A066')
call StoreString(udg_gc, s, "target", "instant")
call StoreString(udg_gc, s, "aoetype", "ally")
call StoreString(udg_gc, s, "damagetype", "holy")
call StoreReal(udg_gc, s, "dmgbase", -30)
call StoreReal(udg_gc, s, "dmglevel", 0)
call StoreReal(udg_gc, s, "aoebase", 400)
call StoreReal(udg_gc, s, "aoelevel", 0)
call StoreReal(udg_gc, s, "dmgstr", 0)
call StoreReal(udg_gc, s, "dmgagi", 0)
call StoreReal(udg_gc, s, "dmgint", -2)
// Shadowword Pain - Unit
set s = "A" + I2S('A06K')
call StoreString(udg_gc, s, "target", "unit")
call StoreString(udg_gc, s, "aoetype", "enemy") // What is targeted (ally/enemy/any)
call StoreString(udg_gc, s, "damagetype", "dark")
call StoreReal(udg_gc, s, "dmgbase", 0) // Damage base
call StoreReal(udg_gc, s, "dmglevel", 5) // Damage per ability level
call StoreReal(udg_gc, s, "dmgstr", 0) // Strength factor
call StoreReal(udg_gc, s, "dmgagi", 0) // Agility factor
call StoreReal(udg_gc, s, "dmgint", 1) // Intelligence factor; note the negative for healing
call StoreInteger(udg_gc, s, "dotwaves", 7)
call StoreReal(udg_gc, s, "dotbreak", 2)
call StoreReal(udg_gc, s, "dotdmgbase", 0)
call StoreReal(udg_gc, s, "dotdmglevel", 5)
call StoreReal(udg_gc, s, "dotdmgstr", 0)
call StoreReal(udg_gc, s, "dotdmgagi", 0)
call StoreReal(udg_gc, s, "dotdmgint", 1)
// ----
// Mage
// ----
// Firebolt
set s = "A" + I2S('A045')
call StoreString(udg_gc, s, "target", "unit")
call StoreReal(udg_gc, s, "dmgbase", 5)
call StoreReal(udg_gc, s, "dmglevel", 0)
call StoreString(udg_gc, s, "damagetype", "fire")
call StoreReal(udg_gc, s, "dmgstr", 0)
call StoreReal(udg_gc, s, "dmgagi", 0)
call StoreReal(udg_gc, s, "dmgint", 5)
// Blizzard (new)
set s = "A" + I2S('A04B')
call StoreString(udg_gc, s, "target", "point") // Targeting type
call StoreString(udg_gc, s, "aoetype", "enemy") // What is targeted (ally/enemy/any)
call StoreString(udg_gc, s, "damagetype", "ice") // Damage type (data added in DamageTypeBonus function)
call StoreReal(udg_gc, s, "dmgbase", 5) // Damage base
call StoreReal(udg_gc, s, "dmglevel", 0) // Damage per ability level
call StoreReal(udg_gc, s, "aoebase", 400)
call StoreReal(udg_gc, s, "aoelevel", 0)
call StoreReal(udg_gc, s, "dmgstr", 0) // Strength factor
call StoreReal(udg_gc, s, "dmgagi", 0) // Agility factor
call StoreReal(udg_gc, s, "dmgint", 2) // Intelligence factor; note the negative for healing
// Water Elemental: Crushing Wave
set s = "A" + I2S('A04I')
call StoreString(udg_gc, s, "target", "point")
call StoreString(udg_gc, s, "aoetype", "enemy")
call StoreReal(udg_gc, s, "dmgbase", 0)
call StoreReal(udg_gc, s, "dmglevel", 5)
call StoreString(udg_gc, s, "damagetype", "ice")
call StoreReal(udg_gc, s, "aoebase", 300)
call StoreReal(udg_gc, s, "aoelevel", 0)
call StoreReal(udg_gc, s, "dmgstr", 0)
call StoreReal(udg_gc, s, "dmgagi", 0)
call StoreReal(udg_gc, s, "dmgint", 10)
// Lightning Explosion - Instant
set s = "A" + I2S('A065')
call StoreString(udg_gc, s, "target", "instant")
call StoreString(udg_gc, s, "aoetype", "enemy")
call StoreString(udg_gc, s, "damagetype", "lightning")
call StoreReal(udg_gc, s, "dmgbase", 50)
call StoreReal(udg_gc, s, "dmglevel", 0)
call StoreReal(udg_gc, s, "aoebase", 250)
call StoreReal(udg_gc, s, "aoelevel", 0)
call StoreReal(udg_gc, s, "dmgstr", 0)
call StoreReal(udg_gc, s, "dmgagi", 0)
call StoreReal(udg_gc, s, "dmgint", 5)
// -----
// Ninja
// -----
// Deadly Strike - Unit
set s = "A" + I2S('A07C')
call StoreString(udg_gc, s, "target", "unit")
call StoreReal(udg_gc, s, "dmgbase", 0)
call StoreReal(udg_gc, s, "dmglevel", 5)
call StoreString(udg_gc, s, "damagetype", "normal")
call StoreSound(s, "soundcaster", "Sound\\Units\\Combat\\MetalHeavySliceMetal3.wav")
call StoreString(udg_gc, s, "effectattach", "origin")
call StoreString(udg_gc, s, "effectmodel", "Objects\\Spawnmodels\\Human\\HumanBlood\\HumanBloodFootman.mdl")
call StoreString(udg_gc, s, "effectattachdot", "origin")
call StoreString(udg_gc, s, "effectmodeldot", "Objects\\Spawnmodels\\Human\\HumanBlood\\HumanBloodFootman.mdl")
call StoreReal(udg_gc, s, "dmgstr", 0)
call StoreReal(udg_gc, s, "dmgagi", 12)
call StoreReal(udg_gc, s, "dmgint", 0)
call StoreInteger(udg_gc, s, "dotwaves", 3)
call StoreReal(udg_gc, s, "dotbreak", 2)
call StoreReal(udg_gc, s, "dotdmgbase", 0)
call StoreReal(udg_gc, s, "dotdmglevel", 5)
call StoreReal(udg_gc, s, "dotdmgstr", 0)
call StoreReal(udg_gc, s, "dotdmgagi", 6)
call StoreReal(udg_gc, s, "dotdmgint", 0)
// Fan of Knives
set s = "A" + I2S('A077')
call StoreString(udg_gc, s, "target", "instant") // Targeting type
call StoreString(udg_gc, s, "aoetype", "enemy") // What is targeted (ally/enemy/any)
call StoreString(udg_gc, s, "damagetype", "normal") // Damage type (data added in DamageTypeBonus function)
call StoreReal(udg_gc, s, "dmgbase", 0) // Damage base
call StoreReal(udg_gc, s, "dmglevel",10) // Damage per ability level
call StoreReal(udg_gc, s, "aoebase", 400)
call StoreReal(udg_gc, s, "aoelevel", 0)
call StoreReal(udg_gc, s, "dmgstr", 0) // Strength factor
call StoreReal(udg_gc, s, "dmgagi", 8) // Agility factor
call StoreReal(udg_gc, s, "dmgint", 0) // Intelligence factor; note the negative for healing
// -----------------
// Tigeran Berserker
// -----------------
// Brutal Strike
set s = "A" + I2S('A00E')
call StoreString(udg_gc, s, "target", "unit")
call StoreReal(udg_gc, s, "dmgbase", 10)
call StoreReal(udg_gc, s, "dmglevel", 5)
call StoreString(udg_gc, s, "damagetype", "normal")
call StoreSound(s, "soundcaster", "Sound\\Units\\Combat\\MetalHeavySliceMetal3.wav")
call StoreString(udg_gc, s, "effectattach", "origin")
call StoreString(udg_gc, s, "effectmodel", "Objects\\Spawnmodels\\Orc\\Orcblood\\OrcBloodGrunt.mdl")
call StoreString(udg_gc, s, "effectattachdot", "origin")
call StoreString(udg_gc, s, "effectmodeldot", "Objects\\Spawnmodels\\Orc\\Orcblood\\OrcBloodGrunt.mdl")
call StoreReal(udg_gc, s, "dmgstr", 3)
call StoreReal(udg_gc, s, "dmgagi", 3)
call StoreReal(udg_gc, s, "dmgint", 0)
call StoreInteger(udg_gc, s, "dotwaves", 3)
call StoreReal(udg_gc, s, "dotbreak", 3)
call StoreReal(udg_gc, s, "dotdmgbase", 0)
call StoreReal(udg_gc, s, "dotdmglevel", 5)
call StoreReal(udg_gc, s, "dotdmgstr", 3)
call StoreReal(udg_gc, s, "dotdmgagi", 3)
call StoreReal(udg_gc, s, "dotdmgint", 0)
// -------
// Druid
// -------
// Rejuvenation
set s = "A" + I2S('A064')
call StoreString(udg_gc, s, "target", "unit")
call StoreString(udg_gc, s, "aoetype", "ally") // What is targeted (ally/enemy/any)
call StoreString(udg_gc, s, "damagetype", "nature")
call StoreReal(udg_gc, s, "dmgbase", 0) // Damage base
call StoreReal(udg_gc, s, "dmglevel", 0) // Damage per ability level
call StoreReal(udg_gc, s, "dmgstr", 0) // Strength factor
call StoreReal(udg_gc, s, "dmgagi", 0) // Agility factor
call StoreReal(udg_gc, s, "dmgint", 0) // Intelligence factor; note the negative for healing
call StoreInteger(udg_gc, s, "dotwaves", 14)
call StoreReal(udg_gc, s, "dotbreak", 1)
call StoreReal(udg_gc, s, "dotdmgbase", 0)
call StoreReal(udg_gc, s, "dotdmglevel", 0)
call StoreReal(udg_gc, s, "dotdmgstr", 0)
call StoreReal(udg_gc, s, "dotdmgagi", 0)
call StoreReal(udg_gc, s, "dotdmgint", -1)
// --------
// Examples
// --------
//Healing Blast - Point
// set s = "A" + I2S('A001')
// call StoreString(udg_gc, s, "target", "point") // Targeting type
// call StoreString(udg_gc, s, "aoetype", "ally") // What is targeted (ally/enemy/any)
// call StoreString(udg_gc, s, "damagetype", "holy") // Damage type (data added in DamageTypeBonus function)
// call StoreReal(udg_gc, s, "dmgbase", -120) // Damage base
// call StoreReal(udg_gc, s, "dmglevel", -60) // Damage per ability level
// call StoreReal(udg_gc, s, "aoebase", 150) // AoE base
// call StoreReal(udg_gc, s, "aoelevel", 50) // AoE per level
// call StoreSound(s, "soundcaster", "Units\\Human\\Priest\\PriestReady1.wav") // Sound to play at caster (local, can overlap)
// call StoreSound(s, "soundtarget", "Abilities\\Spells\\Human\\InnerFire\\InnerFireBirth.wav") // Sound to play at target (local, can overlap)
// call StoreReal(udg_gc, s, "dmgstr", 0) // Strength factor
// call StoreReal(udg_gc, s, "dmgagi", 0) // Agility factor
// call StoreReal(udg_gc, s, "dmgint", -3.5) // Intelligence factor; note the negative for healing
//Consecrate - Instant
// set s = "A" + I2S('A002')
// call StoreString(udg_gc, s, "target", "instant")
// call StoreString(udg_gc, s, "aoetype", "enemy")
// call StoreString(udg_gc, s, "damagetype", "holy")
// call StoreReal(udg_gc, s, "dmgbase", 50)
// call StoreReal(udg_gc, s, "dmglevel", 25)
// call StoreReal(udg_gc, s, "aoebase", 200)
// call StoreReal(udg_gc, s, "aoelevel", 25)
// call StoreSound(s, "soundcaster", "Units\\Human\\Priest\\PriestYesAttack1.wav")
// call StoreSound(s, "soundtarget", "Abilities\\Spells\\Human\\Resurrection\\ResurrectTarget.wav")
// call StoreString(udg_gc, s, "effectmodelaoe", "Consecrate.mdx") // Model for AoE; not essential, but enable control over duration
// call StoreReal(udg_gc, s, "effectlengthaoe", 7.5) // Duration of AoE model
// call StoreReal(udg_gc, s, "dmgstr", 0)
// call StoreReal(udg_gc, s, "dmgagi", 0)
// call StoreReal(udg_gc, s, "dmgint", 2)
// call StoreString(udg_gc, s, "effectattachdotaoe", "origin") // AoE DoT effect attachment point
// call StoreString(udg_gc, s, "effectmodeldotaoe", "Abilities\\Spells\\Other\\BreathOfFire\\BreathOfFireDamage.mdl") // AoE DoT effect model
// call StoreString(udg_gc, s, "dotaoetype", "invert")
// call StoreInteger(udg_gc, s, "dotaoewaves", 3) // Number of DoT AoE waves
// call StoreReal(udg_gc, s, "dotaoebreak", 3) // Gap between waves
// call StoreReal(udg_gc, s, "dotaoedmgbase", 50)
// call StoreReal(udg_gc, s, "dotaoedmglevel", 25)
// call StoreReal(udg_gc, s, "dotaoedmgstr", 0)
// call StoreReal(udg_gc, s, "dotaoedmgagi", 0)
// call StoreReal(udg_gc, s, "dotaoedmgint", 2)
//Fire Strike - Unit
// set s = "A" + I2S('A000')
// call StoreString(udg_gc, s, "target", "unit")
// call StoreReal(udg_gc, s, "dmgbase", 100)
// call StoreReal(udg_gc, s, "dmglevel", 50)
// call StoreString(udg_gc, s, "damagetype", "fire")
// call StoreSound(s, "soundcaster", "Units\\Human\\BloodElfSpellThief\\SpellbreakerWarcry1.wav")
// call StoreSound(s, "soundtarget", "Abilities\\Spells\\Human\\FlameStrike\\FlameStrikeBirth1.wav")
// call StoreReal(udg_gc, s, "dmgstr", 0)
// call StoreReal(udg_gc, s, "dmgagi", 0)
// call StoreReal(udg_gc, s, "dmgint", 3)
// call StoreString(udg_gc, s, "effectattachdot", "chest")
// call StoreString(udg_gc, s, "effectmodeldot", "Abilities\\Spells\\Other\\BreathOfFire\\BreathOfFireDamage.mdl")
// call StoreInteger(udg_gc, s, "dotwaves", 4)
// call StoreReal(udg_gc, s, "dotbreak", 4)
// call StoreReal(udg_gc, s, "dotdmgbase", 10)
// call StoreReal(udg_gc, s, "dotdmglevel", 5)
// call StoreReal(udg_gc, s, "dotdmgstr", 0)
// call StoreReal(udg_gc, s, "dotdmgagi", 0)
// call StoreReal(udg_gc, s, "dotdmgint", 1)
//Star Nova - Unit
// set s = "A" + I2S('A003')
// call StoreString(udg_gc, s, "target", "unit")
// call StoreReal(udg_gc, s, "dmgbase", 250)
// call StoreReal(udg_gc, s, "dmglevel", 75)
// call StoreString(udg_gc, s, "damagetype", "arcane")
// call StoreSound(s, "soundcaster", "Units\\Human\\Sorceress\\SorceressYesAttack2.wav")
// call StoreSound(s, "soundtarget", "Sound\\Ambient\\DoodadEffects\\ShimmeringPortalDeath.wav")
// call StoreReal(udg_gc, s, "dmgstr", 0)
// call StoreReal(udg_gc, s, "dmgagi", 0)
// call StoreReal(udg_gc, s, "dmgint", 5)
//Wraith Strike - Unit = 1
// set s = "A" + I2S('A004')
// call StoreString(udg_gc, s, "target", "unit")
// call StoreReal(udg_gc, s, "cooldown", 55)
// call StoreReal(udg_gc, s, "dmgbase", 150)
// call StoreReal(udg_gc, s, "dmglevel", 75)
// call StoreString(udg_gc, s, "damagetype", "dark")
// call StoreSound(s, "soundtarget", "Abilities\\Spells\\Undead\\DeathCoil\\DeathCoilMissileLaunch1.wav")
// call StoreReal(udg_gc, s, "dmgstr", 2)
// call StoreReal(udg_gc, s, "dmgagi", 0)
// call StoreReal(udg_gc, s, "dmgint", 2)
// call StoreString(udg_gc, s, "effectattachdot", "overhead")
// call StoreString(udg_gc, s, "effectmodeldot", "Abilities\\Spells\\Other\\AcidBomb\\BottleImpact.mdl")
// call StoreInteger(udg_gc, s, "dotwaves", 4)
// call StoreReal(udg_gc, s, "dotbreak", 2)
// call StoreReal(udg_gc, s, "dotdmgbase", 25)
// call StoreReal(udg_gc, s, "dotdmglevel", 15)
// call StoreReal(udg_gc, s, "dotdmgstr", 1)
// call StoreReal(udg_gc, s, "dotdmgagi", 0)
// call StoreReal(udg_gc, s, "dotdmgint", 1)
//Fire Wave - Cone
// set s = "A" + I2S('A005')
// call StoreString(udg_gc, s, "target", "cone")
// call StoreString(udg_gc, s, "aoetype", "enemy")
// call StoreString(udg_gc, s, "damagetype", "fire")
// call StoreReal(udg_gc, s, "dmgbase", 100)
// call StoreReal(udg_gc, s, "dmglevel", 25)
// call StoreReal(udg_gc, s, "aoebase", 800)
// call StoreReal(udg_gc, s, "aoelevel", 0)
// call StoreReal(udg_gc, s, "aoestartbase", 50) // Currently unsupported.
// call StoreReal(udg_gc, s, "aoefinishbase", 150)
// call StoreReal(udg_gc, s, "dmgstr", 0)
// call StoreReal(udg_gc, s, "dmgagi", 0)
// call StoreReal(udg_gc, s, "dmgint", 2)
// call StoreString(udg_gc, s, "effectattachdotstick", "origin")
// call StoreString(udg_gc, s, "effectmodeldotstick", "Abilities\\Spells\\Other\\BreathOfFire\\BreathOfFireDamage.mdl")
// call StoreInteger(udg_gc, s, "dotstickwaves", 5)
// call StoreReal(udg_gc, s, "dotstickbreak", 3)
// call StoreReal(udg_gc, s, "dotstickdmgbase", 5)
// call StoreReal(udg_gc, s, "dotstickdmglevel", 5)
// call StoreReal(udg_gc, s, "dotstickdmgstr", 0)
// call StoreReal(udg_gc, s, "dotstickdmgagi", 0)
// call StoreReal(udg_gc, s, "dotstickdmgint", 1)
// Unit Type Setup (This can be used to override for individual unit types)
// At present only works for instant damage calculations.
// NB: This is not really supported.
////Ability name + Unit Name
//set s = "A" + I2S('A000') + ";" + I2S('H000')
//call StoreReal(udg_gc, s, "dmgbase", 43)
//call StoreReal(udg_gc, s, "dmglevel", 6)
//call StoreReal(udg_gc, s, "dmgstr", 2)
//call StoreReal(udg_gc, s, "dmgagi", 2)
//call StoreReal(udg_gc, s, "dmgint", 0)
endfunction
//===========================================================================
function InitTrig_CG_Casting_Setup takes nothing returns nothing
set gg_trg_CG_Casting_Setup = CreateTrigger( )
call TriggerAddAction( gg_trg_CG_Casting_Setup, function Trig_CG_CADS_Init_Actions )
endfunction
//TESH.scrollpos=62
//TESH.alwaysfold=0
function Trig_CG_Casting_Conditions takes nothing returns boolean
// local string s = GetStoredString(udg_gc, "A" + I2S(GetSpellAbilityId()), "target")
// return s == "unit" or s == "point" or s == "instant" or s == "cone"
return HaveStoredString(udg_gc, "A" + I2S(GetSpellAbilityId()), "target")
endfunction
function Trig_CG_Casting_Actions takes nothing returns nothing
local integer id = GetSpellAbilityId()
local string sid = "A" + I2S(id)
local location l = GetSpellTargetLoc()
local unit u1 = GetTriggerUnit()
local unit u2 = GetSpellTargetUnit()
local unit uloop
local real x2
local real y2
local integer i = H2I(u1)
local integer it
local string s = I2S(i)
local string st
local sound so1
local sound so2
local real angle
local real anglevar
local real angle1
local real angle2
local real aoe
local real aoeStart
local real aoeFinish
local group g = CreateGroup()
local boolexpr b
local string target = GetStoredString(udg_gc, sid, "target")
local real xc1
local real xc2
local real yc1
local real yc2
// if spell is blizzard wait a bit
if id == 'A04J' then
call TriggerSleepAction( 0.70 )
endif
// Blizzard new
if id == 'A04B' then
call TriggerSleepAction( 0.70 )
endif
// if spell is firebolt wait a bit
if id == 'A045' then
call TriggerSleepAction( 0.70 )
endif
if target == "unit" then
set x2 = GetUnitX(u2)
set y2 = GetUnitY(u2)
elseif target == "point" then
set x2 = GetLocationX(l)
set y2 = GetLocationY(l)
elseif target == "instant" then
set x2 = GetUnitX(u1)
set y2 = GetUnitY(u1)
elseif target == "cone" then
set x2 = GetUnitX(u1)
set y2 = GetUnitY(u1)
set angle = bj_RADTODEG * Atan2(GetLocationY(l) - y2, GetLocationX(l) - x2)
endif
if HaveStoredString(udg_gc, sid, "soundcaster") then
set so1 = CreateSound(GetStoredString(udg_gc, sid, "soundcaster"), false, true, true, 12700, 12700, "")
call AttachSoundToUnit(so1, u1)
call StartSound(so1)
call KillSoundWhenDone(so1)
endif
if HaveStoredString(udg_gc, sid, "soundtarget") then
set so2 = CreateSound(GetStoredString(udg_gc, sid, "soundtarget"), false, true, true, 12700, 12700, "")
if target == "unit" then
call AttachSoundToUnit(so2, u2)
else
call SetSoundPosition(so2, x2, y2, 30)
endif
call StartSound(so2)
call KillSoundWhenDone(so2)
endif
if target == "unit" or ( target == "instant" and HaveStoredString(udg_gc, sid, "aoetype") == false ) then
call DealDamage(u1, u2, id, sid)
endif
if HaveStoredInteger(udg_gc, sid, "dotaoewaves") then
set it = H2I(CreateTimer())
set st = I2S(it)
call StoreInteger(udg_gc, st, "unit", i)
call StoreString(udg_gc, st, "sid", sid)
call StoreReal(udg_gc, st, "x", x2)
call StoreReal(udg_gc, st, "y", y2)
call StoreInteger(udg_gc, st, "lvl", GetUnitAbilityLevel(u1, id))
call StoreInteger(udg_gc, st, "c", GetStoredInteger(udg_gc, sid, "dotaoewaves"))
call StoreReal(udg_gc, st, "gap", GetStoredReal(udg_gc, sid, "dotaoebreak"))
call TimerAttach(I2T(it), GetStoredReal(udg_gc, sid, "dotaoebreak"), it, function DoTeffectAoE)
endif
if HaveStoredString(udg_gc, sid, "aoetype") then
set b = aoeBool(GetStoredString(udg_gc, sid, "aoetype"), GetOwningPlayer(u1))
set aoe = GetStoredReal(udg_gc, sid, "aoebase") + (GetStoredReal(udg_gc, sid, "aoelevel") * GetUnitAbilityLevel(u1, id))
if target == "cone" then
set aoeStart = GetStoredReal(udg_gc, sid, "aoestartbase") + (GetStoredReal(udg_gc, sid, "aoestartlevel") * GetUnitAbilityLevel(u1, id))
set aoeFinish = GetStoredReal(udg_gc, sid, "aoefinishbase") + (GetStoredReal(udg_gc, sid, "aoefinishlevel") * GetUnitAbilityLevel(u1, id))
set anglevar = bj_RADTODEG * Acos( ( (2 * aoe * aoe) - (aoeFinish * aoeFinish) ) / ( 8 * aoe * aoe ) ) / 2
set angle1 = angle - anglevar
set angle2 = angle + anglevar
endif
call GroupEnumUnitsInRange(g, x2, y2, aoe, b)
loop
set uloop = FirstOfGroup(g)
exitwhen uloop == null
if target != "cone" or ( target == "cone" and InCone(angle1, angle2, x2, y2, uloop) ) then
call DealDamage(u1, uloop, id, sid)
if HaveStoredString(udg_gc, sid, "effectmodeldotaoe") then
call DestroyEffectTimed(AddSpecialEffectTarget(GetStoredString(udg_gc, sid, "effectmodeldotaoe"), uloop, GetStoredString(udg_gc, sid, "effectattachdotaoe")), GetStoredReal(udg_gc, sid, "dotaoebreak"))
endif
if HaveStoredInteger(udg_gc, sid, "dotstickwaves") then
set it = H2I(CreateTimer())
set st = I2S(it)
call StoreString(udg_gc, st, "typ", "stick")
call StoreInteger(udg_gc, st, "u1", i)
call StoreInteger(udg_gc, st, "u2", H2I(uloop))
call StoreString(udg_gc, st, "sid", sid)
call StoreInteger(udg_gc, st, "lvl", GetUnitAbilityLevel(u1, id))
call StoreInteger(udg_gc, st, "c", GetStoredInteger(udg_gc, sid, "dotstickwaves"))
call StoreReal(udg_gc, st, "gap", GetStoredReal(udg_gc, sid, "dotstickbreak"))
call TimerAttach(I2T(it), GetStoredReal(udg_gc, sid, "dotstickbreak"), it, function DoTeffect)
if HaveStoredString(udg_gc, sid, "effectmodeldotstick") then
call DestroyEffectTimed(AddSpecialEffectTarget(GetStoredString(udg_gc, sid, "effectmodeldotstick"), uloop, GetStoredString(udg_gc, sid, "effectattachdotstick")), GetStoredReal(udg_gc, sid, "dotstickbreak"))
endif
endif
endif
call GroupRemoveUnit(g, uloop)
endloop
call DestroyBoolExpr(b)
endif
if HaveStoredInteger(udg_gc, sid, "dotwaves") then
set it = H2I(CreateTimer())
set st = I2S(it)
call StoreString(udg_gc, st, "typ", "")
call StoreInteger(udg_gc, st, "u1", i)
call StoreInteger(udg_gc, st, "u2", H2I(u2))
call StoreString(udg_gc, st, "sid", sid)
call StoreInteger(udg_gc, st, "lvl", GetUnitAbilityLevel(u1, id))
call StoreInteger(udg_gc, st, "c", GetStoredInteger(udg_gc, sid, "dotwaves"))
call StoreReal(udg_gc, st, "gap", GetStoredReal(udg_gc, sid, "dotbreak"))
call TimerAttach(I2T(it), GetStoredReal(udg_gc, sid, "dotbreak"), it, function DoTeffect)
if HaveStoredString(udg_gc, sid, "effectmodeldot") then
call DestroyEffectTimed(AddSpecialEffectTarget(GetStoredString(udg_gc, sid, "effectmodeldot"), u2, GetStoredString(udg_gc, sid, "effectattachdot")), GetStoredReal(udg_gc, sid, "dotbreak"))
endif
endif
if HaveStoredString(udg_gc, sid, "effectmodelaoe") then
call DestroyEffectTimed(AddSpecialEffect(GetStoredString(udg_gc, sid, "effectmodelaoe"), x2, y2), GetStoredReal(udg_gc, sid, "effectlengthaoe"))
endif
call RemoveLocation(l)
set l = null
call DestroyGroup(g)
set g = null
set b = null
set so1 = null
set so2 = null
set u1 = null
set u2 = null
set uloop = null
endfunction
//===========================================================================
function InitTrig_CG_Casting takes nothing returns nothing
set gg_trg_CG_Casting = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_CG_Casting, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_CG_Casting, Condition( function Trig_CG_Casting_Conditions ) )
call TriggerAddAction( gg_trg_CG_Casting, function Trig_CG_Casting_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
This is the JumpSystem made by Waldbaer.
It is included with permission.
If you use this or you may choose to use a different system for the jumping functions.
But if you use it, you must give credit to Waldbaer too for this.
You will find the latest version and support for this system here:
http://www.wc3campaigns.net/showthread.php?t=87831
===========================================================================
What this tutorial tells
===========================================================================
The intention of this tutorial is to make you know so much of using JASS
that you can use the jump system effectively whithout problems. If you want
to know more about JASS in general, we recommend that you read one or more
of the tutorials at
www.wc3campaigns.net or www.wc3sear.ch.
===========================================================================
What is JASS?
===========================================================================
JASS is the scripting language Blizzard developed and used for Warcraft 3.
In fact, nearly everything the world editor does is JASS, but in most cases
you don't see it. Just to see how it looks, you should once just choose one
more or less simple trigger you designed and select Convert to Custom Text
from the menu edit.
What you see now is what is saved in the map actually and is read and exe-
cuted by War3. It is generated JASS text the World Editor creates for you
if you select events, conditions and actions in the GUI (Graphical User
Interface). You could type this text on your own and it would have the
same effect.
JASS consists of so called functions. They are something like mini programs
and there are two different types of functions: so called natives, that
means functions that are hard coded in Warcraft III and custom functions,
that are written completely in JASS and only use the natives as base. The
jump system is a collection of custom functions and you can execute them
whenever you need them in your map.
Some functions return values that you can use and you know that from GUI:
Everything listed as "function" in the Trigger Editor is actually a
function that returns a value. E.g. if you click 'Triggering Unit' this
just calls the JASS function GetTriggerUnit() that returns the unit which
caused the event of your trigger and that unit is what you actually want.
===========================================================================
How to use the Jump System
===========================================================================
In your normal triggers, you can insert single lines of JASS directly if
you use the action General - Custom Text.
In JASS, every line calls exactly one function. Everytime you want just to
execute a function ignoring the value it might return, e.g. one from the
jump system, you have to begin the line with the word 'call'.
Then the name of the function and brackets follow. JASS is case sensitive,
that means you have to pay attention that you write capital letters only
if they are really needed. If you type anything wrong, you'll get an error
message when saving the next time!
Sometimes a function needs additional data, e.g. the function
DCJS_Jump needs the unit that you want to jump, the location where you want
it to land, the height of the jump and the time the jump will take. You
have to write this data into the brackets, seperated with ','. Make sure
you don't screw up the order!
For the time and the height you just write the values, e.g.'1.5' and '200'.
For the unit, there is another difficulty of JASS: You need the JASS name
of the unit. It is constructed as follows:
gg_unit_UnitTypeRawcode_Number
You can find out the unit type's rawcode by searching for the unit type in
the object editor and then pressing Ctrl+D. Now the real names disappear
and instead a four letter long code appears, e.g. hfoo for the soldier.
The number is the one you also see if you just select the unit in the world
editor. You can also find out a unit's JASS name by converting a trigger
using the unit (e.g. just "Remove Unit") to custom text and copy and paste
it from there (you should find it in the second line).
The easiest way to get a location is to write
Location( x-coordinate, y-coordinate).
In the end, your JASS line should look e.g. like this:
call DCJS_Jump( gg_unit_hfoo_0001, Location( 200, -400), 200, 1.5 )
To refer to a variable you created in the variables window, insert udg_
before its normal name.
You also always can insert a mathematical expression or the name of a
function that returns a value of the type you need (e.g. Location() is
already a function). Some such functions that might be useful in connection
with the jump system are listed up and explained in the next part.
===========================================================================
Some common functions in connection with the jump system
===========================================================================
If you use one of the following functions, copy their name and put a value
into the brackets for each of the variables after the 'take' and before the
'returns'. Every variable is mentioned with its type and then an example
name, e.g. for the line
function GetUnitLoc takes unit u returns location
the needed type is unit and u is the example name. The name mainly is shown
to help you to find out the variables role in the function. So write e.g.
GetUnitLoc( gg_unit_hfoo_0001 )
This might be useful if you e.g. want one unit jump to the position of ano-
ther one, because this function returns the location where the input unit
stands at this moment. To use it making unit nr 0002 jump on unit 0001, you
write
call DCJS_Jump( gg_unit_hfoo_0002, GetUnitLoc( gg_unit_hfoo_0001), 3, 1.5 )
function GetRectCenter takes rect r returns location
>>Returns the center of a rect; a common way to define locations in cinema-
tics. The JASS name of rects is constructed this way:
gg_rct_NameOfTheRect
In the name, spaces are replaced by '_'.
function GetEnumUnit takes nothing returns unit
>>Returns the unit of a unit loop, it is just "PickedUnit" in GUI.
function GetTriggerUnit takes nothing returns unit
>>Returns the unit that caused the trigger's event, in GUI it is called
"TriggeringUnit".
function PolarProjectionBJ takes location source, real distance, real angle returns location
>>Returns the location which is the distance away from the source in direc-
tion of the input degree angle. May be useful in combination with
GetUnitLoc when used in loops.
function GetSpellTargetLoc takes nothing returns location
>>The target of the spell connected with the event of the trigger, e.g. in
connection with the event "unit starts the effect of an ability".
function GetUnitMoveSpeed takes unit whichUnit returns real
>>Returns the current movement speed of the input unit.
function SetUnitAnimationByIndex takes unit u, integer index returns location
>>This will make the unit perform one special animation. This function has
some advantages to the GUI action Set Unit Animation:
-it definately will do this animation and no other, also if the model has
e.g. two different attack animations
-it works while jumping because it is not interrupted by Move Unit
(instantly)
To find out the correct index number, you will have to try it out or open
the model itself and count the animations to the wished one beginning with
zero. To do this, use e.g. Wc3Viewer™ by TheProphet.
To get the name and use of other functions, just use them in an empty GUI
trigger and convert that to custom text. You should find it in the second
line.
Now you should be ready to continue with "General Info and Function Des-
cription"!
===========================================================================
Implementation into your map
===========================================================================
Before you can use the functions of the JumpSystem in your map, you have to
build them in and create the variables. To do that, copy everything that
is displayed in the main window if you click on the map icon on the top
left of the trigger list to the same area in your own map. Then also copy
and paste the trigger DCJS Init to your map and save. When you did that,
the WE should have created all needed variables automatically.
If it did not, the trigger is displayed not active. In this case delete the
trigger and go to the global preferences of the WE and select the category
"General". There you have to activate "Automatically create unknown varia-
bles while pasting trigger data". Click OK and paste the trigger again.
Now everything should be ready to use and work correctly.
===========================================================================
The main functions with explainations of their effect
===========================================================================
function DCJS_Jump takes unit u, location target, real height, real time returns nothing
>>This causes the input unit to jump to the target with the maximum rela-
tive altitude of the input height during the input time departing from the
current position of the unit. The unit won't face or animate in any way if
you do notuse additional actions. To animate it during the jump, use the
JASS function SetUnitAnimationByIndex (explained in the "Intro for people
new to JASS").
function DCJS_JumpSpeed takes unit u, location target, real height, real speed returns nothing
>>Has the same effect as DCJS_Jump, but instead of using time for control-
ling the duration/speed of a jump, it uses a walking speed. May be easier
to use if you want a unit to jump with its exact current walking speed.
function DCJS_Bounce takes unit u, location newtarget returns nothing
>>This will change the horizontal direction and speed of the input jumping
unit making it land on the input location. The time to get to the new tar-
get will be just the remaining time of the original jump, so use it care-
fully to prevent the effect from looking silly.
function DCJS_EndJump takes unit u, boolean StopHeightChange returns nothing
>>This will interrupt the jump of a unit. If the boolean input is true, the
unit will rest exactly in its current position in the air. If it is false,
Just the horizontal movement stops and the vertical movement will be conti-
nued as normally. This may be useful if you e.g. make a unit jump against a
wall.
===========================================================================
Helper functions with explainations of their effect
===========================================================================
function IsLocPathable takes location target returns boolean
>>Checks if a location can be walked on by ground units or not
function GetNearestPathableLoc takes location source returns location
>>Returns a location that is pathable for ground units at any cost. If the
source location is not pathable, it will return the nearest pathable loca-
tion. May be useful to prevent a unit from jumping to normally unpathable
locations.
===========================================================================
Notes
===========================================================================
- The JumpSystem does not work reliably on Map Initialization. Use
Gametime = 0 seconds instead.
- If the JumpSystem directly refers to a unit (e.g. the input unit is
gg_unit_hfoo_0001), but this unit is not used in any other GUI-Trigger, the
Jump does not work because the unit variable does not exist. There is no
solution against this issue except creating a trigger using the unit, maybe
one without an event.
Functions are not influenced of this; e.g. GetTriggerUnit() works with ev-
ery unit, no matter if it is used anywhere else.
- To pause a unit's jump, just remove it from the unit group DCJS_Jumpers.
To unpause it, add the unit again. To cancel a jump completely, you should
nevertheless use DCJS_EndJump to delete alsothe created variables which
otherways just stay as brakes in the memory.
- The Jump System's height correction does not work correctly if you want a
ground unit jump across water. This problem cannot be solved by the system
since it is a problem in blizzard's programming. You can workaround it by
using a custom water model instead of blizzard's or using a swimming unit
when you have to jump across water.
- You can post your comment to the System either at www.wc3campaings.net or
at www.dragonblood-creations.de in the according forum thread.
Thanks in advance for this!
===========================================================================
Dragonblood Creations' Jump System Version History
===========================================================================
>>Version 2.0.1
- Performance improvements (new structure of the variables)
- Savety enquiry added in EndJump and Bounce, to check if the input unit is
actually jumping
- Added prefix DCJS_ also to the functions H2I and I2U to prevent conflicts
with other systems
>>Version 2.0
- Added the function DCJS_Bounce
- The Jump functions now also work correctly with a unit starting the jump
in the air. May be useful to let a unit jump from an object that actually
does not influence pathing at all.
- Major performance improvements (the system now uses very few gameccache
storing the needed values in a global real array called DCJS_Data; the
z-correction is now based on time instead of distance, saving some calcu-
lating in the loop)
- Bugfix: When using DCJS_EndJump with StopHeightChange = false, the unit
will no longer be teleported to the original target when reaching ground
>>Version 1.1
- Added the function DCJS_JumpSpeed, which is based on a movement speed in-
stead of the total time of the jump
- Added the helper function IsLocPathable returning if a location is patha-
ble or not
- Added the helper function GetNearestPathableLoc returning the nearest
pathable location beginning from an input location
>>Version 1.0.5
- Removed a minor configuration possibility that did not work as described
>>Version 1.0.4
- Some more technical advancements
>>Version 1.0.3
- Killed some additional leaks
>>Version 1.0.2
- Different technical advancements
- Simple Jump spell for testing included in the demo map
>>Version 1.0.1
- Killed some leaks
>>Version 1.0
First Release featuring
- Makes units jump with a single line of code
- Realistic flying curve (also if you jump e.g. over a canyon)
- Fully multiinstanceable, that means it can be used as often as you want
at the same time
- English and German Tutorials, also for people new to JASS
GameCache
¯¯¯¯¯¯¯¯¯
The following values are stored in GameCache:
Mission Name Type Comment
I2S( unit ) "Number" integer for every unit jumping
I2S( Number ) "Unit" integer for every unit jumping
"Units" "Count" integer
Data Array
¯¯¯¯¯¯¯¯¯¯
The data for each unit's jump is stored in the real array DCJS Data with index
The unit's number (stored in GameCache) * 9 + the numbers below
0 Target X
1 Target Y
2 X-Offset how far the unit is moved every time in the loop during the jump
3 Y-Offset how far the unit is moved every time in the loop during the jump
4 Z-correction value 1
5 Z-correction value 2
6 Z-correction value 3
7 Time elapsed since the beginning of the jump
8 Total time of the jump