| 04-15-2009, 11:11 AM | #1 |
Hi guys, I am trying to make a spell that creates a summon with his own life (a flying bird). this is not hard, however I want him to move in a "circular" fashion. This means, I want him to move in circles to places. Also he must be able to attack enemies in circular fashion. I saw some spells doing it, but they are poorly coded. So I wonder, is there a good solution any of you may know? |
| 04-15-2009, 11:40 AM | #2 |
Cos / Sin use angle instead of position and do in expire: JASS:local Data d = GetTimerData( t ) local real x = GetUnitX( d.caster ) local real y = GetUnitY( d.caster ) local real tx local real ty set d.angle = d.angle + VELOCITY/ (2*bj_PI*d.dist) set tx = x + d.dist * Cos( d.angle ) set ty = y + d.dist * Sin( d.angle ) Or you can use constant angle increase, instead of based off of radius... If you want it done by velocity,acceleration, acceleration is always perpendicular to velocity towards center of circle |
| 04-15-2009, 11:47 AM | #3 | |
what you mean with "attack in circular fashion" ? Quote:
|
| 04-15-2009, 03:27 PM | #4 |
By circular fashion I mean that a unit must "always" be moving in a circle. When it has no orders, instead of being in the same place without moving, it should perform a circle. When moving it should make half-circles, like a drunken plane moving =P I made some code that works, see the example please. I am open for ideas on how to improve: JASS:scope IntSummon initializer Init globals private constant integer SUMMON_ID = 'hphx' private constant real VELOCITY = 600. private constant real CICLE_TIMER = 0.02 private constant real RANGE = 800 endglobals //=========================================================================== private struct aSummon unit caster unit summon timer t real face real summonX real summonY real newX real newY real newface static method summonLoop takes nothing returns nothing local aSummon data = aSummon(GetTimerData(GetExpiredTimer())) //if the unit has no order, than it is stoped and we force it to make //circles //if GetCurrentOrder == DoNothing then //update the current position of the summon set data.face = GetUnitFacing(data.summon) set data.summonX = data.summonX + ( (VELOCITY * CICLE_TIMER) * Cos(data.face * bj_DEGTORAD) ) set data.summonY = data.summonY + ( (VELOCITY * CICLE_TIMER) * Sin(data.face * bj_DEGTORAD) ) //move the bird =P call SetUnitX(data.summon, data.summonX) call SetUnitY(data.summon, data.summonY) //Choose new position for summon to walk next time set data.newX = GetUnitX(data.caster) + ( ( GetRandomReal(0, RANGE) * CICLE_TIMER) * Cos( 360 * bj_DEGTORAD) ) set data.newY = GetUnitY(data.caster) + ( ( GetRandomReal(0, RANGE) * CICLE_TIMER) * Sin( 360 * bj_DEGTORAD) ) set data.newface = bj_RADTODEG * Atan2(data.newY - GetUnitY(data.summon), data.newX - GetUnitX(data.summon)) call SetUnitFacing(data.summon, data.newface) //elseif GetCurrentOrder == MoveToSomePoint //here I make the unit move to that point, but making semi-circles //elseif GetCurrentOrder == Attack //here I make the unit move to that point, but making semi-circles //when the unit reaches the target we attack it //after the attack we repeat last steps //end endmethod static method create takes unit c, unit s returns aSummon local aSummon data = aSummon.allocate() //setting members set data.caster = c set data.summon = s set data.face = GetUnitFacing(c) set data.summonX = GetUnitX(s) set data.summonY = GetUnitY(s) //the movement timer set data.t = NewTimer() call SetTimerData(data.t, integer(data)) call TimerStart(data.t, CICLE_TIMER, true, function aSummon.summonLoop) return data endmethod method onDestroy takes nothing returns nothing call ReleaseTimer(.t) endmethod endstruct //=========================================================================== private function Conditions takes nothing returns boolean local aSummon data if GetUnitTypeId(GetSummonedUnit()) == SUMMON_ID then set data = aSummon.create(GetSummoningUnit(), GetSummonedUnit()) endif return false endfunction //=========================================================================== private function Init takes nothing returns nothing //when the Unit is summoned local trigger IntSummonTrg = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(IntSummonTrg, EVENT_PLAYER_UNIT_SUMMON) call TriggerAddCondition(IntSummonTrg, Condition(function Conditions)) endfunction endscope |
| 04-15-2009, 06:35 PM | #5 |
That kind of thing would take a lot of code and depends heavily on how exactly you want it to behave. Nobody can really write this for you. |
| 04-15-2009, 08:56 PM | #6 | |
Quote:
Is it at least possible to get some formula for the "drunken" summon movement? |
| 04-15-2009, 09:12 PM | #7 |
you didnt specify how you image that drunken movement .. half circles can be everything ...best thing would probably be when you just draw a picture of your thoughts... |
| 04-16-2009, 01:50 AM | #9 |
Didn't Vexorian make a curve like that (Sine curve or something? i dont know) for Stromy Dreams in xe? Don't know if that's the thing you're looking for, but. |
| 04-16-2009, 01:59 AM | #10 | |
Quote:
|
| 04-16-2009, 02:10 AM | #11 | |
Quote:
|
| 04-16-2009, 02:28 AM | #12 |
Zomg! Instead of trying to find a single formula, you could always try this simple (but slow) method: -Pick a radius for all of the semicircles you want the unit to form. -Find the angle between your starting point and your ending point. -Make a point, 200 away from your unit, at the angle you just found. We can call this P. -Rotate your unit around P, for 180 degrees. -Once you rotate it 180 degrees, start the process again, but this time rotate -180 degrees. Behold: A shitty MS paint drawing! ![]() |
| 04-16-2009, 02:38 AM | #13 |
You could use a simple Sin curve :o OT Edit: You be on skype tonight Dil? |
| 04-16-2009, 03:21 AM | #14 |
I'd add circular motion on top of linear motion, like a moon orbiting a (relatively) unbound planet. |
| 04-16-2009, 03:25 AM | #15 | |
Quote:
|
