Chaos_Knight
New Member
- Reaction score
- 39
Anachron said:Change everything ingame. (Even collision size, the effect, the movespeed etc!)
Yup. How?
Anachron said:Change everything ingame. (Even collision size, the effect, the movespeed etc!)
Oh man, I try to keep only one version of scripts. For example CustomInventory,... It would be a mess to have other scripts for every community just because they like it.
You are free to change my librarys to your needs.
Why can't you just post the code here?
Like many systems, and the code will become more than 10000 letters.
Nope. The height changes instantly. It's a feature.ZAngle facing? I don't think you put it in yet did you?
Also is there a way to make facing instant? Kenny's projectile system has faced similiar issues as well with this.
I should think you also include a test spell for each feature, like missile collision, a slow spell or whatnot, etc.
If you fired Arcane Chain at a Flying Unit at like 900 height while standing right under it, it looks strange. It's rather instant. Wouldn't it be something like 850 / 512 (1.66015625) seconds to reach the flying target. But instead it's like 0.20 seconds... 3D movement?
That would be lame. Really.externalize dependencies?
Because its hard to keep it up to date.Why can't you just post the code here?
And that.Like many systems, and the code will become more than 10000 letters.
Okay, so you want me to copy and paste all librarys of all my systems at all forums that I post in when I make an update? No, I can't.Probably, but he coulda have uploaded a txt or j file.
Nope.He could...
You have a weird perception of the word "lame".That would be lame. Really.
Okay, so you want me to copy and paste all librarys of all my systems at all forums that I post in when I make an update?
I will try to say it again:
txt file.
upload.
1. JSP is no longer in use (at least I haven't seen it in use anywhere). Two years ago, I was using JassCraft (JSP's predecessor). It was released four years ago.He could use JSP (JASS Shop Pro)
And upload a such file.
I don't like pastebins = )There's a reason why pastebins were created, what uuuuup!
What do you think about external dependencies? There is no way to implement struct systems or such without recoding my whole systems.You have a weird perception of the word "lame".
Here is a short list of some of the pros/cons:
+It's good style
+It removes the need for multiple versions of a single library
+You could use one interface for ALL you libraries
+You can easily change code without breaking dependencies.
+It allows almost all coders to use your libraries, no matter what common library they use; If they use an uncommon library, they can easily extend your interface to support their libraries.
+If others use your library, but use different libraries than those you depend on, they don't have to recode their changes every time you make a new version. They don't have to change every new library you release.
+If the libraries you depend on change, you don't have to recode all of the libraries that require that library. In fact, you only have to change about 30 lines which are externalized in a single, concentrated .j file. And swoosh, everything works again.
I've decided to not make it, please accept it. There is no need from my point of view to do so.-You have to code an additional 30 lines in your whole life.
Well, probably that is lame. I mean, 30 lines... Once in your life for every dependency... That can easily become 60 lines, or even 90!
For just those few pros (and more)...
It's pretty hard to decide what way to go here, right?
Well I know all of that, but that is nothing more then just CopyNPasting it directly into here. I mean I have to copy all the libraries and paste it somewhere for every forum. Just for example the CustomInventory.No.
I will try to say it again:
txt file.
upload.
you.
Please don't forget that you are already uploading the map. With the map, you are already uploading the updated code to every forum. Just that you do so in a dumb format only a small part of the wc3 community is willing to use. Using txt or j files (with the txt MIME type) means easy access, no need for mpq reader software, smaller file size, and instant file type recognition by any OS i have used so far.
In case you are not completely aware of how to save your code into a txt file, here is a (hopefully) complete list:
HOW TO UPLOAD A TXT FILE - in 10 simple steps.
1. Open your map.
2. Search your trigger(s)
3. Open an appropriate txt file writer. For your basic needs, notepad should be more than enough (I assume you're running windows)
4. Select the library code. For example, you can click into the field where you entered the code and press ctrl + a.
5. Then move to the editor of your choice, create a new file, name it accordingly. For example, CustomMissile_320.txt for the CustomMissile library version 3.20.
6. Paste the code into the txt file. (There is a huge blank insertion field).
7. Save the txt file.
8. Repeat 4-7 for all libraries pertaining to the same system.
9. If you have more than two .txt files, you should compress them into a single .7z or rar archive.
10. Upload either the newly created .7z/.rar file or the txt files to the forum of interest.
If you want, you can even use a single centralized web host and provide links from your forums to that webhost. Github is a great place for doing stuff like that.
If you choose to do so, you will only have to post the links once and never update them again! Oh my god!
Of course, it's much more work updating the links never again than having to upload the wc3 map at every forum every time you have a new resource, I understand that. Okay, actually, I don't. But I don't have to - that is your matter.
David
//<o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o>
//: CustomMissile
//: by Anachron
//:
//: This system is thought to replace xecollider [and xeprojectile]
//:
//: What this is:
//: This is a missileengine designed to easily be integrated into any spell
//: and/or system that needs a missile which does actions.
//:
//: Functionality:
//: - Get when an unit has been touched
//: - Get when a destructable has been touched
//: - Get when terrain wall has been touched
//: - Get when a missile has been touched
//: - Highly customizeable ([Don't] use whatever you want)
//: - Highly flexible (You are allowed to change values at any time)
//: - Fast
//: - Easy understandable (Examples to bring the system closer to you)
//: - Well written (Code is non-redundant, cathegorized, with comments)
//:
//: Credits:
//: Vexorian for xe(collider) [which I don't use]
//: Moyack (For the parabola functions)
//: Rising_Dusk for GroupUtils [<a href="http://www.wc3c.net/showthread.php?t=104464]" target="_blank" class="link link--external" rel="nofollow ugc noopener">http://www.wc3c.net/showthread.php?t=104464]</a>
//:
//: Thanks to:
//: Slaydon, catch_ya, Flame_Phoenix, Element_Of_Water and Berbanog
//: for their input to the system. Without them this wouldn't be that
//: customizeable and would've less functionality.
//:
//<o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o>
library CustomMissile requires CustomEffect, Loc, GroupUtils
globals
// Just looked good
constant real CM_PERIOD = 0.03175
// 22.5 * bj_PI / 180
private constant real ANGLE_TOLERANCE = 0.392699082
private constant real RAD_PER_PERIOD = 2. * bj_PI * CM_PERIOD
endglobals
//: Thanks to Moyack for these functions. They mean a lot to me.
function ParabolaZ takes real h, real d, real x returns real
return (4 * h / d) * (d - x) * (x / d)
endfunction
function ParabolaZ2 takes real y0, real y1, real h, real d, real x returns real
local real A = (2*(y0+y1)-4*h)/(d*d)
local real B = (y1-y0-A*d*d)/d
return A*x*x + B*x + y0
endfunction
//: Thanks to The_Reborn_Devil
function GetZAngle takes real x1, real y1, real z1, real x2, real y2, real z2 returns real
return Atan2(z2 - z1, SquareRoot((x2-x1) * (x2-x1) + (y2-y1) * (y2-y1)))
endfunction
// == -- - - -- ==
// Default settings
// == -- - - -- ==
globals
// Declares the default height of a missle.
private constant real DEFAULT_HEIGHT = 0.
// Declares the default xyArc of the missle.
// xyArc is a curve, but horizontal.
private constant real DEFAULT_XYARC = 0.
// Declares the default zArc of the missle.
private constant real DEFAULT_ZARC = 0.
// Declares whether missles have decay at default or not
private constant boolean DEFAULT_HASDECAY = true
// Declares the time of the default decay.
// Doesn not do anything when hasdecay is on false
private constant real DEFAULT_DECAY = 5.
// Declares the default movespeed of the missle
private constant real DEFAULT_MOVESPEED = 512.
// Declares the default turn of the missle
// Turnspeed: How fast the missel can change its degrees
private constant real DEFAULT_TURNSPEED = 0.33
// Declares the default range of the missle.
// Warning: An unit with 0 range will !never! reach the target.
private constant real DEFAULT_HITRANGE = 64.
private constant boolean DEFAULT_CHECKHEIGHT = true
// Some booleans whether actions
// should be done on those hits or not
private constant boolean DEFAULT_HITSWALLS = false
private constant boolean DEFAULT_HITSUNITS = false
private constant boolean DEFAULT_HITSDESTS = false
private constant boolean DEFAULT_HITSMISSILES = false
endglobals
private interface eventHandler
//: If we have a homing missle, we can just use this to react on the
//: target reached event.
method onTargetReach takes nothing returns nothing defaults nothing
//: Whenever the missle touches an unit it will trigger this event.
//: Note: You will need to enable unit hitting first!
//: (set .hitunits = true)
method onUnitTouch takes unit theUnit returns nothing defaults nothing
//: Whenever the missle touches a destructable it will trigger this event.
//: Note: You will need to enable destructable hitting first!
//: (set .hitdests = true)
method onDestTouch takes destructable theDestructable returns nothing defaults nothing
//: Whenever the missle touches a terrain wall it will trigger this event.
//: Note: You will need to enable terrain hitting first!
//: (set .hitwalls = true)
method onWallHit takes nothing returns nothing defaults nothing
//: Whenever the missle touches a missle it will trigger this event.
//: Note: You will need to enable missle hitting first!
//: (set .hitmissles = true)
method onCollide takes CustomMissile theCollider returns nothing defaults nothing
//: This will be ran the first time the unit moves (and only once).
//: Note: Paused units do not move.
method onStart takes nothing returns nothing defaults nothing
//: This will be ran everytime the missle is in proceeding,
//: whether its active or not.
method onLoop takes nothing returns nothing defaults nothing
//: This will be ran at the end, in the destroy method.
method onEnd takes nothing returns nothing defaults nothing
//: This will be ran right after the creation.
//: Use this to apply your missle settings here.
method onCreate takes nothing returns nothing defaults nothing
//: This will return the missle speed.
//: Use this method to slow / freeze missles.
method getMissleSpeed takes nothing returns real defaults 0.
//: Use this to use your own Z-Parabola.
method getParabolaZ takes real y0, real y1, real h, real d, real x returns real
endinterface
struct CustomMissile extends eventHandler
//: == ---------------------------- ----------------------------
//: # Primary Values
//: == ---------------------------- ----------------------------
private delegate CustomEffect eff = 0
private boolean isAlive = false
private boolean isActive = false
private boolean isStarted = false
private boolean isCreated = false
private Loc start = 0
private Loc end = 0
private real h = DEFAULT_HEIGHT
private boolean zAutoFace = false
//: == ---------------------------- ----------------------------
//: # Arc movement (Column flight)
//: == ---------------------------- ----------------------------
private real xyArc = DEFAULT_XYARC
private real zArc = DEFAULT_ZARC
//: == ---------------------------- ----------------------------
//: # Decay (Death timer)
//: == ---------------------------- ----------------------------
private boolean hasDecay = DEFAULT_HASDECAY
private real decy = DEFAULT_DECAY
//: == ---------------------------- ----------------------------
//: # Haze (Circles)
//: == ---------------------------- ----------------------------
private boolean hasHaze = false
private boolean hazeNeg = false
private real hazeInc = 0.
private real hazeMin = 0.
private real hazeMax = 0.
private real hazeCur = 0.
//: == ---------------------------- ----------------------------
//: # Turn / Movespeed & Management
//: == ---------------------------- ----------------------------
private real moveSpd = DEFAULT_MOVESPEED
private real turnSpd = DEFAULT_TURNSPEED
private boolean isTurning = false
private boolean turnForward = false
//: == ---------------------------- ----------------------------
//: # Unit/Wall/Dest/Missile Colliding
//: == ---------------------------- ----------------------------
private real hitRange = DEFAULT_HITRANGE
private boolean hitsUnits = DEFAULT_HITSUNITS
private boolean hitsWalls = DEFAULT_HITSWALLS
private boolean hitsDests = DEFAULT_HITSDESTS
private boolean hitsMissiles = DEFAULT_HITSMISSILES
//: == ---------------------------- ----------------------------
//: # Targets & Management
//: == ---------------------------- ----------------------------
private boolean hasTarget = false
private boolean checkHeight = DEFAULT_CHECKHEIGHT
private unit target = null
//: == ---------------------------- ----------------------------
//: # Enumeration & Filters
//: == ---------------------------- ----------------------------
private group enumGroup = null
private static boolexpr enumFilter = null
private static rect locRect = null
private boolean isInWall = false
//: == ---------------------------- ----------------------------
//: # Indexing & Structstuff
//: == ---------------------------- ----------------------------
private integer index = 0
private static thistype curInstance = 0
private static timer t = null
private static integer a = 0
private static thistype array i
//: == ---------------------------- ----------------------------
//: # Methods - Instance Creation
//: == ---------------------------- ----------------------------
public static method create takes real x, real y, real z, real f returns thistype
local thistype this = thistype.allocate()
//: Initialize our members
set .eff = CustomEffect.create(x, y, z, f)
set .start = Loc.create(x, y, z, 0.)
set .end = Loc.create(x, y, z, 0.)
set .enumGroup = NewGroup()
set .isAlive = true
set .isActive = true
set .index = thistype.a
set thistype.i[thistype.a] = this
set thistype.a = thistype.a +1
if thistype.a == 1 then
call TimerStart(thistype.t, CM_PERIOD, true, function thistype.run)
endif
return this
endmethod
//: == ---------------------------- ----------------------------
//: # Methods - Creating general behaviours
//: == ---------------------------- ----------------------------
stub method onWallHit takes nothing returns nothing
set .alive = false
set .active = false
endmethod
stub method onCollide takes CustomMissile theCollider returns nothing
set .alive = false
set .active = false
endmethod
stub method getMissileSpeed takes nothing returns real
return .moveSpd
endmethod
//: Thanks to moyack for this wonderful parabola
stub method getParabolaZ takes real y0, real y1, real h, real d, real x returns real
local real A = (2*(y0+y1)-4*h)/(d*d)
local real B = (y1-y0-A*d*d)/d
return A*x*x + B*x + y0
endmethod
//: == ---------------------------- ----------------------------
//: # Methods - Setting / Getting of members
//: == ---------------------------- ----------------------------
method operator xyarc takes nothing returns real
return .xyArc
endmethod
method operator xyarc= takes real val returns nothing
set .xyArc = val
endmethod
method operator zarc takes nothing returns real
return .zArc
endmethod
method operator zarc= takes real val returns nothing
set .zArc = val
endmethod
method operator height takes nothing returns real
return .h
endmethod
method operator height= takes real val returns nothing
set .h = val
endmethod
method operator decay takes nothing returns real
return .decy
endmethod
method operator decay= takes real val returns nothing
set .decy = val
if .decy > 0. then
set .hasDecay = true
else
set .hasDecay = false
endif
endmethod
method operator haze takes nothing returns real
return .hazeInc
endmethod
method operator haze= takes real val returns nothing
set .hazeInc = val
if .hazeInc > 0. then
set .hasHaze = true
else
set .hasHaze = false
endif
endmethod
public method hazeBounds takes real min, real max returns nothing
set .hazeMin = min
set .hazeMax = max
endmethod
method operator hitrange takes nothing returns real
return .hitRange
endmethod
method operator hitrange= takes real val returns nothing
set .hitRange = val
endmethod
method operator movespeed takes nothing returns real
return .moveSpd
endmethod
method operator movespeed= takes real val returns nothing
set .moveSpd = val
endmethod
method operator turnspeed takes nothing returns real
return .turnSpd / TWO_PI
endmethod
method operator turnspeed= takes real val returns nothing
set .turnSpd = TWO_PI * val
endmethod
method operator active takes nothing returns boolean
return .isActive
endmethod
method operator active= takes boolean bol returns nothing
set .isActive = bol
endmethod
method operator alive takes nothing returns boolean
return .isAlive
endmethod
method operator alive= takes boolean bol returns nothing
set .isAlive = bol
endmethod
method operator hitwalls takes nothing returns boolean
return .hitsWalls
endmethod
method operator hitwalls= takes boolean bol returns nothing
set .hitsWalls = bol
endmethod
method operator hitdests takes nothing returns boolean
return .hitsDests
endmethod
method operator hitdests= takes boolean bol returns nothing
set .hitsDests = bol
endmethod
method operator hitunits takes nothing returns boolean
return .hitsUnits
endmethod
method operator hitunits= takes boolean bol returns nothing
set .hitsUnits = bol
endmethod
method operator hitmissiles takes nothing returns boolean
return .hitsMissiles
endmethod
method operator hitmissiles= takes boolean bol returns nothing
set .hitsMissiles = bol
endmethod
method operator autoface takes nothing returns boolean
return .zAutoFace
endmethod
method operator autoface= takes boolean bol returns nothing
set .zAutoFace = bol
endmethod
method operator checkheight takes nothing returns boolean
return .checkHeight
endmethod
method operator checkheight= takes boolean bol returns nothing
set .checkHeight = bol
endmethod
public method getEnumGroup takes nothing returns group
return .enumGroup
endmethod
//: == ---------------------------- ----------------------------
//: # Methods - Targeting & Detargeting
//: == ---------------------------- ----------------------------
public method setTargetUnit takes unit u returns nothing
set .end.x = GetUnitX(u)
set .end.y = GetUnitY(u)
set .end.z = GetLocZ(.end.x, .end.y) + GetUnitFlyHeight(u) + .h / 2
call .start.applyLoc(.loc)
set .hasTarget = true
set .target = u
endmethod
public method setTargetUnitPos takes unit u returns nothing
call .setTargetPosZ(GetUnitX(u), GetUnitY(u), GetLocZ(x, y) + GetUnitFlyHeight(u))
endmethod
public method setTargetPos takes real x, real y returns nothing
set .end.x = x
set .end.y = y
set .end.z = GetLocZ(x, y) + .h / 2
call .start.applyLoc(.loc)
set .target = null
set .hasTarget = true
endmethod
public method setTargetPosZ takes real x, real y, real z returns nothing
set .end.x = x
set .end.y = y
set .end.z = z + .h / 2
call .start.applyLoc(.loc)
set .target = null
set .hasTarget = true
endmethod
public method looseTarget takes nothing returns nothing
set .end.x = .x
set .end.y = .y
set .end.z = .z
set .target = null
set .hasTarget = false
endmethod
//: == ---------------------------- ----------------------------
//: # Methods - Missile Movement
//: == ---------------------------- ----------------------------
private method updateTarget takes nothing returns nothing
if .hasTarget then
if .target != null then
set .end.x = GetUnitX(.target)
set .end.y = GetUnitY(.target)
set .end.z = GetLocZ(.end.x, .end.y) + GetUnitFlyHeight(.target)
endif
else
call .end.applyLoc(.eff.loc)
endif
endmethod
private method updateF takes nothing returns nothing
local real aimF = .eff.loc.angleTo(.end)
local real newF = 0.
if .eff.f != aimF and not .isTurning then
set .isTurning = true
if .eff.f < aimF then
set .turnForward = false
else
set .turnForward = true
endif
else
set .isTurning = false
return
endif
if .turnForward then
set newF = .eff.f + .turnSpd / (RAD_PER_PERIOD)
if newF >= aimF then
set newF = aimF
set .isTurning = false
endif
else
set newF = .eff.f - .turnSpd / (RAD_PER_PERIOD)
if newF <= aimF then
set newF = aimF
set .isTurning = false
endif
endif
set .f = newF
endmethod
private method updateXY takes nothing returns nothing
call .eff.loc.move(.getMissileSpeed() * CM_PERIOD)
set .eff.loc = .eff.loc
if .eff.loc.distanceTo(.end) < .hitRange then
if not .checkHeight or (.checkHeight and .eff.loc.z >= .end.z - .h /2 and .eff.loc.z <= .end.z + .h /2) then
set .alive = false
set .active = false
call .onTargetReach()
endif
endif
endmethod
private method updateZ takes nothing returns nothing
set .z = .getParabolaZ(.end.z, .start.z, (.start.z + .end.z) /2, .start.distanceTo(.end), .eff.loc.distanceTo(.end))
endmethod
private method updateZAngle takes nothing returns nothing
endmethod
private method updateXYarc takes nothing returns nothing
local Loc new = Loc.create(.x, .y, .z, .start.angleTo(.end))
local real dist = .start.distanceTo(.end)
local real toStart = .eff.loc.distanceTo(.start)
if .xyArc != 0. then
call new.moveFaced(ParabolaZ(dist * .xyArc, dist, toStart), new.f + bj_DEGTORAD * 90)
set new.f = new.angleTo(.end)
call .eff.applyLocOnce(new)
endif
if .hitsUnits then
call GroupEnumUnitsInRange(.enumGroup, new.x, new.y, .hitRange, thistype.enumFilter)
endif
if .hitsDests then
call SetRect(thistype.locRect, new.x - .hitRange, new.y - .hitRange, new.x + .hitRange, new.y + .hitRange)
call EnumDestructablesInRect(thistype.locRect, Condition(function thistype.enumDestsInRange), null)
endif
call new.destroy()
endmethod
private method updateZarc takes nothing returns nothing
local Loc new = Loc.create(.x, .y, .z, .start.angleTo(.end))
local real dist = .start.distanceTo(.end)
local real toStart = .eff.loc.distanceTo(.start)
if .zArc != 0. then
set new.z = ParabolaZ2(.start.z, .end.z, (.start.z + .end.z) /2 + dist * .zArc, dist, toStart)
call .eff.applyLocOnce(new)
endif
if new.z < GetLocZ(new.x, new.y) then
if .hitsWalls then
call .onWallHit()
endif
if not .isInWall and .alive then
set .isInWall = true
call ShowUnit(.getEffUnit(), false)
endif
else
if .isInWall then
set .isInWall = false
call ShowUnit(.getEffUnit(), true)
endif
endif
call new.destroy()
endmethod
private method haze takes nothing returns nothing
local Loc new = 0
if .hasHaze then
if .hazeNeg then
set .hazeCur = .hazeCur - .hazeInc * CM_PERIOD
if .hazeCur <= .hazeMin then
set .hazeCur = .hazeMin
set .hazeNeg = false
endif
else
set .hazeCur = .hazeCur + .hazeInc * CM_PERIOD
if .hazeCur >= .hazeMax then
set .hazeCur = .hazeMax
set .hazeNeg = true
endif
endif
set new = Loc.create(.x, .y, .z, .f)
call new.moveFaced(.hazeCur, .f + 90 * bj_DEGTORAD)
call .eff.applyLocOnce(new)
call new.destroy()
endif
endmethod
//: == ---------------------------- ----------------------------
//: # Methods - Instancemanagement & Instanceexecution
//: == ---------------------------- ----------------------------
private method move takes nothing returns nothing
if not .isCreated then
set .isCreated = true
call .onCreate()
else
call .onLoop()
if .hasDecay then
set .decy = .decy - CM_PERIOD
endif
if .decy < 0. then
set .alive = false
set .active = false
endif
endif
if not .isActive or not .isAlive then
return
endif
if not .isStarted then
set .isStarted = true
call .onStart()
endif
call .updateTarget()
call .updateXY()
call .updateF()
call .updateZ()
call .updateXYarc()
call .updateZarc()
call .updateZAngle()
call .haze()
if .hitsMissiles then
call .enumMissiles()
endif
endmethod
public static method run takes nothing returns nothing
local integer i = 0
if thistype.a == 0 then
call PauseTimer(thistype.t)
return
endif
loop
exitwhen i >= thistype.a
if not thistype.i<i>.alive then
call thistype.i<i>.destroy()
set thistype.a = thistype.a -1
set thistype.i<i> = thistype.i[thistype.a]
set thistype.i<i>.index = i
set i = i -1
else
set thistype.curInstance = thistype.i<i>
call thistype.i<i>.move()
endif
set i = i +1
endloop
endmethod
//: == ---------------------------- ----------------------------
//: # Methods - Enumeration of Missiles, Destructables, Units
//: == ---------------------------- ----------------------------
private method enumMissiles takes nothing returns nothing
local unit rallyThis = null
local unit rallyThat = null
local real dist = 0.
local thistype that = 0
local integer i = this.index +1
local boolean collide = false
loop
exitwhen i >= thistype.a or collide
set that = thistype.i<i>
set rallyThis = this.eff.getEffUnit()
set rallyThat = that.eff.getEffUnit()
if not this.checkHeight then
set dist = DistBetweenUnits(rallyThis, rallyThat)
else
set dist = DistBetweenUnitsZ(rallyThis, rallyThat)
endif
if dist <= .hitRange and dist != -1 then
set collide = true
endif
set i = i +1
endloop
set rallyThis = null
set rallyThat = null
if collide then
call this.onCollide(that)
call that.onCollide(this)
endif
endmethod
private static method enumUnitsInRange takes nothing returns boolean
local thistype this = thistype.curInstance
local unit u = GetFilterUnit()
local real z = GetLocZ(GetUnitX(u), GetUnitY(u)) + GetUnitFlyHeight(u)
if IsUnitInGroup(u, .enumGroup) then
return false
endif
if not .checkHeight or (.checkHeight and z >= .z - .h /2 and z <= .z + .h /2 ) then
call GroupAddUnit(.enumGroup, u)
call .onUnitTouch(u)
endif
set u = null
return false
endmethod
private static method enumDestsInRange takes nothing returns boolean
local thistype this = thistype.curInstance
local destructable d = GetFilterDestructable()
local real z = GetLocZ(GetDestructableX(d), GetDestructableY(d)) + GetDestructableOccluderHeight(d)
if not .checkHeight or (.checkHeight and z >= .z - .h /2 and z <= .z + .h /2 ) then
call .onDestTouch(GetFilterDestructable())
endif
set d = null
return false
endmethod
//: == ---------------------------- ----------------------------
//: # Methods - Destroying & Filter init
//: == ---------------------------- ----------------------------
private method onDestroy takes nothing returns nothing
set .alive = false
set .active = false
call .onEnd()
call .start.destroy()
call .end.destroy()
call .eff.destroy()
call ReleaseGroup(.enumGroup)
endmethod
private static method onInit takes nothing returns nothing
set thistype.enumFilter = Condition(function thistype.enumUnitsInRange)
set thistype.t = CreateTimer()
set .locRect = Rect(0., 0., 0., 0.)
endmethod
endstruct
endlibrary
</i></i></i></i></i></i></i>
//<o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o>
//: CustomEffect
//: by Anachron
//:
//: This system is thought to replace xefx.
//:
//: What it is:
//: This system uses a dummy unit to create an effect that is scale- and
//: colorizeble and gives the posability to modify it in any way you want.
//:
//: Credits:
//: Vexorian for xe(fx) [which I don't use]
//: Vexorian for ARGB (optional) [<a href="http://www.wc3c.net/showthread.php?t=101858]" target="_blank" class="link link--external" rel="nofollow ugc noopener">http://www.wc3c.net/showthread.php?t=101858]</a>
//:
//: Thanks to:
//: Slaydon, catch_ya, Flame_Phoenix, Element_Of_Water and Berbanog
//: for their input to the system. Without them this wouldn't be that
//: customizeable and would've less functionality.
//:
//<o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o>
library CustomEffect requires Loc, optional ARGB
globals
private constant integer EFFECT_UNIT_TYPE = 039;CExx039;
private constant integer EFFECT_HEIGHT_ENABLER = 039;Arav039;
private constant integer EFFECT_DISSELECT = 039;Aloc039;
private constant integer MAX_INSTANCES = 8190
endglobals
struct CustomEffect[MAX_INSTANCES]
private unit effUnit = null
private effect effHandle = null
private string effSFX = null
private Loc pos = 0
private real zAng = 0.
/* ------- Scale ------- */
private real scal = 1.
private real scalX = 1.
private real scalY = 1.
private real scalZ = 1.
/* ------- Color ------- */
private integer colr = 255
private integer colrA = 255
private integer colrR = 255
private integer colrG = 255
private integer colrB = 255
public static method create takes real x, real y, real z, real f returns thistype
local thistype this = thistype.allocate()
set .pos = Loc.create(x, y, z, f)
set .effUnit = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), EFFECT_UNIT_TYPE, x, y, bj_RADTODEG * f)
call UnitAddAbility (.effUnit, EFFECT_HEIGHT_ENABLER)
call SetUnitFlyHeight (.effUnit, z - GetLocZ(x, y), 0.)
call UnitRemoveAbility (.effUnit, EFFECT_HEIGHT_ENABLER)
call UnitAddAbility (.effUnit, EFFECT_DISSELECT)
return this
endmethod
//# ======= -----------------------------------
/* Position */
//# ======= -----------------------------------
method operator f takes nothing returns real
return .pos.f
endmethod
method operator f= takes real f returns nothing
set .pos.f = f
call SetUnitFacing(.effUnit, .pos.f * bj_RADTODEG)
endmethod
method operator x takes nothing returns real
return .pos.x
endmethod
method operator x= takes real x returns nothing
set .pos.x = x
call SetUnitX(.effUnit, .pos.x)
endmethod
method operator y takes nothing returns real
return .pos.y
endmethod
method operator y= takes real y returns nothing
set .pos.y = y
call SetUnitY(.effUnit, .pos.y)
endmethod
method operator z takes nothing returns real
return .pos.z
endmethod
method operator z= takes real z returns nothing
set .pos.z = z
call SetUnitFlyHeight(.effUnit, .pos.z - GetLocZ(pos.x, .pos.y), 0.)
endmethod
method operator zAngle takes nothing returns real
return .zAng
endmethod
method operator zAngle= takes real value returns nothing
local integer i = R2I(value * bj_RADTODEG + 90.5)
set this.zAng = value
if i >= 180 then
set i = 179
elseif i < 0 then
set i = 0
endif
call SetUnitAnimationByIndex(this.effUnit, i)
endmethod
method operator loc takes nothing returns Loc
return .pos
endmethod
method operator loc= takes Loc l returns nothing
call .pos.applyLoc(l)
call SetUnitFacing(.effUnit, .pos.f * bj_RADTODEG)
call SetUnitX(.effUnit, .pos.x)
call SetUnitY(.effUnit, .pos.y)
call SetUnitFlyHeight(.effUnit, .pos.z - GetLocZ(pos.x, .pos.y), 0.)
endmethod
public method applyLocOnce takes Loc l returns nothing
call SetUnitFacing(.effUnit, l.f * bj_RADTODEG)
call SetUnitX(.effUnit, l.x)
call SetUnitY(.effUnit, l.y)
call SetUnitFlyHeight(.effUnit, l.z - GetLocZ(l.x, l.y), 0.)
endmethod
//# ======= -----------------------------------
/* Scale */
//# ======= -----------------------------------
private method applyScale takes nothing returns nothing
call SetUnitScale(.effUnit, .scaleX, .scaleY, .scaleZ)
endmethod
method operator scaleX takes nothing returns real
return .scalX
endmethod
method operator scaleX= takes real s returns nothing
set .scalX = s
call .applyScale()
endmethod
method operator scaleY takes nothing returns real
return .scalX
endmethod
method operator scaleY= takes real s returns nothing
set .scalY = s
call .applyScale()
endmethod
method operator scaleZ takes nothing returns real
return .scalZ
endmethod
method operator scaleZ= takes real s returns nothing
set .scalZ = s
call .applyScale()
endmethod
method operator scale takes nothing returns real
return .scal
endmethod
method operator scale= takes real s returns nothing
set .scal = s
set .scalX = s
set .scalY = s
set .scalZ = s
call .applyScale()
endmethod
//# ======= -----------------------------------
/* Color */
//# ======= -----------------------------------
private method applyColor takes nothing returns nothing
call SetUnitVertexColor(.effUnit, .colorR, .colorG, .colorB, .colorA)
endmethod
method operator colorA takes nothing returns integer
return .colrA
endmethod
method operator colorA= takes integer c returns nothing
set .colrA = c
call .applyColor()
endmethod
method operator colorR takes nothing returns integer
return .colrA
endmethod
method operator colorR= takes integer c returns nothing
set .colrR = c
call .applyColor()
endmethod
method operator colorG takes nothing returns integer
return .colrG
endmethod
method operator colorG= takes integer c returns nothing
set .colrG = c
call .applyColor()
endmethod
method operator colorB takes nothing returns integer
return .colrB
endmethod
method operator colorB= takes integer c returns nothing
set .colrB = c
call .applyColor()
endmethod
method operator color takes nothing returns integer
return .colr
endmethod
method operator color= takes integer c returns nothing
set .colrA = c
set .colrR = c
set .colrG = c
set .colrB = c
call .applyColor()
endmethod
public method colorARGB takes integer a, integer r, integer g, integer b returns nothing
set .colrA = a
set .colrR = r
set .colrG = g
set .colrB = b
call .applyColor()
endmethod
static if LIBRARY_ARGB then
public method ARGB takes ARGB color returns nothing
set .colrA = color.alpha
set .colrR = color.red
set .colrG = color.green
set .colrB = color.blue
call .applyColor()
endmethod
endif
//# ======= -----------------------------------
/* Misc */
//# ======= -----------------------------------
method operator owner takes nothing returns player
return GetOwningPlayer(.effUnit)
endmethod
method operator owner= takes player p returns nothing
call SetUnitOwner(.effUnit, p, false)
endmethod
method operator sfx takes nothing returns effect
return .effHandle
endmethod
method operator sfx= takes string sfx returns nothing
call DestroyEffect(.effHandle)
set .effHandle = AddSpecialEffectTarget(sfx, .effUnit, "origin")
endmethod
public method getEffUnit takes nothing returns unit
return .effUnit
endmethod
//# ======= -----------------------------------
/* Effects */
//# ======= -----------------------------------
public method createEffOnPos takes string sfx returns effect
return AddSpecialEffect(sfx, .pos.x, .pos.y)
endmethod
private method onDestroy takes nothing returns nothing
call DestroyEffect(.effHandle)
call .loc.destroy()
call RemoveUnit(.effUnit)
endmethod
endstruct
endlibrary
//<o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o>
//: Loc
//: by Anachron
//:
//: Simple library to give me more control about locations.
//: Feel free to use it without credits.
//<o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o>
library Loc
globals
private constant location zLoc = Location(0, 0)
constant real TWO_PI = 2 * bj_PI
endglobals
//! textmacro CMPos_addOperator takes name, type, object
method operator $name$= takes $type$ val returns nothing
set .$object$ = val
endmethod
method operator $name$ takes nothing returns $type$
return .$object$
endmethod
//! endtextmacro
function GetLocZ takes real x, real y returns real
call MoveLocation(zLoc, x, y)
return GetLocationZ(zLoc)
endfunction
function makeRealAngle takes real a returns real
loop
exitwhen a < TWO_PI and a >= 0.
if a < 0 then
set a = a + TWO_PI
elseif a > TWO_PI then
set a = a - TWO_PI
endif
endloop
return a
endfunction
struct Loc
private real F = 0.
private real X = 0.
private real Y = 0.
private real Z = 0.
//! runtextmacro CMPos_addOperator("f", "real", "F")
//! runtextmacro CMPos_addOperator("x", "real", "X")
//! runtextmacro CMPos_addOperator("y", "real", "Y")
//! runtextmacro CMPos_addOperator("z", "real", "Z")
public static method create takes real x, real y, real z, real f returns thistype
local thistype this = thistype.allocate()
set .F = f
set .X = x
set .Y = y
set .Z = z
return this
endmethod
public method angleTo takes thistype that returns real
return makeRealAngle(Atan2(that.y - .y, that.x - .x))
endmethod
public method distanceTo takes thistype that returns real
local real dx = that.x - .x
local real dy = that.y - .y
return SquareRoot(dx * dx + dy * dy)
endmethod
public method distanceToZ takes thistype that returns real
local real dist = .distanceTo(that)
local real zDist = that.z - .z
return dist + SquareRoot(zDist * zDist)
endmethod
public method move takes real d returns nothing
set .x = .x + d * Cos(.f)
set .y = .y + d * Sin(.f)
endmethod
public method moveFaced takes real d, real f returns nothing
set .x = .x + d * Cos(f)
set .y = .y + d * Sin(f)
endmethod
public method applyNew takes real x, real y, real z, real f returns nothing
set .f = f
set .x = x
set .y = y
set .z = z
endmethod
public method applyLoc takes thistype that returns nothing
set .f = that.f
set .x = that.x
set .y = that.y
set .z = that.z
endmethod
public method clone takes nothing returns thistype
local thistype that = thistype.allocate()
set that.f = .f
set that.x = .x
set that.y = .y
set that.z = .z
return that
endmethod
endstruct
function AngleBetweenUnits takes unit first, unit sec returns real
local Loc lFirst = Loc.create(GetUnitX(first), GetUnitY(first), 0., 0.)
local Loc lSec = Loc.create(GetUnitX(sec), GetUnitY(sec), 0., 0.)
local real angle = 0.
if first == null or sec == null then
set angle = -1.
else
set angle = lFirst.angleTo(lSec)
endif
call lFirst.destroy()
call lSec.destroy()
return angle
endfunction
function DistBetweenUnits takes unit first, unit sec returns real
local real zFirst = GetLocZ(GetUnitX(first), GetUnitY(first)) + GetUnitFlyHeight(first)
local real zSec = GetLocZ(GetUnitX(sec), GetUnitY(sec)) + GetUnitFlyHeight(sec)
local Loc lFirst = Loc.create(GetUnitX(first), GetUnitY(first), zFirst, GetUnitFacing(first))
local Loc lSec = Loc.create(GetUnitX(sec), GetUnitY(sec), zSec, GetUnitFacing(sec))
local real dist = 0.
if first == null or sec == null then
set dist = -1.
else
set dist = lFirst.distanceTo(lSec)
endif
call lFirst.destroy()
call lSec.destroy()
return dist
endfunction
function DistBetweenUnitsZ takes unit first, unit sec returns real
local real zFirst = GetLocZ(GetUnitX(first), GetUnitY(first)) + GetUnitFlyHeight(first)
local real zSec = GetLocZ(GetUnitX(sec), GetUnitY(sec)) + GetUnitFlyHeight(sec)
local Loc lFirst = Loc.create(GetUnitX(first), GetUnitY(first), zFirst, GetUnitFacing(first))
local Loc lSec = Loc.create(GetUnitX(sec), GetUnitY(sec), zSec, GetUnitFacing(sec))
local real dist = 0.
if first == null or sec == null then
set dist = -1.
else
set dist = lFirst.distanceToZ(lSec)
endif
call lFirst.destroy()
call lSec.destroy()
return dist
endfunction
endlibrary