| 05-19-2006, 10:43 PM | #1 |
Ok im sorry for this, its confusing, i probly have 100 leaks and big mistakes, but i dont mind about the leaks just yet, its just the mistakes. I get no compile errors, but nothings happening. Please please could somebody point me in the right direction. Iv split this up into 3 sections of code. 1) Basic stuff: JASS:// Globals (Only used for Jass Editing Programs) globals gamecache udg_GC = null endglobals // Constants constant function MoveProjectileSpeed takes nothing returns real return 0.04 endfunction constant function DummyAbilityID takes nothing returns integer return 'nzin' endfunction constant function FlyAbilityID takes nothing returns integer return 'amrf' endfunction constant function MinRangeProjectileCollision takes nothing returns real return 25. endfunction constant function DistanceMovedPerInterval takes real speed returns real return speed / 1000 endfunction // Game Cache Return function GC takes nothing returns gamecache if(udg_GC == null) then call FlushGameCache(InitGameCache("GC")) set udg_GC = InitGameCache("GC") endif return udg_GC endfunction // Handle Variables function H2I takes handle H returns integer return H return 0 endfunction function I2Effect takes integer I returns effect return I return null endfunction function I2Unit takes integer I returns unit return I return null endfunction function I2AttackType takes integer I returns attacktype return I return null endfunction function I2DamageType takes integer I returns damagetype return I return null endfunction Then i have the midiumish type code, just to save some space and time: JASS:// Well Used Functions Helpers function SafeX takes real x returns boolean local rect r = bj_mapInitialPlayableArea local real maxX = GetRectMaxX(r) local real minX = GetRectMinX(r) if(x > maxX) then return false elseif(x < minX) then return false endif set r = null return true endfunction function SafeY takes real y returns boolean local rect r = bj_mapInitialPlayableArea local real maxY = GetRectMaxY(r) local real minY = GetRectMinY(r) if(y > maxY) then return false elseif(y < minY) then return false endif set r = null return true endfunction function SafeLoc takes real x, real y returns boolean local boolean xUnsafe = true local boolean yUnsafe = true set xUnsafe = SafeX(x) set yUnsafe = SafeY(y) if(xUnsafe == false) and (yUnsafe == false) then return true endif return false endfunction function SafeLocEx takes location l returns boolean return SafeLoc(GetLocationX(l), GetLocationY(l)) endfunction function MoveUnit takes unit whichUnit, real x, real y returns nothing if(SafeLoc(x, y) == true) then call SetUnitX(whichUnit, x) call SetUnitY(whichUnit, y) endif endfunction function ReturnEffectWithHeight takes string modelPath, real x, real y, real height returns effect local unit u = CreateUnit(Player(11), DummyAbilityID(), x, y, 0.) local effect e = AddSpecialEffectTarget(modelPath, u, "overhead") if(SafeLoc(x, y) == false) then call KillUnit(u) call DestroyEffect(e) set u = null set e = null else call UnitAddAbility(u, FlyAbilityID()) call SetUnitFlyHeight(u, height, 0.) call StoreReal(GC(), I2S(H2I(e)), "EffectHeight", height) call StoreString(GC(), I2S(H2I(e)), "EffectModel", modelPath) call StoreInteger(GC(), I2S(H2I(e)), "EffectAttachedUnit", H2I(u)) return e endif return null endfunction function CopyHeightEffectWithCoords takes effect e, real x, real y returns effect local effect sourceEffect = e local string sourceModel = GetStoredString(GC(), I2S(H2I(e)), "EffectModel") local real sourceHeight = GetStoredReal(GC(), I2S(H2I(e)), "EffectHeight") return ReturnEffectWithHeight(sourceModel, x, y, sourceHeight) endfunction function DestroyEffectEx takes effect e returns nothing local unit attachedUnit = I2Unit(GetStoredInteger(GC(), I2S(H2I(e)), "EffectAttachedUnit")) call FlushStoredMission(GC(), I2S(H2I(e))) call DestroyEffect(e) call KillUnit(attachedUnit) set attachedUnit = null endfunction function GetEffectLoc takes effect whichEffect returns location return GetUnitLoc(I2Unit(GetStoredInteger(GC(), I2S(H2I(whichEffect)), "EffectAttachedUnit"))) endfunction function IsRealInBetween takes real whichReal, real min, real max returns boolean if(whichReal > max) then return false endif if(whichReal < min) then return false endif return true endfunction and then i have the main launch projectile functions, using a timer as a loop type function. JASS:function LaunchProjectile_Adult takes nothing returns nothing local timer t = GetExpiredTimer() local unit targ = I2Unit(GetStoredInteger(GC(), I2S(H2I(t)), "LaunchProjectile_Target")) local unit credit = I2Unit(GetStoredInteger(GC(), I2S(H2I(t)), "LaunchProjectile_Credit")) local real targX = GetUnitX(targ) local real targY = GetUnitY(targ) local location targLoc = Location(targX, targY) local real newX local real newY local real speed = GetStoredInteger(GC(), I2S(H2I(t)), "LaunchProjectile_Speed") local effect oldEffect = I2Effect(GetStoredInteger(GC(), I2S(H2I(t)), "LaunchProjectile_Effect")) local effect newEffect local location effectLoc = GetEffectLoc(oldEffect) local real currentX = GetLocationX(effectLoc) local real currentY = GetLocationY(effectLoc) local real amount = GetStoredReal(GC(), I2S(H2I(t)), "LaunchProjectile_Damage") local attacktype attackType = I2AttackType(GetStoredInteger(GC(), I2S(H2I(t)), "LaunchProjectile_AttackType")) local damagetype damageType = I2DamageType(GetStoredInteger(GC(), I2S(H2I(t)), "LaunchProjectile_DamageType")) set newX = currentX + DistanceMovedPerInterval(speed) * Cos(AngleBetweenPoints(targLoc, effectLoc) * bj_DEGTORAD) set newY = currentY + DistanceMovedPerInterval(speed) * Sin(AngleBetweenPoints(targLoc, effectLoc) * bj_DEGTORAD) if(IsRealInBetween(newX, (targX + MinRangeProjectileCollision()), (targX - MinRangeProjectileCollision())) == true) and (IsRealInBetween(newY, (targY + MinRangeProjectileCollision()), (targY - MinRangeProjectileCollision())) == true) then call FlushStoredMission(GC(), I2S(H2I(t))) call UnitDamageTarget(credit, targ, amount, true, false, attackType, damageType, WEAPON_TYPE_WHOKNOWS) call DestroyEffect(newEffect) call DestroyTimer(t) set newEffect = null set t = null set attackType = null set damageType = null else set newEffect = CopyHeightEffectWithCoords(oldEffect, newX, newY) call StoreInteger(GC(), I2S(H2I(t)), "LaunchProjectile_Effect", H2I(newEffect)) call TimerStart(t, MoveProjectileSpeed(), false, function LaunchProjectile_Adult) endif call DestroyEffectEx(oldEffect) call RemoveLocation(targLoc) call RemoveLocation(effectLoc) set targLoc = null set oldEffect = null set effectLoc = null endfunction function LaunchProjectile_Child takes unit credit, unit target, real damage, real x, real y, real height, real speed, string modelPath, attacktype attackType, damagetype damageType returns nothing local timer t = CreateTimer() local effect e = ReturnEffectWithHeight(modelPath, x, y, height) call StoreInteger(GC(), I2S(H2I(t)), "LaunchProjectile_AttackType", H2I(attackType)) call StoreInteger(GC(), I2S(H2I(t)), "LaunchProjectile_DamageType", H2I(damageType)) call StoreInteger(GC(), I2S(H2I(t)), "LaunchProjectile_Credit", H2I(credit)) call StoreInteger(GC(), I2S(H2I(t)), "LaunchProjectile_Target", H2I(target)) call StoreReal(GC(), I2S(H2I(t)), "LaunchProjectile_Damage", damage) call StoreInteger(GC(), I2S(H2I(t)), "LaunchProjectile_Effect", H2I(e)) call StoreReal(GC(), I2S(H2I(t)), "LaunchProjectile_Speed", speed) call TimerStart(t, MoveProjectileSpeed(), false, function LaunchProjectile_Adult) endfunction |
| 05-19-2006, 11:15 PM | #2 |
What exactly is this "Custom Launch Projectile" and what's it supposed to do? Can't help you if we don't know what you want to do. |
| 05-19-2006, 11:24 PM | #3 |
Well, I have some criticisms to start. I'm not sure if they will help, but I'm mentioning them because I'm a little confused. First, look at ReturnEffectWithHeight. If your effect with height is going to be an effect attached to a unit, why not simply create a single unit with an attached effect and move the unit instead of creating a bunch of units that get left over and you can't do anything about? Second, also dealing with ReturnEffectWithHeight, it might just be me but it seems counterproductive to test for a safe location after creating the unit. Another thing, just some notation things really, so it's up to you in the end, but usually the Parent function calls the Child function, you seem to have the order reversed. MoveProjectileSpeed probably should be called something like TimerDuration or TimerPeriod, it's a little confusing otherwise because one might thing that's the speed that the projectile's supposed to move instead of how often. Anyway, interesting naming conventions aside, DistanceMovedPerInterval is the definition of speed, so to get the distance moved you want to multiply the speed by the period. That way, you don't have to worry about doing any other calculations. It looks like you have the right idea, but I'm not sure about what's going on with IsRealBetween because for that method you'd need to check direction to know which way is the maximum and which way is minimum. Instead I'd suggest simply using the Pythagorean Theorem (Distance formula) and seeing if the distance between the projectile and the target is less than the collision radius. That last thing I mentioned is the only problem that might be preventing your projectile from moving unless the value you used for speed is too small so the distance moved is too small to be noticed. If your problem is completely different and you can't even get an effect to appear, it may have something to do with the effect your using or the event or condition of your trigger (assuming you're using a trigger). |
| 05-19-2006, 11:42 PM | #4 |
@ MysticGeneral, Custom Launch function i created should have the same effect of the "attack" method, create a projectile that follows the unit until it hits it and when it does it damages it. @ Naakaloh, Wow, thanks for the great reply , alot of feedback their. I do have alot of things muddeled up, but its the first time iv gone that advanced, i just normally stick to abit of attaching handles to timers and thats about it. I really couldent figure out a way of making the effect follow a unit, because if the unit moves, the projectile must change its course. So i decided to use Polar offset. I will change it in the morning, i have to sleep now. Thanks for the infomation. The function IsRealBetween is a lame function name, i couldent come up with a good 1, all it really does is checks if real whichReal is inbetween real min and real max, if it is return true else return false. Sorry for the mix ups. |
| 05-20-2006, 12:04 AM | #5 |
You're quite welcome. About IsRealBetween, I see what it's doing now, at first I thought you were checking it in a different way. I was suggesting just doing something like this so you don't have to check as many conditions: JASS:if( DistanceBetweenPoints( effectLoc, targLoc ) < CollisionRange() == true ) then ... endif As for getting an effect to follow a unit: JASS:native AddSpecialEffectTarget (string modelName, widget targetWidget, string attachPointName) returns effect In most cases you can just use attachPointName = "origin" and the effect will move with the unit. |
| 05-20-2006, 07:12 AM | #6 |
Well, the reason i dident make the effect move with the unit is: I started making my code, and was going to make a effect every 0.04 secs. Then i realised i needed height for the effect, so i had to create a dummy unit and attach the effect. By then i dident have the code sorted out for the "just make the unit move" solution. I might just change the units speed and order him to move to position of targ. Its probally easier. Thanks again |
