| 03-08-2008, 03:28 PM | #1 |
I haven't a clue on how to make MUI work for my spells. Can anyone point in the right direction on making MUI. I know it uses arrays and globals that manage how many instances are in each array, but I have no idea on how to handle them and make sure the right ones are moving. Here is my code JASS:library UserDecFunctions function Expiration takes nothing returns nothing call KillUnit(CascadingCatacylsm.ProjDummy) endfunction //Functions used in the structs (IE, Collision functions) made by you go here function TenSeconds takes nothing returns nothing local unit u = udg_TEMPUnit local effect e = udg_TEMPEffect local integer x = 0 loop exitwhen x==10 call PolledWait(1) if (IsUnitAliveBJ(u)== false) then call UnitRemoveAbility(u,'A002') call DestroyEffect(e) return endif set x = x+1 endloop call UnitRemoveAbility(u,'A002') call DestroyEffect(e) endfunction function IsNotCascading takes nothing returns boolean if (GetUnitTypeId(GetEnumUnit())=='u000') then return false else return true endif endfunction function CollisionEx takes nothing returns nothing if (UnitHasBuffBJ(GetEnumUnit(),'B000')==false) then if (IsUnitAliveBJ(GetEnumUnit())==true) then call SetUnitState((GetEnumUnit()), UNIT_STATE_LIFE, GetUnitState(GetEnumUnit(),UNIT_STATE_LIFE)-CascadingCatacylsm.Damage) set CascadingCatacylsm.Size = CascadingCatacylsm.Size+.1 call SetUnitScale(CascadingCatacylsm.ProjDummy,CascadingCatacylsm.Size,CascadingCatacylsm.Size,CascadingCatacylsm.Size) set CascadingCatacylsm.Damage = CascadingCatacylsm.Damage+25+(R2I((CascadingCatacylsm.Level/3))*25) set CascadingCatacylsm.ObjectCollisionSize = CascadingCatacylsm.ObjectCollisionSize+.75 call TimerStart( udg_CascCataTimer, ( TimerGetRemaining(udg_CascCataTimer) + 0.25 ), false,function Expiration ) set udg_TEMPEffect = AddSpecialEffectTarget("Abilities\\Spells\\Items\\OrbDarkness\\OrbDarkness.mdl",GetEnumUnit(),"overhead") call UnitAddAbility(GetEnumUnit(),'A002') set udg_TEMPUnit = GetEnumUnit() call ExecuteFunc("TenSeconds") endif else endif endfunction function OnUnitCollision takes nothing returns nothing local group g set g = GetUnitsInRangeOfLocMatching(CascadingCatacylsm.ObjectCollisionSize,GetUnitLoc(CascadingCatacylsm.ProjDummy), Condition(function IsNotCascading)) call ForGroup(g, function CollisionEx) endfunction endlibrary library VectorLib //////////////////////////////////// //This is TheSecretArts' // //WIP Basic Vector System // //Only for use in Spell Making // //Contest #10. Only TheSecretArts// //can use this system. // //////////////////////////////////// globals Vector GRAVITYVECTOR Vector MathVector trigger initialization endglobals struct Vector real x //This detirmines where the vector 'is' real y //This detirmines where the vector 'is' real z //This detirmines where the vector 'is' real Fx //These values are counterintuitive from what you might think real Fy //These are based on planes, rather than force, a negative is backwards, thats why there is no directional value real Fz //This way, it requires less math and is easier and less taxing if many events are happening at once //the force values should be speed/sec. method SetX takes real x returns nothing set this.x = x endmethod method SetY takes real y returns nothing set this.y = y endmethod method SetZ takes real z returns nothing set this.z = z endmethod method SetFx takes real m returns nothing set this.Fx = m endmethod method SetFy takes real m returns nothing set this.Fy = m endmethod method SetFz takes real m returns nothing set this.Fz = m endmethod static method create takes real X, real Y, real Z, real FX, real FY, real FZ returns Vector local Vector Vec = Vector.allocate() set Vec.x = X set Vec.y = Y set Vec.z = Z set Vec.Fz = FZ set Vec.Fy = FY set Vec.Fx = FX return Vec endmethod endstruct function VectorNull takes Vector A returns Vector set MathVector.x = A.x set MathVector.y = A.y set MathVector.z = A.z set MathVector.Fx = 0 set MathVector.Fy = 0 set MathVector.Fz = 0 return MathVector endfunction // function VectorNormal takes Vector A returns Vector // local Vector v2 = Vector.create(A.x,A.y,A.z,1,1,1) VectorNormal requires some trig and stuff i don't understand // return v2 // endfunction function VectorAdd takes Vector A, Vector B returns Vector set MathVector.Fx = A.Fx + B.Fx set MathVector.Fy = A.Fy + B.Fy set MathVector.Fz = A.Fz + B.Fz return MathVector endfunction function VectorSubtract takes Vector A, Vector B returns Vector set MathVector.Fx = A.Fx - B.Fx set MathVector.Fy = A.Fy - B.Fy set MathVector.Fz = A.Fz - B.Fz return MathVector endfunction function VectorMultiply takes Vector A, Vector B returns Vector set MathVector.Fx = A.Fx * B.Fx set MathVector.Fy = A.Fy * B.Fy set MathVector.Fz = A.Fz * B.Fz return MathVector endfunction function VectorDivide takes Vector A, Vector B returns Vector set MathVector.Fx = A.Fx / B.Fx set MathVector.Fy = A.Fy / B.Fy set MathVector.Fz = A.Fz / B.Fz return MathVector endfunction function SYSTEMINIT takes nothing returns nothing //MUST BE CALLED ON INITIALIZATION, I CAN'T STRESS THIS ENOUGH. set MathVector = Vector.create(0,0,0,0,0,0) set GRAVITYVECTOR = Vector.create(0,0,0,0,0,-9.8) set GRAVITYVECTOR.Fz = 0 //(I've modified it so that my projectiles won't fall.) endfunction endlibrary library ProjSyst needs VectorLib, UserDecFunctions /////////////////////////////////////// //This is TheSecretArts' WIP // //projectile system. // //This version is for use with // //Spell Making Contest #10 ONLY // //Only TheSecretArts can use this WIP// /////////////////////////////////////// globals Projectile CascadingCatacylsm endglobals struct Projectile real TimeLife private real BaseTerrainLevel // This is used when FollowsTerrainHeight is FALSE, this stands as the base terrain level // real Cd //This is the drag coefficient, this effects how air drag effects the projectile // real RA //This is the reference area, this is used in calculating drag real ObjectCollisionSize //Say the unit has a proximity effect, this would allow control over that proximity size // real Mass // To make a projectile that doesnt fall, set mass to zero location TargetPoint unit Target //More or less for homing projectiles unit ProjDummy integer Level real Damage real Size real TimeStep // boolean EffectedByWind //At the moment this does not effect the unit, but when wind is implemented, spells that create wind or natural wind will not effect the projectile, for most objects this should probably be used. // boolean HitsCliffs //this could be toggled false so that it floats through cliffs boolean HitsUnits // boolean ExplodesOnGround // boolean FollowsTerrainHeight //This is a big one, this determines wether the unit's z is based off terrain height, or a base level (the base level is intially based of terrain height, but then becomes independed of terrain height) // boolean HitsCaster //If the spell rebounds back by some means, can it hit the caster // boolean HitsAllies // string CasterCollision //Function name to run on caster collision // string AllyCollision //Function name to run on allied collision string UnitCollision //Function name to run on unit collision, will check if you hit allies and if this unit can hit allies. // string GroundCollision //Function name to run on Ground collision // string CliffCollision //Function name to run on cliff collision Vector Ve=0 method Initialization takes real x, real y, real z, real Fx, real Fy, real Fz returns nothing set this.Ve = Vector.create(x,y,z,Fx,Fy,Fz) set this.Ve.x = x set this.Ve.y = y set this.Ve.z = z set this.Ve.Fx = Fx set this.Ve.Fy = Fy set this.Ve.Fz = Fz endmethod method DetectCliffCollision takes nothing returns nothing // Placeholder endmethod method DetectUnitCollision takes nothing returns nothing local boolean TFBool = this.CheckCollision() if (TFBool==TRUE) then call ExecuteFunc(this.UnitCollision) endif endmethod method SetFacingAngleToTargetedPoint takes nothing returns nothing call SetUnitFacing(this.ProjDummy,3.14159/180.0 * Atan2(GetLocationY(this.TargetPoint) - GetLocationY(GetUnitLoc(this.ProjDummy)), GetLocationX(this.TargetPoint) - GetLocationX(GetUnitLoc(this.ProjDummy)))) endmethod method SetFacingAngleToTargetedUnit takes nothing returns nothing // This allows a 'homing' projectile call SetUnitFacing(this.ProjDummy,3.14159/180.0 * Atan2(GetLocationY(GetUnitLoc(this.Target)) - GetLocationY(GetUnitLoc(this.ProjDummy)), GetLocationX(GetUnitLoc(this.Target)) - GetLocationX(GetUnitLoc(this.ProjDummy)))) endmethod // method GetGravForce takes nothing returns real // return (this.Mass * GLOBALMASS) //Placeholder for actual grav formula // endmethod method SetNewXYZ takes nothing returns nothing //Doesnt move unit, just sets the values to prepare movement. Has a use for debugging set this.Ve.x = this.Ve.x + (this.Ve.Fx * this.TimeStep) set this.Ve.y = this.Ve.y + (this.Ve.Fy * this.TimeStep) // if (this.FollowsTerrainHeight == TRUE) then call VectorAdd(this.Ve,GRAVITYVECTOR) // set this.Ve.z = this.Ve.Fz + this.Ve.z // else // ((z-grav*X)*TS) // call VectorAdd(v,GRAVITYVECTOR) // set this.Ve.Fz = (TERRAINHEIGHT-this.BaseTerrainLevel) set this.Ve.z = this.Ve.Fz + this.Ve.z // endif endmethod method MoveToXYZ takes nothing returns nothing call SetUnitPosition(this.ProjDummy,this.Ve.x,this.Ve.y) call UnitAddAbility(this.ProjDummy,'Amrf') call SetUnitFlyHeight(this.ProjDummy,this.Ve.z,0) call UnitRemoveAbility(this.ProjDummy,'Amrf') endmethod method SmartMove takes nothing returns nothing // this pretty much combines MovetoXYZ and SetNewXYZ set this.Ve.x = this.Ve.x + (this.Ve.Fx * this.TimeStep) set this.Ve.y = this.Ve.y + (this.Ve.Fy * this.TimeStep) // if (this.FollowsTerrainHeight == TRUE) then call VectorAdd(this.Ve,GRAVITYVECTOR) // set this.Ve.z = this.Ve.Fz + this.Ve.z // else // ((z-grav*X)*TS) // call VectorAdd(this.Ve,GRAVITYVECTOR) // set this.Ve.Fz = (TERRAINHEIGHT-this.BaseTerrainLevel) set this.Ve.z = this.Ve.Fz + this.Ve.z // endif call SetUnitPosition( this.ProjDummy , this.Ve.x , this.Ve.y ) call UnitAddAbility( this.ProjDummy , 'Amrf' ) call SetUnitFlyHeight( this.ProjDummy , this.Ve.z , 0 ) call UnitRemoveAbility( this.ProjDummy , 'Amrf' ) call this.DetectUnitCollision() endmethod method CheckCollision takes nothing returns boolean local group g = GetUnitsInRangeOfLocAll(this.ObjectCollisionSize,GetUnitLoc(this.ProjDummy)) if (CountUnitsInGroup(g)>0) then return TRUE else return FALSE endif endmethod endstruct endlibrary library CascadingCataclysm needs ProjSyst /////////////////////////////////////////// //This is spell making contest #10 // //entry: Cascading Cataclysm // //Also check the Library UserDecFunctions// //for it also contains part of this spell// //that is used by my system. // /////////////////////////////////////////// globals trigger Move trigger CheckCast trigger CheckExpire trigger Master endglobals function MoveConditions takes nothing returns boolean if (R2I(TimerGetRemaining(udg_CascCataTimer)) > 0 ) then return true endif return false endfunction function MoveActions takes nothing returns nothing call CascadingCatacylsm.SmartMove() endfunction function Trig_OnCast_Conditions takes nothing returns boolean if ( not ( GetSpellAbilityId() == 'A001' ) ) then return false endif return true endfunction function CalculateForceX takes unit u returns real local location p = PolarProjectionBJ(GetUnitLoc(u), 1000.00, GetUnitFacing(u)) local real XMX //X minus X to find total X change local real XC //X over (distance/speed) 1000/200=5 set XMX = GetLocationX(p)-GetLocationX(GetUnitLoc(u)) set XC = (XMX/2) return XC endfunction function CalculateForceY takes unit u returns real local location p = PolarProjectionBJ(GetUnitLoc(u), 1000.00, GetUnitFacing(u)) local real YMY //Y minus Y local real YC //Y over (distance/speed) set YMY = GetLocationY(p)-GetLocationY(GetUnitLoc(u)) set YC = (YMY/2) return YC endfunction function Casted takes nothing returns nothing local unit U call CreateNUnitsAtLocFacingLocBJ( 1, 'u000', Player(0), GetUnitLoc(GetTriggerUnit()), OffsetLocation(GetSpellTargetLoc(), 0, 0) ) set U = GetLastCreatedUnit() set CascadingCatacylsm = Projectile.create() call CascadingCatacylsm.Initialization(GetUnitX(U),GetUnitY(U),100,CalculateForceX(GetTriggerUnit()),CalculateForceY(GetTriggerUnit()),0) set CascadingCatacylsm.Level = GetUnitAbilityLevel(GetTriggerUnit(),'A001') set CascadingCatacylsm.ObjectCollisionSize =75 set CascadingCatacylsm.Size = 1 set CascadingCatacylsm.Damage = ((25*(CascadingCatacylsm.Level)))+25 set CascadingCatacylsm.ProjDummy = U set CascadingCatacylsm.TimeStep = .01 set CascadingCatacylsm.TimeLife = ((.5*(CascadingCatacylsm.Level)))+1.5 set CascadingCatacylsm.HitsUnits = TRUE set CascadingCatacylsm.UnitCollision = "OnUnitCollision" call SetUnitFacing(CascadingCatacylsm.ProjDummy,GetUnitFacing(GetTriggerUnit())) set CascadingCatacylsm.TargetPoint = PolarProjectionBJ(GetUnitLoc(GetTriggerUnit()), 1000.00, GetUnitFacing(GetTriggerUnit())) call TimerStart( udg_CascCataTimer, CascadingCatacylsm.TimeLife, false, function Expiration ) endfunction endlibrary |
| 03-10-2008, 12:27 PM | #2 |
bump, are there any make-a-spell MUI tutorials at all or any tutorials that could help me? |
| 03-10-2008, 03:39 PM | #3 |
MUI is not a system, is more related in the way you code. If you want to make your spells MUI, you must code in such way that if you have 20 units and they cast at the same time a triggered spell, the code and the behavior of the spell won't be affected among them. So, the test is easy: put several units with the spell in the map, and then put them to cast the spell at the same time on a target, if the spell behavior is affected in a bad way, then your spell is not MUI. How to ensure your spell is MUI? use local vars, and if you need to transfer data from one function to another (aka send data to a timer or trigger) then use handlevars, ABC, etc. |
| 03-10-2008, 03:53 PM | #4 |
I do send data to a function with a trigger, but it uses a global... so I might need to do a little recoding. I think I'll just create a couple arrays for the struct, the timer, and an index variable and just destroy everything on expiration and re-initialize and creation... that should make it MUI. I already know my spell isn't MUI. What I'd imagine would happen is that one would stop moving. |
