Name | Type | is_array | initial_value |
//TESH.scrollpos=8
//TESH.alwaysfold=0
scope Init initializer i
globals
private unit u
endglobals
private function cond takes nothing returns boolean
call SetFloatGameState(GAME_STATE_TIME_OF_DAY, bj_MELEE_STARTING_TOD)
set u = CreateUnit(Player(0), 'Hblm', 0, 0, 0)
return false
endfunction
private function cond2 takes nothing returns boolean
call SetHeroLevel(u, GetHeroLevel(u)+1, true)
return false
endfunction
//===========================================================================
private function i takes nothing returns nothing
local trigger t = CreateTrigger()
local trigger tt = CreateTrigger()
call TriggerRegisterTimerEvent(t, 0.01, false)
call TriggerRegisterPlayerEvent(tt, Player(0), EVENT_PLAYER_END_CINEMATIC)
call TriggerAddCondition( t, Condition(function cond) )
call TriggerAddCondition( tt, Condition(function cond2))
set t = null
set tt = null
endfunction
endscope
//TESH.scrollpos=60
//TESH.alwaysfold=0
library FearSystem /* v2.6
************************************************************************************
*
* */uses /*
* */optional/*
*
* */ Table /* http://www.hiveworkshop.com/forums/jass-resources-412/snippet-new-table-188084/
* //By Bribe or Vexorian
*
************************************************************************************
*
* struct Fear extends array
*
* Description
* -------------------------
*
* This is a fear system; use it to remove player
* control from a unit temporarily. Units affected
* will also be unable to attack.
*
* Fields
* -------------------------
*
* unit targ -> The unit you want to apply the fear.
*
* string path -> The path of the sfx you want to add to the unit.
*
* string attach -> The attachment string you want the sfx to be on the unit
*
* readonly effect e -> The effect currently applied to the unit.
* Initializes to null
*
* Methods
* -------------------------
*
* static method create takes nothing returns thistype
* method destroy takes nothing returns nothing
*
* method start takes nothing returns nothing
* When you have set every parameters you start your fear instance.
*
* method changeEffect takes string path, string attach returns nothing
* If you already have set the effect of your instance and it is running
* and you want to change it use this.
*
* static method isFeared takes unit u returns boolean
* static method get takes unit u returns thistype
*
* Operators
* -------------------------
*
* method operator time= takes real t returns nothing
* method operator time takes nothing returns real
*
* Credits
* -------------------------
*
* - Vexorian for vJASS and Table
* - Maker for the DisableUnit function
* - Bribe for Table
* - Chobibo for the addition in the DisableUnit function/
*
************************************************************************************/
native UnitAlive takes unit u returns boolean
globals
//There will be check every FPS second.
private constant real FPS = 0.31250000
//Feared units will change direction every EACH_CHANGE FPS.
private constant integer EACH_CHANGE = 3
//Feared units will go maximum in a circle of 150 around them each time they change direction.
private constant real AROUND = 150.
//The rawcode of the attack disable. Be sure it is the same in the Object Editor.
private constant integer DISABLE_ATTACK = 'W000'
//The rawcode of the morph. Be sure it is the same in the Object Editor.
private constant integer MORPH_ID = 'Z001'
//The rawcode of the bear form. Be sure it is the same in the Object Editor.
private constant integer BEAR_ID = 'Z000'
endglobals
static if Table.flush2D.exists then
globals
private HandleTable tab
endglobals
elseif Table.has.exists then
globals
private Table tb
endglobals
else
globals
private hashtable ht = InitHashtable()
endglobals
endif
private function round takes real r returns integer
return R2I(r+0.5)
endfunction
private function modulo takes integer a, integer b returns integer
return a - (a/b)*b
endfunction
//Credits to Maker for this awesum func <3
private function DisableControl takes unit u returns nothing
local boolean b
call UnitAddAbility(u, 'Aloc')
call UnitRemoveAbility(u, 'Aloc')
if IsUnitType(u, UNIT_TYPE_HERO) then
call UnitAddAbility(u,MORPH_ID)
call IssueImmediateOrder(u, "metamorphosis")
call UnitRemoveAbility(u,MORPH_ID)
else
call UnitAddAbility(u, BEAR_ID)
call IssueImmediateOrder(u, "bearform")
call UnitRemoveAbility(u, BEAR_ID)
endif
//Thanks to chobibo for this idea
if GetLocalPlayer() != GetOwningPlayer(u) then
set b = not IsUnitHidden(u)
call ShowUnit(u,false)
call ShowUnit(u,b)
endif
//I added this line to disable their attack too.
call UnitAddAbility(u,DISABLE_ATTACK)
endfunction
private function EnableControl takes unit u returns nothing
local boolean backup = not IsUnitHidden(u)
call ShowUnit(u,false)
//I added this line to enable their attack.
call UnitRemoveAbility(u,DISABLE_ATTACK)
call ShowUnit(u,backup)
endfunction
struct Fear extends array
unit targ
string path
string attach
readonly effect e
readonly boolean b
private integer steps
private integer startat
private static timer period
private static integer dindex
private static thistype array data
private static integer instanceCount
private static thistype recycle
private thistype recycleNext
private static method periodic takes nothing returns nothing
local thistype this
local real x
local real y
local integer i = 0
loop
exitwhen i > dindex
set this = data[i]
if modulo(this.steps,EACH_CHANGE) == this.startat then
set x = GetUnitX(this.targ)
set y = GetUnitY(this.targ)
call IssuePointOrder(this.targ, "move", GetRandomReal(x-AROUND,x+AROUND), GetRandomReal(y-AROUND, x+AROUND) )
endif
set this.steps = this.steps - 1
if this.steps == 0 or not(UnitAlive(this.targ)) then
set data[i] = data[dindex]
set i = i - 1
set dindex = dindex - 1
if this.e != null then
call DestroyEffect(this.e)
set this.e = null
endif
call IssueImmediateOrder(this.targ,"stop")
call EnableControl(this.targ)
static if Table.flush2D.exists then
call tab.flush(this.targ)
elseif Table.has.exists then
return tb.remove(GetHandleId(this.targ))
else
return FlushChildHashtable(ht,GetHandleId(this.targ))
endif
if this.b then
set this.targ = null
set recycleNext = recycle
set recycle = this
endif
endif
if dindex == -1 then
call PauseTimer(period)
endif
set i = i + 1
endloop
endmethod
static method isFeared takes unit u returns boolean
static if Table.flush2D.exists then
return tab.exists(u)
elseif Table.has.exists then
return tb.has(GetHandleId(u))
else
return HaveSavedInteger(ht,GetHandleId(u),0)
endif
endmethod
method operator time= takes real t returns nothing
set this.steps = round(t/FPS)
endmethod
method operator time takes nothing returns real
return this.steps*FPS
endmethod
method changeEffect takes string path, string attach returns nothing
call DestroyEffect(this.e)
set this.e = null
set this.e = AddSpecialEffectTarget(path,this.targ,attach)
endmethod
static method get takes unit u returns thistype
local thistype this
if isFeared(u) then
static if Table.flush2D.exists then
set this = tab[u]
if this.b then
return tab[u]
else
debug call BJDebugMsg("Trying to get an instance that will be destroyed at the end of the execution")
return 0
endif
elseif Table.has.exists then
set this = tb[GetHandleId(u)]
if this.b then
return tb[GetHandleId(u)]
else
debug call BJDebugMsg("Trying to get an instance that will be destroyed at the end of the execution")
return 0
endif
else
set this = LoadInteger(ht,GetHandleId(u),0)
if this.b then
return LoadInteger(ht,GetHandleId(u),0)
else
debug call BJDebugMsg("Trying to get an instance that will be destroyed at the end of the execution")
return 0
endif
endif
else
debug call BJDebugMsg("Tryng to get wrong instance")
return 0
endif
endmethod
method start takes nothing returns nothing
debug if this.targ==null or this.steps==0 then
debug call BJDebugMsg("You're instanciating badly ....")
debug return
debug endif
set dindex = dindex + 1
set data[dindex] = this
set this.startat = modulo(this.steps,EACH_CHANGE)
call DisableControl(this.targ)
if this.path != "" and this.attach != "" then
set this.e = AddSpecialEffectTarget(this.path, this.targ, this.attach)
endif
static if Table.flush2D.exists then
set tab[this.targ] = this
elseif Table.has.exists then
set tb[GetHandleId(this.targ)] = this
else
call SaveInteger(ht,GetHandleId(this.targ),0,this)
endif
if dindex == 0 then
call TimerStart(period, FPS, true, function thistype.periodic)
endif
endmethod
static method create takes nothing returns thistype
local thistype this
if recycle == 0 then
set instanceCount = instanceCount + 1
set this = instanceCount
else
set this = recycle
set recycle = recycle.recycleNext
endif
set this.path = ""
set this.attach = ""
set this.e = null
set this.b = false
return this
endmethod
method destroy takes nothing returns nothing
set this.b = true
endmethod
private static method onInit takes nothing returns nothing
static if Table.flush2D.exists then
set tab = HandleTable.create()
elseif Table.has.exists then
set tb = Table.create()
endif
set dindex = - 1
set instanceCount = 0
set recycle = 0
set period = CreateTimer()
endmethod
endstruct
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library Table
//***************************************************************
//* Table object 3.1
//* ------------
//*
//* set t=Table.create() - instanceates a new table object
//* call t.destroy() - destroys it
//* t[1234567] - Get value for key 1234567
//* (zero if not assigned previously)
//* set t[12341]=32 - Assigning it.
//* call t.flush(12341) - Flushes the stored value, so it
//* doesn't use any more memory
//* t.exists(32) - Was key 32 assigned? Notice
//* that flush() unassigns values.
//* call t.reset() - Flushes the whole contents of the
//* Table.
//*
//* call t.destroy() - Does reset() and also recycles the id.
//*
//* If you use HandleTable instead of Table, it is the same
//* but it uses handles as keys, the same with StringTable.
//*
//* You can use Table on structs' onInit if the struct is
//* placed in a library that requires Table or outside a library.
//*
//* You can also do 2D array syntax if you want to touch
//* mission keys directly, however, since this is shared space
//* you may want to prefix your mission keys accordingly:
//*
//* set Table["thisstring"][ 7 ] = 2
//* set Table["thisstring"][ 5 ] = Table["thisstring"][7]
//*
//***************************************************************
//=============================================================
globals
private constant integer MAX_INSTANCES=8100 //400000
//Feel free to change max instances if necessary, it will only affect allocation
//speed which shouldn't matter that much.
//=========================================================
private hashtable ht = InitHashtable()
endglobals
private struct GTable[MAX_INSTANCES]
method reset takes nothing returns nothing
call FlushChildHashtable(ht, integer(this) )
endmethod
private method onDestroy takes nothing returns nothing
call this.reset()
endmethod
endstruct
//Hey: Don't instanciate other people's textmacros that you are not supposed to, thanks.
//! textmacro Table__make takes name, type, key
struct $name$ extends GTable
method operator [] takes $type$ key returns integer
return LoadInteger(ht, integer(this), $key$)
endmethod
method operator []= takes $type$ key, integer value returns nothing
call SaveInteger(ht, integer(this) ,$key$, value)
endmethod
method flush takes $type$ key returns nothing
call RemoveSavedInteger(ht, integer(this), $key$)
endmethod
method exists takes $type$ key returns boolean
return HaveSavedInteger( ht, integer(this) ,$key$)
endmethod
static method flush2D takes string firstkey returns nothing
call $name$(- StringHash(firstkey)).reset()
endmethod
static method operator [] takes string firstkey returns $name$
return $name$(- StringHash(firstkey) )
endmethod
endstruct
//! endtextmacro
//! runtextmacro Table__make("Table","integer","key" )
//! runtextmacro Table__make("StringTable","string", "StringHash(key)" )
//! runtextmacro Table__make("HandleTable","handle","GetHandleId(key)" )
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library BoundSentinel initializer init
//*************************************************
//* BoundSentinel
//* -------------
//* Don't leave your units unsupervised, naughty
//* them may try to get out of the map bounds and
//* crash your game.
//*
//* To implement, just get a vJass compiler and
//* copy this library/trigger to your map.
//*
//*************************************************
//==================================================
globals
// High enough so the unit is no longer visible, low enough so the
// game doesn't crash...
//
// I think you need 0.0 or soemthing negative prior to patch 1.22
//
private constant real EXTRA = 500.0
endglobals
//=========================================================================================
globals
private real maxx
private real maxy
private real minx
private real miny
endglobals
//=======================================================================
private function dis takes nothing returns nothing
local unit u=GetTriggerUnit()
local real x=GetUnitX(u)
local real y=GetUnitY(u)
if(x>maxx) then
set x=maxx
elseif(x<minx) then
set x=minx
endif
if(y>maxy) then
set y=maxy
elseif(y<miny) then
set y=miny
endif
call SetUnitX(u,x)
call SetUnitY(u,y)
set u=null
endfunction
private function init takes nothing returns nothing
local trigger t=CreateTrigger()
local region r=CreateRegion()
local rect rc
set minx=GetCameraBoundMinX() - EXTRA
set miny=GetCameraBoundMinY() - EXTRA
set maxx=GetCameraBoundMaxX() + EXTRA
set maxy=GetCameraBoundMaxY() + EXTRA
set rc=Rect(minx,miny,maxx,maxy)
call RegionAddRect(r, rc)
call RemoveRect(rc)
call TriggerRegisterLeaveRegion(t,r, null)
call TriggerAddAction(t, function dis)
//this is not necessary but I'll do it anyway:
set t=null
set r=null
set rc=null
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library TerrorRising requires FearSystem/*By me*/, BoundSentinel //By Vex
/*
FearSystem : http://www.hiveworkshop.com/forums/spells-569/fear-system-v-2-7-a-243755/
BoundSentinel : http://www.wc3c.net/showthread.php?t=102576
*/
//CONFIGURATION
globals
private constant real FPS = 0.0312500
//The distance between two explosions.
private constant real BETWEEN_UNITS = 175.
//The time between two explosions.
private constant real TIME_BETWEEN = 0.5
//It means that the speed of the orb is BETWEEN_UNITS/TIME_BETWEEN
private constant integer SPELL_ID = 'U000'
private constant integer DUMMY_ID = 'd000'
private constant real AOE = 175.
private constant attacktype ATTACK_TYPE = ATTACK_TYPE_MAGIC
private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_MAGIC
//The path of the special effect attached to fear status
private constant string FEAR_PATH = "Abilities\\Spells\\Undead\\Curse\\CurseTarget.mdl"
private constant string FEAR_ATTACH = "overhead"
//The path of the effect that will spawn on the units when it takes damage
private constant string UNIT_PATH = "Abilities\\Spells\\Human\\Feedback\\ArcaneTowerAttack.mdl"
private constant string UNIT_ATTACH = "origin"
private constant string EXPLOSION_PATH = "Abilities\\Weapons\\Bolt\\BoltImpact.mdl"
endglobals
private constant function Damage takes integer level returns real
return 25.*level
endfunction
private constant function Explosion_Number takes integer level returns integer
return 2+level
endfunction
private constant function Time_Fear takes integer level returns real
return 1. + 0.2*level
endfunction
private function Unit_Filter takes player source, unit targ returns boolean
return (not IsUnitType(targ, UNIT_TYPE_MAGIC_IMMUNE)) and (UnitAlive(targ)) and IsUnitEnemy(targ, source)
endfunction
//END CONFIGURATION -> DONUT TOUCH ANYTHING BELOW
private struct Explosion extends array
unit u
unit caster
player owner
integer steps
real temp
real fear
real X
real Y
real dmg
thistype prev
thistype next
static integer count
static timer period
static group g
method destroy takes nothing returns nothing
if this.next != 0 then
set this.next.prev = this.prev
endif
set this.prev.next = this.next
set this.prev = thistype(0).prev
set thistype(0).prev = this
if thistype(0).next == 0 then
call PauseTimer(period)
endif
call UnitApplyTimedLife(u, 'BTLF', 0.01)
set this.u = null
set this.caster = null
set this.owner = null
endmethod
static method periodic takes nothing returns nothing
local Fear F
local thistype this = thistype(0).next
local unit v
local real x
local real y
loop
exitwhen this == 0
set this.temp = this.temp - FPS
set x = GetUnitX(this.u) + this.X
set y = GetUnitY(this.u) + this.Y
call SetUnitX(this.u, x)
call SetUnitY(this.u, y)
if this.temp <= 0 then
call DestroyEffect( AddSpecialEffect(EXPLOSION_PATH, x, y) )
call GroupEnumUnitsInRange(g, x, y, AOE, null)
loop
set v = FirstOfGroup(g)
exitwhen v==null
call GroupRemoveUnit(g, v)
if Unit_Filter(this.owner, v) then
call DestroyEffect( AddSpecialEffectTarget(UNIT_PATH,v,UNIT_ATTACH) )
if Fear.isFeared(v) then
set F = Fear.get(v)
set F.time = this.fear + F.time
else
set F = Fear.create()
set F.targ = v
set F.path = FEAR_PATH
set F.attach = FEAR_ATTACH
set F.time = this.fear
call F.start()
call F.destroy()
endif
call UnitDamageTarget(this.caster, v, this.dmg, true, false, ATTACK_TYPE, DAMAGE_TYPE, null)
endif
endloop
set this.steps = this.steps - 1
set this.temp = TIME_BETWEEN
endif
if this.steps == 0 then
call this.destroy()
endif
set this = this.next
endloop
endmethod
static method cond takes nothing returns boolean
local thistype this
local real angle
local real tx
local real ty
local integer i
if GetSpellAbilityId() == SPELL_ID then
//Allocate
if thistype(0).prev == 0 then
set count = count + 1
set this = count
else
set this = thistype(0).prev
set thistype(0).prev = thistype(0).prev.prev
endif
if thistype(0).next == 0 then
call TimerStart(period, FPS, true, function thistype.periodic)
else
set thistype(0).next.prev = this
endif
set this.next = thistype(0).next
set thistype(0).next = this
set this.prev = thistype(0)
//End Allocate
set this.caster = GetTriggerUnit()
set i = GetUnitAbilityLevel(this.caster,SPELL_ID)
set tx = GetSpellTargetX()
set ty = GetSpellTargetY()
set angle = Atan2(ty-GetUnitY(this.caster), tx-GetUnitX(this.caster))
set this.owner = GetTriggerPlayer()
set this.u = CreateUnit(this.owner, DUMMY_ID, tx, ty, angle*bj_RADTODEG)
set this.steps = Explosion_Number(i)
set this.temp = TIME_BETWEEN
set this.fear = Time_Fear(i)
set this.X = BETWEEN_UNITS*Cos(angle)*FPS
set this.Y = BETWEEN_UNITS*Sin(angle)*FPS
set this.dmg = Damage(i)
endif
return false
endmethod
static method onInit takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t, Condition(function thistype.cond))
call Preload(FEAR_PATH)
call Preload(EXPLOSION_PATH)
call Preload(UNIT_PATH)
set period = CreateTimer()
set count = 0
set g = CreateGroup()
set t = null
endmethod
endstruct
endlibrary