| 10-30-2009, 11:42 PM | #1 |
Ok, so I'm trying to make a system which will work like the "Locust Swarm" ability, meaning that some creatures will come out of the caster, and "circulate" him within a specific range... (By "circulate" I mean they will move around randomly until they spot an enemy etc... You know how I mean ;)) So, this is what I have atm: JASS:library EntityCol requires AutoIndex globals private constant integer MAX_ENTITIES = 20 endglobals /*struct Entity unit Entity unit Owner static method create takes unit owner, integer amount, real x, real y, integer unitId returns Entity local Entity a = Entity.allocate() local player p = GetOwningPlayer( owner ) set a.Owner = owner set a.Entity = CreateUnit( p, unitId, x, y, bj_UNIT_FACING ) return a endmethod endstruct*/ struct EntityCollection// extends Entity //group Entities = CreateGroup() unit array Entity [ MAX_ENTITIES ] unit Caster integer array ID [ MAX_ENTITIES ] static method create takes unit caster, integer number, integer unitId, real radius returns thistype local real x = GetUnitX( caster ) local real y = GetUnitY( caster ) local thistype this = thistype.allocate(/* caster, number, x, y, unitId */) local integer loops = 1 local player p = GetOwningPlayer( caster ) local real x2 = x + GetRandomReal( x - radius, x + radius ) local real y2 = y + GetRandomReal( y - radius, y + radius ) set this.Caster = caster loop exitwhen loops >= number set Entity[ ID[ loops ]] = CreateUnit( p, unitId, x, y, bj_UNIT_FACING ) set ID[loops] = GetUnitId( caster ) call IssuePointOrder( Entity[GetUnitId( caster )], "move", x2, y2 ) //call GroupAddUnit( d.Entities, u ) endloop return this endmethod endstruct endlibrary And as you can see, I had a struct for the "Entity Collection", meaning the whole group on entities (Locusts) a unit "owns", but also a struct for each entity... I could not get this to work, because I thought i'd need to extend the EntityCollection struct, and I didn't know how that works :( I haven't yet tested what I have now, but I'd believe it wouldn't work very well... And also, as you can see by the unit arrays and integer arrays, I've tried to "link" the entities of a specific cast to their caster, but I'm very unsure if I've done it correctly :S And, I think I still need to extend EntityCollection... (Or I at least want to have a stand-alone struct for each entity so you can change their flying height and many more features for them ;)) Anyone want to help me change it so it'll work as intended ? :S (Note: I searched the forums TheHelper.net, WC3C.net and TheHiveWorkshop.com before I started working on this and I couldn't find anything like this anywhere :S If you know of a system like this, please let me know so I don't waste my time with this :D) If you need more information, or you think I've been unclear on anything please let me know and I'll fix it :D |
| 11-02-2009, 02:09 PM | #2 |
Ok, so I have rewritten this now, and it looks like this: JASS:library EntityCol requires TimerUtils globals private constant integer MAX_ENTITIES = 100 // Is what it says, the maximum amount of "entities" which will be attached to a single unit at any time ! private constant real MOVE_INTERVAL = 0.03125 // Interval of the "entities" movement... private constant real DMG_INTERVAL = 1.0 // Interval of the entities damaging... private constant integer CROW_ID = 'Arav' // "Storm Crow Form" ability's ID, for height-changing purposes... Shouldn't need changing :D private constant integer LOCUST_ID = 'Aloc' // "Locust" ability's ID... Shouldn't need changing either ;) endglobals struct Entity real angle = 0.0 // Current angle of movement for the "entity" real currentX = 0.0 // Current X position of the "entity" real currentY = 0.0 // Current Y position of the "entity" real radius = 0.0 // The range from the caster real casterX = 0.0 real casterY = 0.0 timer array t [ 2 ] unit u = null // The "entity" unit... unit c = null // The caster that all of the creatures will circulate around... static method create takes unit c, integer entityID, real height, real radius returns Entity local thistype this = thistype.allocate() local player p = GetOwningPlayer( c ) set this.currentX = GetUnitX( c ) set this.currentY = GetUnitY( c ) set this.casterX = GetUnitX( c ) set this.casterY = GetUnitY( c ) set this.t[ 0 ] = NewTimer() // Some TimerUtils magic ! ;) set this.t[ 1 ] = NewTimer() // Some TimerUtils magic ! ;) set this.c = c // The owner of this "entity" ! set this.u = CreateUnit( p, entityID, currentX, currentY, bj_UNIT_FACING ) // Creating the "entity" set this.angle = GetRandomReal( 0.0, 360.0 ) set this.radius = radius //call DisplayTextToPlayer( Player( 0 ), 0.0, 0.0, R2S( this.currentX ) ) //call DisplayTextToPlayer( Player( 0 ), 0.0, 0.0, R2S( this.currentY ) ) call UnitAddAbility( this.u, CROW_ID ) call UnitRemoveAbility( this.u, CROW_ID ) call SetUnitFlyHeight( this.u, height, 0.0 ) call UnitAddAbility( this.u, LOCUST_ID ) call SetTimerData( this.t[ 0 ], this ) // TimerUtils' magic again ! :D call TimerStart( this.t[ 0 ], MOVE_INTERVAL, true, function thistype.Move ) // Putting the TimerUtils' magic to use :P call SetTimerData( this.t[ 1 ], this ) // TimerUtils' magic again ! :D call TimerStart( this.t[ 1 ], DMG_INTERVAL, true, function thistype.Damage ) // Putting the TimerUtils' magic to use :P set p = null return this endmethod static method Move takes nothing returns nothing local timer t = GetExpiredTimer() local thistype this = GetTimerData( t ) local real x local real y local real distance set this.angle = GetRandomReal( this.angle - 30.0, this.angle + 30.0 ) set this.casterX = GetUnitX( this.c ) set this.casterY = GetUnitY( this.c ) set x = currentX + 5.0 * Cos( this.angle * ( bj_PI / 180.0 ) ) set y = currentY + 5.0 * Sin( this.angle * ( bj_PI / 180.0 ) ) set distance = SquareRoot( ( ( casterX - x ) * ( casterX - x ) ) + ( ( casterY - y ) * ( casterY - y ) ) ) //call DisplayTextToPlayer( Player( 0 ), 0.0, 0.0, R2S( distance ) ) //call DisplayTextToPlayer( Player( 0 ), 0.0, 0.0, R2S( x ) ) //call DisplayTextToPlayer( Player( 0 ), 0.0, 0.0, R2S( y ) ) if distance > this.radius then loop exitwhen distance < this.radius set this.angle = this.angle - GetRandomReal( 0.0, 360.0 ) set this.casterX = GetUnitX( this.c ) set this.casterY = GetUnitY( this.c ) set x = currentX + 5.0 * Cos( this.angle * ( bj_PI / 180.0 ) ) set y = currentY + 5.0 * Sin( this.angle * ( bj_PI / 180.0 ) ) set distance = SquareRoot( ( ( casterX - x ) * ( casterX - x ) ) + ( ( casterY - y ) * ( casterY - y ) ) ) endloop endif call SetUnitX( this.u, x ) call SetUnitY( this.u, y ) set this.currentX = x set this.currentY = y set t = null endmethod static method Damage takes nothing returns nothing local timer t = GetExpiredTimer() local thistype this = GetTimerData( t ) endmethod method onDestroy takes nothing returns nothing //some cleaning here, for example killing the unit, destroying the timer... endmethod endstruct struct EntityCollection Entity array e [ MAX_ENTITIES ] // All "entities" are here... real duration = 0. static method create takes unit caster, integer amount, integer entityID, real entityHeight, real maxRadius, real duration returns thistype local thistype this = thistype.allocate() local integer i = 1 loop exitwhen i == amount set this.e[ i ] = Entity.create( caster, entityID, entityHeight, maxRadius ) set i = i + 1 endloop //set this.duration = duration + MOVE_INTERVAL return this endmethod endstruct endlibrary And this actually works just fine, accept for a few flaws...
Anyone have any idea of how to fix these problems ? :S |
| 11-02-2009, 02:25 PM | #3 |
JASS:
if distance > this.radius then
loop
exitwhen distance < this.radius
set this.angle = this.angle - GetRandomReal( 0.0, 360.0 )
set this.casterX = GetUnitX( this.c )
set this.casterY = GetUnitY( this.c )
set x = currentX + 5.0 * Cos( this.angle * ( bj_PI / 180.0 ) )
set y = currentY + 5.0 * Sin( this.angle * ( bj_PI / 180.0 ) )
set distance = SquareRoot( ( ( casterX - x ) * ( casterX - x ) ) + ( ( casterY - y ) * ( casterY - y ) ) )
endloop
endif
Because of this, obviously. |
| 11-02-2009, 02:34 PM | #4 |
Huh ?! Is that an answer to a question ? :S |
| 11-02-2009, 02:39 PM | #5 | ||||
Quote:
Quote:
Quote:
Quote:
|
| 11-02-2009, 03:31 PM | #6 | ||
Quote:
Well, ok... Thanks for that info :P Though it didn't really help, as I still don't know how to fix it XD Quote:
Huh ?! |
| 11-02-2009, 03:33 PM | #7 | |
JASS:f distance > this.radius then loop exitwhen distance < this.radius set this.angle = this.angle - GetRandomReal( 0.0, 360.0 ) set this.casterX = GetUnitX( this.c ) set this.casterY = GetUnitY( this.c ) set x = currentX + 5.0 * Cos( this.angle * ( bj_PI / 180.0 ) ) set y = currentY + 5.0 * Sin( this.angle * ( bj_PI / 180.0 ) ) set distance = SquareRoot( ( ( casterX - x ) * ( casterX - x ) ) + ( ( casterY - y ) * ( casterY - y ) ) ) endloop endif Quote:
|
| 11-02-2009, 03:37 PM | #8 | ||
Quote:
Well, wouldn't that make it never work ? :S Or, does it only "not-finish" when the caster move ? Quote:
Using a global, or what ? |
| 11-02-2009, 04:37 PM | #9 | ||
Quote:
Quote:
|
| 11-02-2009, 07:42 PM | #10 | ||
Quote:
Why not ?! It is becoming true, as long as it doesn't move because the "entitys" will turn around when they come too far away... Sorry, but please explain a bit more :D Quote:
So normal members can't be accessed then ? They need to be static ? |
| 11-02-2009, 07:59 PM | #11 | ||
Quote:
Quote:
I still don't get what you are trying to do. |
| 11-02-2009, 08:21 PM | #12 |
You don't get what I'm trying to do with the whole script, or just with the "Single-Timer-Per-Group" stuff ? :S |
| 11-02-2009, 08:26 PM | #13 |
So, you're trying to do something like this? |
| 11-03-2009, 06:33 AM | #14 |
No... You don't know what "Locust Swarm" is ? :S You create a few creatures, which hover around you, and when enemies appear, they'll start to attack, a little at a time ;) |
| 11-03-2009, 08:23 AM | #15 |
Actually he does. What I don't understand is: What are you trying to do with this system? How should it work? What does(n't) work? |
