SoUI 0.5版本占坑
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

468 lines
20 KiB

3 years ago
#ifndef YDWETimerPatternIncluded
#define YDWETimerPatternIncluded
#include "YDWEBase.j"
library_once YDWETimerPattern initializer Init requires YDWEBase
//***************************************************
//* <EFBFBD><EFBFBD> - Matrix <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD><EFBFBD>
//*--------------------
//* <EFBFBD><EFBFBD><EFBFBD>ߣ<EFBFBD>Warft_TigerCN <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ż<EFBFBD><EFBFBD><EFBFBD>Fetrix_sai
//***************************************************
#define TIMER_PATTERN_RADIUS 120.0
private keyword Thread
globals
private boolexpr Bexpr = null
private rect Area = null
private Thread tmp_data
private location yd_loc = Location(0.0, 0.0)
endglobals
private struct YDVector3
real x
real y
real z
endstruct
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// Timer Pattern Union //
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
private function SingleMagic takes unit sour, unit targ, real x, real y, real h, integer uid, integer aid, integer lv, integer order returns nothing
local unit dummy = CreateUnit(GetOwningPlayer(sour), uid, x, y, GetUnitFacing(sour))
call UnitApplyTimedLife(dummy, 'BHwe', 1.0)
call UnitAddAbility(dummy, aid)
call SetUnitAbilityLevel(dummy, aid, lv)
call SetUnitFlyHeight(dummy, h, 0.0)
call IssueTargetOrderById(dummy, order, targ)
//debug call BJDebugMsg("Target order")
set dummy = null
endfunction
private function GetUnitZ takes unit u returns real
call MoveLocation(yd_loc, GetUnitX(u), GetUnitY(u))
return GetUnitFlyHeight(u) + GetLocationZ(yd_loc)
endfunction
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// Filter Funcs //
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
private function EnemyFilter takes unit u, unit caster returns boolean
return IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE) == false and IsUnitType(u, UNIT_TYPE_RESISTANT) == false /*
*/ and IsUnitType(u, UNIT_TYPE_SLEEPING) == false and GetUnitState(u, UNIT_STATE_LIFE) > 0.405 /*
*/ and IsUnitType(u, UNIT_TYPE_STRUCTURE) == false and IsUnitIllusion(u) == false /*
*/ and IsUnitHidden(u) == false and IsUnitEnemy(u, GetOwningPlayer(caster)) /*
*/ and IsUnitVisible(u, GetOwningPlayer(caster))
endfunction
private function TreeFilter takes nothing returns boolean
local integer id = GetDestructableTypeId(GetFilterDestructable())
return id == 'LTlt' or id == 'ATtr' or id == 'BTtw' or id == 'KTtw' /*
*/or id == 'YTft' or id == 'JTct' or id == 'YTst' or id == 'YTct' /*
*/or id == 'YTwt' or id == 'JTtw' or id == 'DTsh' or id == 'FTtw' /*
*/or id == 'CTtr' or id == 'ITtw' or id == 'NTtw' or id == 'OTtw' /*
*/or id == 'ZTtw' or id == 'WTst' or id == 'GTsh' or id == 'VTlt' /*
*/or id == 'WTtw' or id == 'ATtc' or id == 'BTtc' or id == 'CTtc' /*
*/or id == 'ITtc' or id == 'NTtc' or id == 'ZTtc'
endfunction
private function DamageFilter takes nothing returns boolean
local unit u = GetFilterUnit()
local Thread d = tmp_data
if not(IsUnitInGroup(u, d.g)) and d.switch != 0 and EnemyFilter(u, d.caster) then
call UnitDamageTarget(d.caster, u, d.amount, true, true, bj_lastSetAttackType, bj_lastSetDamageType, bj_lastSetWeaponType)
call DestroyEffect(AddSpecialEffectTarget(d.dsfx, u, d.part))
if d.skills > '0000' and d.skills != null and d.order > 0 and d.order != null then
call SingleMagic(d.caster, u, d.pos.x, d.pos.y, GetUnitFlyHeight(d.obj), d.unitid, d.skills, d.level, d.order)
endif
if not(d.recycle) then
//debug call BJDebugMsg("|cff00ff00[YDWE] Timer Pattern : |r A one-time.")
set d.switch = 0
endif
set d.target = u
//call GroupAddUnit(d.g, u)
set u = null
return true
endif
set u = null
return false
endfunction
private function TreeKill takes nothing returns nothing
local destructable d = GetEnumDestructable()
if GetWidgetLife(d) > 0.405 then
call KillDestructable(d)
endif
set d = null
endfunction
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// Major Structure Code //
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
private struct Thread
YDVector3 des //destination
YDVector3 pos //position
YDVector3 vel //velocity
unit caster
unit source
unit target
unit obj
real ac
real bc
real dist
real step
real amount
integer switch
integer follow
integer unitid
integer skills
integer order
integer level
string dsfx
string gsfx
string wsfx
string part
boolean recycle
boolean killdest
boolean volume
group g
timer t
static method operator [] takes handle h returns thistype
return YDWEGetIntegerByString("YDWETimerPattern.", I2S(YDWEH2I(h)))
endmethod
static method operator []= takes handle h, thistype value returns nothing
call YDWESaveIntegerByString("YDWETimerPattern.", I2S(YDWEH2I(h)), value)
endmethod
static method flush takes handle h returns nothing
call YDWEFlushStoredIntegerByString("YDWETimerPattern.", I2S(YDWEH2I(h)))
endmethod
method operator x= takes real value returns nothing
set .pos.x = value
call SetUnitX(.obj, value)
endmethod
method operator y= takes real value returns nothing
set .pos.y = value
call SetUnitY(.obj, value)
endmethod
method operator z= takes real value returns nothing
set .pos.z = value
call MoveLocation(yd_loc, .pos.x, .pos.y)
call SetUnitFlyHeight(.obj, value - GetLocationZ(yd_loc), 0)
endmethod
method onDestroy takes nothing returns nothing
//debug call BJDebugMsg("|cff00ff00[YDWE] Timer Pattern : |r Knockback stopped!")
call Thread.flush(.obj)
call Thread.flush(.t)
call GroupClear(.g)
call DestroyGroup(.g)
call PauseTimer(.t)
call DestroyTimer(.t)
call .des.destroy()
call .pos.destroy()
call .vel.destroy()
set .caster = null
set .target = null
set .obj = null
set .g = null
set .t = null
set .amount = 0
set .skills = 0
set .order = 0
set .dsfx = ""
set .gsfx = ""
set .wsfx = ""
set .part = ""
endmethod
endstruct
private struct Parabola extends Thread
static method move takes nothing returns nothing
local thistype this = Thread[GetExpiredTimer()]
//local real vx = .des.x - .pos.x
//local real vy = .des.y - .pos.y
//local real vz = .des.z - .pos.z
//if vx * vx + vy * vy + vz * vz > 900.0 then
set .x = GetUnitX(.obj) + .vel.x //.pos.x + .vel.x
set .y = GetUnitY(.obj) + .vel.y //.pos.y + .vel.y
set .z = GetUnitZ(.obj) + .ac * .step * 2 + .ac * .dist + .bc //.pos.z + .ac * .step * 2 + .ac * .dist + .bc
set .step = .step + .dist
//debug call BJDebugMsg("|cff00ff00[YDWE] Timer Pattern : |r high = ." + R2S(GetLocationZ(yd_loc)))
if YDWECoordinateX(.pos.x) != .pos.x or YDWECoordinateY(.pos.y) != .pos.y or .pos.z <= GetLocationZ(yd_loc) then
set .switch = 0
endif
if .amount > 0.0 then
//call this.damage(.caster, .pos.x + .vel.x, .pos.y + .vel.y, GetUnitZ(.obj), false, false)
set tmp_data = integer(this)
call GroupEnumUnitsInRange(.g, .pos.x + .vel.x, .pos.y + .vel.y, TIMER_PATTERN_RADIUS, function DamageFilter)
//debug call BJDebugMsg("|cff00ff00[YDWE] Timer Pattern : |r Area damage.")
endif
//else
//set .switch = 0
//endif
if .switch == 0 then
call SetUnitFlyHeight(.obj, GetUnitDefaultFlyHeight(.obj), 200.0)
call SetUnitTimeScale(.obj, 1)
//YDWETriggerEvent
call YDWESyStemAbilityCastingOverTriggerAction(.obj, 7)
call this.destroy()
endif
endmethod
static method create takes unit source, unit object, real angle, real distance, real time, real interval, real high, real damage, string attach, string deff returns thistype
local thistype this = thistype.allocate()
local real vx = 0.0
local real vy = 0.0
local real vz = 0.0
set .des = YDVector3.create()
set .pos = YDVector3.create()
set .vel = YDVector3.create()
set .pos.x = GetUnitX(object)
set .pos.y = GetUnitY(object)
set .pos.z = GetUnitZ(object)
set .des.x = .pos.x + distance * Cos(angle)
set .des.y = .pos.y + distance * Sin(angle)
call MoveLocation(yd_loc, .des.x, .des.y)
set .des.z = GetLocationZ(yd_loc)
if .pos.z > .des.z then
set high = high + .pos.z
else
set high = high + .des.z
endif
set .ac = (2 * (.pos.z + .des.z) - 4 * high) / (distance * distance)
set .bc = (.des.z - .pos.z - .ac * distance * distance) / distance
set .dist = distance * interval / time
set .ac = .ac * .dist
set .bc = .bc * .dist
set .vel.x = .dist * Cos(angle)
set .vel.y = .dist * Sin(angle)
set .step = 0.0
set .caster = source
set .obj = object
set .amount = damage
set .dsfx = deff
set .part = attach
set .switch = 1
set .recycle = true
set .t = CreateTimer()
set .g = CreateGroup()
call UnitAddAbility(.obj, 'Amrf')
call UnitRemoveAbility(.obj, 'Amrf')
call TimerStart(.t, interval, true, function thistype.move)
call GroupAddUnit(.g, object)
set Thread[object] = integer(this)
set Thread[.t] = integer(this)
return this
endmethod
endstruct
// uniform speed
private struct Linear extends Thread
static method move takes nothing returns nothing
local thistype this = Thread[GetExpiredTimer()]
if .step > .dist then
set .x = GetUnitX(.obj) + .vel.x //.pos.x + .vel.x
set .y = GetUnitY(.obj) + .vel.y //.pos.y + .vel.y
//set .pos.z = GetUnitZ(.obj)
set .step = .step - .dist
//call this.damage(.caster, .pos.x, .pos.y, .pos.z, true, true)
set tmp_data = integer(this)
call GroupEnumUnitsInRange(.g, .pos.x + .vel.x, .pos.y + .vel.y, TIMER_PATTERN_RADIUS, function DamageFilter)
if YDWECoordinateX(.pos.x) != .pos.x or YDWECoordinateY(.pos.y) != .pos.y then
set .switch = 0
endif
else
set .switch = 0
endif
if .switch == 0 then
// YDWETriggerEvent
if .target != null then
//debug call BJDebugMsg("|cff00ff00[YDWE] Timer Pattern : |r |cffff0000" + GetUnitName(.target) + "|r was hit!!!")
//call YDWESaveUnitByString(I2S(YDWEH2I(.caster)), "MoonPriestessArrow", .target)
set bj_lastAbilityTargetUnit = .target
call YDWESyStemAbilityCastingOverTriggerAction(.caster, 8)
else
call YDWESyStemAbilityCastingOverTriggerAction(.caster, 9)
endif
//call KillUnit(.obj)
call RemoveUnit(.obj)
call this.destroy()
endif
endmethod
static method create takes unit source, unit object, real angle, real distance, real time, real interval, integer uid, integer aid, integer lv, integer orderid, string attach, string sfx returns thistype
local thistype this = thistype.allocate()
set .des = YDVector3.create()
set .pos = YDVector3.create()
set .vel = YDVector3.create()
set .step = distance
set .dist = distance * interval / time
set .vel.x = .dist * Cos(angle)
set .vel.y = .dist * Sin(angle)
set .pos.x = GetUnitX(object)
set .pos.y = GetUnitY(object)
set .caster = source
set .obj = object
set .unitid = uid
set .skills = aid
set .level = lv
set .order = orderid
set .part = attach
set .gsfx = sfx
set .switch = 1
set .recycle = false
set .t = CreateTimer()
set .g = CreateGroup()
call TimerStart(.t, interval, true, function thistype.move)
set Thread[.t] = integer(this)
return this
endmethod
endstruct
// Uniform deceleration
private struct Deceleration extends Thread
static method move takes nothing returns nothing
local thistype this = Thread[GetExpiredTimer()]
local real xp = GetUnitX(.obj) + .dist * .vel.x
local real yp = GetUnitY(.obj) + .dist * .vel.y
if .volume == false then
//debug call BJDebugMsg("|cff00ff00[YDWE] Timer Pattern : |rPathable without terrain.")
if IsTerrainPathable(xp, yp, PATHING_TYPE_WALKABILITY) then
set .switch = 0
else
set .x = xp
set .y = yp
endif
else
set .x = xp
set .y = yp
endif
if .follow == 0 then
if GetUnitFlyHeight(.obj) < 5. then
if IsTerrainPathable(.pos.x, .pos.y, PATHING_TYPE_FLOATABILITY) then
call DestroyEffect(AddSpecialEffect(.gsfx, .pos.x, .pos.y))
else
call DestroyEffect(AddSpecialEffect(.wsfx, .pos.x, .pos.y))
endif
endif
endif
set .follow = .follow + 1
if .follow == 2 then
set .follow = 0
endif
if .killdest then
call MoveRectTo(Area, .pos.x, .pos.y)
call EnumDestructablesInRect(Area, Bexpr, function TreeKill)
endif
if .amount > 0.0 then
//call this.damage(.caster, .pos.x, .pos.y, 0.0, false, .recycle)
set tmp_data = integer(this)
call GroupEnumUnitsInRange(.g, .pos.x, .pos.y, TIMER_PATTERN_RADIUS, function DamageFilter)
endif
set .dist = .dist - .step
if .dist <= 0.0 or YDWECoordinateX(.pos.x) != .pos.x or YDWECoordinateY(.pos.y) != .pos.y then
set .switch = 0
endif
if .switch == 0 then
call SetUnitFlyHeight(.obj, GetUnitDefaultFlyHeight(.obj), 200.0)
call SetUnitTimeScale(.obj, 1)
// YDWETriggerEvent
call YDWESyStemAbilityCastingOverTriggerAction(.obj, 6)
call this.destroy()
endif
endmethod
static method create takes unit source, unit object, real angle, real distance, real time, real interval, real damage, boolean killtrees, boolean cycle, boolean path, string part, string geff, string weff returns thistype
local thistype this = thistype.allocate() //thistype(Thread[object])
local real vx = 0.0
local real vy = 0.0
local real l = 0.0
set .des = YDVector3.create()
set .pos = YDVector3.create()
set .vel = YDVector3.create()
set .vel.x = Cos(angle)
set .vel.y = Sin(angle)
set .dist = 2 * distance * interval / time
set .step = .dist * interval / time
set .pos.x = GetUnitX(object)
set .pos.y = GetUnitY(object)
set .caster = source
set .obj = object
set .amount = damage
set .killdest = killtrees
set .recycle = cycle
set .volume = path
set .gsfx = geff
set .wsfx = weff
set .switch = 1
set .follow = 0
set .g = CreateGroup()
set .t = CreateTimer()
call TimerStart(.t, interval, true, function thistype.move)
set Thread[.t] = integer(this)
return this
endmethod
endstruct
// Jump Attack PUI
function YDWETimerPatternJumpAttack takes unit u, real face, real dis, real lasttime, real timeout, real high, real damage, string part, string dsfx returns nothing
if u == null then
//debug call BJDebugMsg("|cff00ff00[YDWE] Timer Pattern : |r No object!")
return
endif
call Parabola.create(u, u, Deg2Rad(face), RMaxBJ(dis, 0), RMaxBJ(lasttime, 0), RMaxBJ(timeout, 0), high, damage, part, dsfx)
endfunction
// Moon Priestess Arrow PUI
function YDWETimerPatternMoonPriestessArrow takes unit u, real face, real dis, real lasttime, real timeout, integer lv, integer aid, integer uid, string order, string part, string dsfx returns nothing
local unit sour = null
if u == null then
//debug call BJDebugMsg("|cff00ff00[YDWE] Timer Pattern : |r No object!")
return
endif
set sour = YDWEGetUnitByString(I2S(YDWEH2I(u)), "MoonPriestessArrow")
if sour == null then
set sour = u
endif
call Linear.create(sour, u, Deg2Rad(face), RMaxBJ(dis, 0), RMaxBJ(lasttime, 0), RMaxBJ(timeout, 0), uid, aid, IMaxBJ(lv, 1), OrderId(order), part, dsfx)
//call YDWEFlushMissionByString(I2S(YDWEH2I(u)))
set sour = null
endfunction
// Rush Slide PUI
function YDWETimerPatternRushSlide takes unit u, real face, real dis, real lasttime, real timeout, real damage, boolean killtrees, boolean cycle, boolean path, string part, string gsfx, string wsfx returns nothing
if u == null then
//debug call BJDebugMsg("|cff00ff00[YDWE] Timer Pattern : |r No object!")
return
endif
call Deceleration.create(u, u, Deg2Rad(face), RMaxBJ(dis, 0), RMaxBJ(lasttime, 0), RMaxBJ(timeout, 0), damage, killtrees, cycle, path, part, gsfx, wsfx)
endfunction
private function Init takes nothing returns nothing
set Area = Rect(-TIMER_PATTERN_RADIUS, -TIMER_PATTERN_RADIUS, TIMER_PATTERN_RADIUS, TIMER_PATTERN_RADIUS)
set Bexpr = Filter(function TreeFilter)
endfunction
#undef TIMER_PATTERN_RADIUS
endlibrary
#endif /// YDWETimerPatternIncluded