HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Labeling or naming groups? + some math

01-06-2009, 08:03 PM#1
bowzerbro
Hey, I'm currently trying to learn JASS and am currently playing around with custom functions to learn how they work.
I'm trying to make a function which creates units, groups them and uses the name entered in a chat string to name the group so it can be used to kill the group.
Eg. -Mut 99,killers (creates 99 units at some point on map with the group name killers)
-Kut killers (kills all units in group "killers" and removes the group)

Even though my main concert in this topic is mainly group labels or a good method of indexing, I've also added the reason for why I'd like such a function.

I've attempted to convert part of Golem Invocation and Forest Call by Flame_Phoenix, to create units in a circle. I'm not entirely sure how to determine unit collision size let along the calculation for calculating the angle differences to make sure the units created do not collide and always create a full circle no matter the circle radius(adaptive spacing between units depending on circle size). :|

Attempting to get the above result(just moved units in position by orders), however if I were to enter 99 the number of unit circles would increase to fit the number of units. Also the first circle would start earlier from the center of the position chosen and without a unit in the middle. (the red and green lines are just markers added with mspaint :p)

I've yet to experiment more with the code I've attempted to use from the spell. Will test it with set group and such for now.
Any help would be appreciated. I've got to go for the day, I'll be back tomorrow. Sorry about that though I've got to work tomorrow, so good night~
(forgot to paste code :p, even though it is horrible atm)
Functions:
Collapse JASS:
//Early tutorial custom function
function DisplayAMessage takes string message returns nothing
    call BJDebugMsg(message)
endfunction
//BJDebugMsg() is shorter :p will change to M() or something later for easier use.

function MakeUnits2 takes integer a, string b returns nothing
//99% of code by Flame_Phoenix
        local unit u
        // innerRadius   -> The radius of the innermost circle
        // outerRadius   -> The radius of the outmost circle
        local real innerRadius = 80
        local real outerRadius = 80+I2R(a)*10
        // x and y       -> Center of circles
        local real x = GetCameraTargetPositionX()
        local real y = GetCameraTargetPositionY()
        local real radiusInc = (outerRadius - innerRadius) / I2R(6)
        local real phi = 0
        local real phiInc
        local group g = CreateGroup()
        //This code is not complete, I am trying to use string b to name the group g
       loop
            exitwhen (innerRadius + 0.001 >= outerRadius)

            set phi = 0
            set phiInc = 2*bj_PI/I2R(a)
            
            loop
                exitwhen (phi + 0.001 >= 2 * bj_PI)
                //we add the units to a group, so we can kill them when we want ! =P
                call GroupAddUnit(g, CreateUnit(GetTriggerPlayer(), 'hfoo', x + innerRadius * Cos(phi), y + innerRadius * Sin(phi), 180 + Rad2Deg(phi)))
                call DisplayAMessage("Attempted to create unit "+I2S(a))
                set phi = phi + phiInc
            endloop
            
            set innerRadius = innerRadius + radiusInc
        
        endloop
        set u = null
endfunction
//My first attempt to make units in a circle is horrible.
//It made squares ... :p Code probably didn't work...
function MakeUnits takes integer a returns nothing
 local group unt
 local integer L = 0
 local real m = 0
 local real ar = 0
 local real o = 80
 local location loc = GetRandomLocInRect(GetPlayableMapRect())
 local location uni = loc
 local unit u
  loop
   exitwhen L > a
   set ar = m*(360/31)
   if ar > 360. then
    set o = o + 80
    set m = 0.
    else
    set uni = PolarProjectionBJ(loc, o, ar)
    set m = m + 1.
   endif
   set L = L+1
  endloop
  set loc = null
  set uni = null
  set u = null
endfunction

//Bellow is the function I've got called to use to determine how many units and such.
//It has flaws and probably needs a rewrite later on, though it is only for test purpose atm.
unction Trig_MyFunction_Actions takes nothing returns nothing
 local string tst = SubString(GetEventPlayerChatString(),1,3)
 local string nfo = SubString(GetEventPlayerChatString(),5,StringLength(GetEventPlayerChatString())-5)
 local string grp
 local string amt
 if tst == "Kut" then
  call DisplayAMessage("-Kut has been typed")
  call DisplayAMessage("Units in group "+grp+" will be killed!")
  if SubString(nfo,1,1) == "," then
   set grp = SubString(nfo,2,StringLength(nfo)-1)
   set amt = SubString(nfo,0,0)
   elseif SubString(nfo,2,2) == "," then
   set grp = SubString(nfo,3,StringLength(nfo)-2)
   set amt = SubString(nfo,0,1)
  endif
 endif
 if tst == "Mut" then
 //-Mut is letters 0 to 4 where the last space is letter 4.
 //xx are letters 5 to 6 where the first letter is x and the last is 6
 //, can be 7,8 or 8,9.
  call DisplayAMessage("Units created will be in group "+grp)
 if SubString(nfo,1,1) == "," then
  set grp = SubString(nfo,2,StringLength(nfo)-1)
  set amt = SubString(nfo,0,0)
  elseif SubString(nfo,2,2) == "," then
  set grp = SubString(nfo,3,StringLength(nfo)-2)
  set amt = SubString(nfo,0,1)
 endif
 call DisplayAMessage(SubString(GetEventPlayerChatString(),5,6) + " was then declared after.")
  //call DisplayTextToPlayer(Player(GetPlayerId(GetTriggerPlayer())),0,0,GetEventPlayerChatString())
  if S2I(SubString(GetEventPlayerChatString(),5,7)) > 0 and SubString(grp,0,0) != "," and tst == "Mut" then
  call MakeUnits2(S2I(amt),grp)
  elseif tst == "Kut" and SubString(grp,0,0) != "," then
  call KillUnits("ugd_" + grp)
  else
  call DisplayAMessage("Too little units or other error!")
  endif
 endif
 set tst = null
 set grp = null
 set nfo = null
endfunction

//I'm hoping I did not miss anything.
Here's some credits to:
Flame_Phoenix - for the Golem Invocation code hopefully not minding me snipping pieces from it :p


~bowzerbro
01-06-2009, 09:54 PM#2
Archmage Owenalacaster
  • You should use DisplayTimedTextToPlayer(Player(0),0,0,60,msg). It is a native, so that's one function call compared to 18 calls: your function + BJDebugMsg + 16 DisplayTimedTextToPlayer. If you insist on something a little quicker to type, have it call the native.
  • Not sure why you'd want a random map location, but calling this function is less messy and safer. Just input a buffer value to keep the units you're creating away from the edge.
    Collapse JASS:
        private function RandMapLoc takes integer buffer returns location
            return Location(GetRandomReal(GetRectMinX(bj_mapInitialPlayableArea)+buffer, GetRectMaxX(bj_mapInitialPlayableArea)-buffer), GetRandomReal(GetRectMinY(bj_mapInitialPlayableArea)+buffer, GetRectMaxY(bj_mapInitialPlayableArea)-buffer))
        endfunction
  • Your code leaks. You only nulled the variables, but didn't remove the location or destroy the group. You could store a string and a group in a struct, especially since you don't seem to do anything with the group right now. If you intend to make this multi-instancable, use Vexorian's Table system.

EDIT: Fixed two stupid typos.
01-06-2009, 11:58 PM#3
Zerzax
Making units in a circle is best accomplished (at least most easily, I find) through the use of trigonometric functions in order to project coordinates from some source point. The angular offset of each unit can be determined by dividing 360 degrees or 2 pi radians by the number of units you require in the circle. Collision size generally ranges from 16 to 32 I think, and you'll be able to detect whether collision will actually kick in by calculating the radius of the circle and dividing that by the number of units.
01-07-2009, 12:14 AM#4
Pyrogasm
Okay, well here's some math for you. Given that you know most everything about your situation (radii, collision sizes, number of units), finding the one remaining thing, the AngleIncrement, is actually pretty easy. The basic math here is AngleIncrement = 6.28318/<Number of Units>, and then you do this:
Collapse JASS:
local integer N = <whatever>
local real AngleIncrement = 6.28318/N
local integer I = 0

loop
    set X = CenterX+Radius*Cos(AngleIncrement*I)
    set Y = CenterY+Radius*Sin(AngleIncrement*I)
    call CreateUnit(Player(15), 'hfoo', X, Y, AngleIncrement*I*57.2958) //Because unit facing is in degrees, not radians

    set I = I+1
    exitwhen I >= N
endloop
Now say you have a circle of radius R[0] (and subsequent radiuses of R[1], R[2], R[3], etc.) that you want to fill up with N units, each with a collision size of C. It's pretty easy to come up with a formula. What you're going to do is find the max number of units that can fit in the circle, like so:
Collapse JASS:
local integer Max = R2I(R0/(C*2.00)) //multiplied by two because collision size is a radius, is it not?
Now, you must compute AngleIncrement as:
Collapse JASS:
local integer AngleIncrement = 6.28318/Max
And again you have this:
Collapse JASS:
local integer Max = R2I(R[0]/(C*2.00))
local real AngleIncrement = 6.28318/Max
local integer I = 0

loop
    set X = CenterX+R[0]*Cos(AngleIncrement*I)
    set Y = CenterY+R[0]*Sin(AngleIncrement*I)
    call CreateUnit(Player(15), 'hfoo', X, Y, AngleIncrement*I*57.2958)

    set I = I+1
    exitwhen I >= Max
endloop
But since this only makes one circle, and you want to fill up multiple circles until 99 units have been placed, then we need to add a loop in. In this loop, we'll decrease some counter variable that states how many more units need to be placed, and once it is small enough we will exit the loop:
Collapse JASS:
local integer Count = 99
local integer J = 0

loop
    set Count = Count-Max
    if Count <= 0 then
        exitwhen true
    else
        set J = J+1
    endif
endloop

Collapse JASS:
local integer Count = 99
local integer J = 0
local integer Max
local real AngleIncrement
local integer I

loop
    set I = 0
    set Max = R2I(R[J]/(C*2.00))
    set AngleIncrement = 6.28318/Max

    loop
        set X = CenterX+R[J]*Cos(AngleIncrement*I)
        set Y = CenterY+R[J]*Sin(AngleIncrement*I)
        call CreateUnit(Player(15), 'hfoo', X, Y, Angle*57.2958)

        set I = I+1
        exitwhen I >= Max
    endloop

    set Count = Count-Max
    if Count <= 0 then
        exitwhen true
    else
        set J = J+1
    endif
endloop
Now, the only thing we haven't accounted for is what if Max is less than Count? We'll be making room for units that we won't create, so we need to check and then modify AngleIncrement and Max accordingly:
Collapse JASS:
local integer Count = 99
local integer J = 0

loop
    set Count = Count-Max
    if Count <= 0 then
        exitwhen true
    else
        set J = J+1
    endif
endloop

Collapse JASS:
local integer Count = 99
local integer J = 0
local integer Max
local real AngleIncrement
local integer I

loop
    set I = 0
    set Max = R2I(R[J]/(C*2.00))
    if Max > Count then
        set Max = Count
    endif
    set AngleIncrement = 6.28318/Max

    loop
        set X = CenterX+R[J]*Cos(AngleIncrement*I)
        set Y = CenterY+R[J]*Sin(AngleIncrement*I)
        call CreateUnit(Player(15), 'hfoo', X, Y, Angle*57.2958)

        set I = I+1
        exitwhen I >= Max
    endloop

    set Count = Count-Max
    if Count <= 0 then
        exitwhen true
    else
        set J = J+1
    endif
endloop

As long as you can supply R[0], R[1]...R[N] and the collision size of the units being created (which can be found with GetUnitCollisionSize()), then this should work.
01-07-2009, 12:28 AM#5
Ammorth
As for the labelling, look into gamecache.

If you are using vJass, a combination of structs and Table (specifically the StringTable class), you can store the unit group based on a string.

Collapse JASS:
globals
    private StringTable string2group = null
endglobals

struct UnitGroupStruct
    group g
    string label

    static method create takes unitgroup g, string label returns UnitGroupStruct
        local UnitGroupStruct this = UnitGroupStruct.allocate()
        set this.g = g
        set this.label = label
        set string2group[label] = this // sets reference
        return this
    endmethod
    
    method onDestroy takes nothing returns nothing
        set string2group[this.label] = 0 // clears reference
        if this.g != null then
            call DestroyGroup(this.g)
            set this.g = null
        endif
    endmethod

    static method GetGroupFromString takes string s returns UnitGroupStruct
        return string2group[s]
    endmethod
endstruct

function DemoInit takes nothing returns nothing // call this function first
    set string2group = StringTable.create() // allocates a table to use
endfunction

// Then you can use:
UnitGroupStruct.create(group, label) // to create a unitgroup reference
set someUnitGroupStructVar = UnitGroupStruct.GetGroupFromString(label) // to get back the struct
someUnitGroupStructVar.g // to access the group, and
someUnitGroupStructVar.destroy() // to remove everything when done.

I would recommend learning vJass as you learn Jass since it is much easier to code in and provides much more flexibility.
01-07-2009, 06:45 PM#6
bowzerbro
Quote:
Originally Posted by Archmage Owenalacaster
Not sure why you'd want a random map location
That's only temporary.

Quote:
Originally Posted by Archmage Owenalacaster
Your code leaks. You only nulled the variables, but didn't remove the location or destroy the group. You could store a string and a group in a struct, especially since you don't seem to do anything with the group right now. If you intend to make this multi-instancable, use Vexorian's Table system.
Tried to implement the table system though don't know how to, I've implemented two systems by cohadar but haven't bothered to use either of them.
Thanks for your reply.

Quote:
Originally Posted by Zerzax
Making units in a circle is best accomplished (at least most easily, I find) through the use of trigonometric functions in order to project coordinates from some source point. The angular offset of each unit can be determined by dividing 360 degrees or 2 pi radians by the number of units you require in the circle. Collision size generally ranges from 16 to 32 I think, and you'll be able to detect whether collision will actually kick in by calculating the radius of the circle and dividing that by the number of
I've tried using the angular offset thing first but am not sure how to calculate the space between units and how to calculate the amount of units that fit in a circle when the distance from center increases.
I ended up with squares, indicating that they just spawned where they were able to ;p

Pyrogasm: Thank you. I can understand most of the code but am not good at calculations. I used to know those things but I've never had any use for math over like +,-,* and / :p eh.. I suppose I meant, radius calculations and such. I hope I revive some knowledge throughout my jassing :)

Ammorth: Good, clean and understandable reply.(not that other ones were but I thought since the system is so clean it made the code cleaner thus making reply shorter and .. yeah) Just need to implement system :) Thanks. I've got PUI on the test map but not using :p My comp is quite slow and I read it would be faster and that all systems can be used with it(if converted). I'll not bother trying to use it yet ;p But the table function is one I need to learn how to implement because I'll need to use Unit Properties on my main map.

Thanks to all for your replies
~bowzerbro, will attempt to make circles of units soon!

{ Add: Holy pasta in random shapes, I clicked submit but it never posted. I've been cleaning and stuff and will soon go to sleep. Not gotten any time to test spawning units :| }
01-11-2009, 06:01 PM#7
bowzerbro
Getting a few problems with unit group label sys.
PJASS
16 compile errors [not listed all]
Cannot convert null to integer
* integer UnitGroupLabel__string2group= null
Undefined type unitgroup
* unitgroup f__arg_unitgroup1
* function sc__UnitGroupStruct_create takes unitgroup g,string label returns integer
Undeclared variable string2group
* set string2group = s__StringTable__allocate() // allocates a table to use

I've got quite a few other errors but those are because I'm not sure how to use various functions yet and haven't specified various values.

Pyrogasm: Will I have to pre-set all the R[#] radius values? Table converts a var set as R[#] to R0,R1 etc? Or do I use R[0] again to get the value in R[0]? :o I'm slightly confused due to all I've read in various topics.
1. I've read that arrays are slow.
2. I've read that gamecache sucks due to many bugs as well as being slower than available alternatives.
3. Missed or unable to find clear explanations on how to implement things. Such as knowing where to put the code if I'm not told where to, which order to place triggers with functions so they work together correctly. When to put scopes, where to put the scopes (order), which order to init new functions and so on.

Syntax Check can not be trusted? It gives me a large variety of error reports such as saying that there is no function named GetUnitCollisionSize. I made a trigger named GetUnitCollisionSize and made it run on map init. Though didn't name it Init_GetUnitCollisionSize.

I'm sorry, I find learning things on forums quite hard. I've made a lot of macros and scripted a lot of things for various programs. I've never really in any mayor code-language but I've read snips of quite a few languages and I've not had problems seeing how the structure worked.
However I think JASS is harder due to mixing of languages, lack of proper error descriptions and not as powerful as some scripting languages even. :p
I'm a bit frustrated due to lack of time to spend on trying to learn something, finding it harder to learn this than anything I've got myself into and every break rusts the progress so I'll have to spend some time to remember where I was.
I'm not sure who said it but someone said "it only takes one day to learn jass", I assume that's if you had all links, knew where to start and there were simple yet understandable enough explanations for everything, had that whole days time to spend and didn't end up confusing yourself by digging too deep too early. :p I need a fresh start..

The bellow is nowhere close to complete. I'm lost in all the functions atm, quite tired. There are many values and probably some functions and such not stated. And I'm sure there's a lot not yet changed to code.
Collapse JASS:
//Get Radius to use
function GetR takes real in, real dif returns real
 // The value in is unitcollisionsize. dif is the difference between circles.
 // And value out is the radius increase to use.
 local integer ucs
 return ucs+dif //collisionsize + distance between circles.
endfunction

function GetColSize takes integer unt returns real
 local unit u
 set u=Unit.create(CreateUnit(Player(12), unt, 0, 0, 0))
 return GetUnitCollisionSize(u)
 call u.destroy()
endfunction

function MakeUnits3 takes integer a, string grp, real ux, real uy, integer unt returns nothing
local real X = ux
local real Y = uy
local integer Count = a
local integer J = 0
local integer Max
local real AngleIncrement
local integer I
local group ug = CreateGroup()
call DemoInit()
call GetColSize(unt)
set ug = UnitGroupStruct.create(ug, grp)
loop
    set I = 0
    set Max = R2I(R[J]/(C*2.00))
    if Max > Count then
        set Max = Count
    endif
    set AngleIncrement = 6.28318/Max

    loop
        set X = ux+R[J]*Cos(AngleIncrement*I)
        set Y = uy+R[J]*Sin(AngleIncrement*I)
        call GroupAddUnit(ug, CreateUnit(Player(0), 'hfoo', X, Y, Angle*57.2958)) //Was Angle a typo or unit facing, what if unit faces 0 :p? It isn't specified anywhere :X
        set I = I+1
        exitwhen I >= Max
    endloop

    set Count = Count-Max
    if Count <= 0 then
        exitwhen true
    else
        set J = J+1
    endif
    set ug=null
endloop
endfunction
Sorry I can't find the energy to finish this at the moment. I'll go back to simpler stuff for now though not today. I need smaller things to work on to learn how to use table, vJASS and such. There's so many systems and so much code mixed together and since I'm not sure where I am any more it's all a big pile of rubble in my head atm. I'm sorry I didn't include all my code, it's a big mess. I could upload whole map though I doubt anyone would wanna go through it. ;p
~yawn~ I hope this post made some sense since right now I'm not feeling fit to code. I'm probably just going through the phrase before you go "OH! Now it all makes sense!".. :p
01-12-2009, 06:51 AM#8
Pyrogasm
When you get bogus errors it's because you've forgotten something silly like an endif or endfunction or something and the parser just has a field day on that and gives all sorts of errors to hell and back.

If you have AIM, MSN, YIM, ICQ, or Gtalk, get my contact info from my profile and send me a message. I'm online nearly all the time (though idle for a fair amount while I'm at school), and I certainly don't have a problem talking with you in real time if that helps you learn.

Anyway, regarding your script...:
Collapse JASS:
//Get Radius to use
function GetR takes real in, real dif returns real
 // The value in is unitcollisionsize. dif is the difference between circles.
 // And value out is the radius increase to use.
 local integer ucs
 return ucs+dif //collisionsize + distance between circles.
endfunction
Well, the radius really shouldn't depend on the unit collision size at all, should it? If you know the distance between the circles and which number circle you're on, then you know the radius of each consecutive circle. So let's turn this into a formula:
Collapse JASS:
function GetR takes real Previous, real UCS returns real
    local real Modifier = 35.00
    if Modifier < UCS then
        return Previous+UCS
    endif
    return Previous+Modifier
endfunction
That takes the previous radius as an argument and finds the new radius. It also has a check in there to make sure that the new radius is at least the current radius + the unit's collision size. When I wrote R[0], R[1], etc., I was just having a way of representing the next radius. Nothing said it had to be an array, but that was how I was representing it to show that it was a set of values.

Collapse JASS:
function GetColSize takes integer unt returns real
 local unit u
 set u=Unit.create(CreateUnit(Player(12), unt, 0, 0, 0))
 return GetUnitCollisionSize(u)
 call u.destroy()
endfunction
Now this function is really screwed up. You sort-of combined normal JASS and some vJASS syntax that makes no sense xD. The <Type>.create(...) syntax is only used for custom types created through vJASS. For normal types (unit, item, destructable, lightening, etc.) there are functions used to create them. In this case, we'll use CreateUnit(...). When dealing with reals and integers, always make the distinction (if it's a real, write 0.00 or 0. instead of just 0); failing to do so can cause Mac users to crash when your code is executed.

Something it looks like you don't understand is that in JASS, everything after a return stops. After you return a value (or you can just return with no value), the next lines of code are never executed. Here, the unit will never be removed (you put .destroy() when it should be RemoveUnit(u)]) because there is a return before it:
Collapse JASS:
function GetColSize takes integer unt returns real
 local unit u=CreateUnit(Player(12), unt, 0.00, 0.00, 0.00))
 local real c = GetUnitCollisionSize(u)
 call RemoveUnit(u)
 return c
endfunction

As for the rest, I think it might be best to start over entirely whilst writing all the code yourself. It's a bit of a mess because you combined my code and yours and you have a lot of extra fluff/nonsensical stuff. Also, I don't have time to go over that part right now, but perhaps in the near future I will. Contact me online if you'd like, I'm GMT -8:00.
01-12-2009, 09:04 PM#9
bowzerbro
Quote:
Originally Posted by Pyrogasm
When you get bogus errors it's because you've forgotten something silly like an endif or endfunction or something and the parser just has a field day on that and gives all sorts of errors to hell and back.

If you have AIM, MSN, YIM, ICQ, or Gtalk, get my contact info from my profile and send me a message. I'm online nearly all the time (though idle for a fair amount while I'm at school), and I certainly don't have a problem talking with you in real time if that helps you learn.

Anyway, regarding your script...:
Collapse JASS:
//Get Radius to use
function GetR takes real in, real dif returns real
 // The value in is unitcollisionsize. dif is the difference between circles.
 // And value out is the radius increase to use.
 local integer ucs
 return ucs+dif //collisionsize + distance between circles.
endfunction
Well, the radius really shouldn't depend on the unit collision size at all, should it? If you know the distance between the circles and which number circle you're on, then you know the radius of each consecutive circle. So let's turn this into a formula:
Collapse JASS:
function GetR takes real Previous, real UCS returns real
    local real Modifier = 35.00
    if Modifier < UCS then
        return Previous+UCS
    endif
    return Previous+Modifier
endfunction
That takes the previous radius as an argument and finds the new radius. It also has a check in there to make sure that the new radius is at least the current radius + the unit's collision size. When I wrote R[0], R[1], etc., I was just having a way of representing the next radius. Nothing said it had to be an array, but that was how I was representing it to show that it was a set of values.

Collapse JASS:
function GetColSize takes integer unt returns real
 local unit u
 set u=Unit.create(CreateUnit(Player(12), unt, 0, 0, 0))
 return GetUnitCollisionSize(u)
 call u.destroy()
endfunction
Now this function is really screwed up. You sort-of combined normal JASS and some vJASS syntax that makes no sense xD. The <Type>.create(...) syntax is only used for custom types created through vJASS. For normal types (unit, item, destructable, lightening, etc.) there are functions used to create them. In this case, we'll use CreateUnit(...). When dealing with reals and integers, always make the distinction (if it's a real, write 0.00 or 0. instead of just 0); failing to do so can cause Mac users to crash when your code is executed.

Something it looks like you don't understand is that in JASS, everything after a return stops. After you return a value (or you can just return with no value), the next lines of code are never executed. Here, the unit will never be removed (you put .destroy() when it should be RemoveUnit(u)]) because there is a return before it:
Collapse JASS:
function GetColSize takes integer unt returns real
 local unit u=CreateUnit(Player(12), unt, 0.00, 0.00, 0.00))
 local real c = GetUnitCollisionSize(u)
 call RemoveUnit(u)
 return +1 
endfunction

As for the rest, I think it might be best to start over entirely whilst writing all the code yourself. It's a bit of a mess because you combined my code and yours and you have a lot of extra fluff/nonsensical stuff. Also, I don't have time to go over that part right now, but perhaps in the near future I will. Contact me online if you'd like, I'm GMT -8:00.
Ah, ;p I wish I was uber at vJASS so I could write a mirc-style documentation help-file. mirc script was the easiest script lang to learn before actool script, then something for a bot-program which had fairly understandable lang. A mix of C and scripting. I love "case x <do actions>" since it's so much easier to understand. ;| I want case function in JASS.
Anyway, I suppose we may be able to speak on.. hmm darn. Maybe next weekend or if I'm ever home early or something. I am GTM so quite hard to find time :p
Thanks for reply, now I'm off to bed. Will attempt waking up at 5 am to get to work early :p ... May end up waiting liek an hour for trains in denmark to start going :p hehe.
Good night
~bowzerbro
Bellow would never work :p
Collapse JASS:
if not GetPlayerEnteredChat() == "" then
 case "Help"
 call CustomAIAssistFunction(GetTriggerPlayer())
 case "Attack!"
 call CustumAIAttackFunction(GetTriggerPlayer())
 case "Retreat!"
 call CustomAIRetreatFunction(GetTriggerPlayer())
 case "Hold position"
 call CustomAIHaltFunction(GetTriggerPlayer())
 case "Deffend position"
 call CustomAIDeffendPosFunction(GetTriggerPlayer())
 case "Fight among each other!"
 call CustomAIChaosFunction(GetTriggerPlayer())
 case "Archers target "
 call CaseSub(GetSubString(GetPlayerEnteredChat(),16,StringLength(<entered string>-16)))
else
 call CalledUnitSay("Now, there isn't any such command! Type -AIHelp for a list of squad commands.")
endif
Collapse JASS:
function CaseSub takes string x returns nothing
if not x == ""
case "weakest"
 call CustomAIAAWeakFunc(GetTriggerPlayer())
case "strongest"
 call CustomAIAAStrongFunc(GetTriggerPlayer())
case "structures"
 call CustomAIAAStrucFunc(GetTriggerPlayer())
case "hero"
 call CustomAIAAHeroFunc(GetTriggerPlayer())
else
 call CalledUnitSay("Huh? What master?") //Would make archer squad leader say "<this>"
endif
endfunction
yeah.. quite flawerd. believe there'd be need for endcase or such :p just an example. Nite! :)
01-12-2009, 11:54 PM#10
Pyrogasm
What you're looking for is elseif.
Collapse JASS:
local string s = GetEventPlayerChatString()
if s == "" then
   call CalledUnitSay("Now, there isn't any such command! Type -AIHelp for a list of squad commands.")
elseif s == "Help"
   call CustomAIAssistFunction(GetTriggerPlayer())
elseif s == "Attack!"
   call CustumAIAttackFunction(GetTriggerPlayer())
elseif s == "Retreat!"
   call CustomAIRetreatFunction(GetTriggerPlayer())
elseif s == "Hold position"
   call CustomAIHaltFunction(GetTriggerPlayer())
elseif s == "Deffend position"
   call CustomAIDeffendPosFunction(GetTriggerPlayer())
elseif s == "Fight among each other!"
   call CustomAIChaosFunction(GetTriggerPlayer())
elseif s == "Archers target "
   call CaseSub(GetSubString(GetPlayerEnteredChat(),16,StringLength(<entered string>-16)))
endif
And similarly for the other one. In JASS an "if" is executed. If true then it runs the actions after the if and before any other elseif or else, then skips to the end of the block. An elseif is essentially a second (or third, fourth, etc.) check after the first if, and if the elseif is true, then it runs those actions then exits.
01-13-2009, 04:50 PM#11
bowzerbro
Quote:
Originally Posted by Pyrogasm
What you're looking for is elseif.
Collapse JASS:
local string s = GetEventPlayerChatString()
if s == "" then
   call CalledUnitSay("Now, there isn't any such command! Type -AIHelp for a list of squad commands.")
elseif s == "Help"
   call CustomAIAssistFunction(GetTriggerPlayer())
elseif s == "Attack!"
   call CustumAIAttackFunction(GetTriggerPlayer())
elseif s == "Retreat!"
   call CustomAIRetreatFunction(GetTriggerPlayer())
elseif s == "Hold position"
   call CustomAIHaltFunction(GetTriggerPlayer())
elseif s == "Deffend position"
   call CustomAIDeffendPosFunction(GetTriggerPlayer())
elseif s == "Fight among each other!"
   call CustomAIChaosFunction(GetTriggerPlayer())
elseif s == "Archers target "
   call CaseSub(GetSubString(GetPlayerEnteredChat(),16,StringLength(<entered string>-16)))
endif
And similarly for the other one. In JASS an "if" is executed. If true then it runs the actions after the if and before any other elseif or else, then skips to the end of the block. An elseif is essentially a second (or third, fourth, etc.) check after the first if, and if the elseif is true, then it runs those actions then exits.
similar enough :p just not as clean since the reappearing s == "<var>" confuses slightly. Would probably be possible to make functions to simulate it making long if-trees prettier. Something like if Case(s,i,l) == true then //where s is string to compare, i is what case to compare to and l is what case-list to use. if true then call DoCase(i,l) or so :p However this would make access to what is done less comfortable so just having commands after the then is probably better. This is probably slower so.. suppose one will just have to get used ;p
Repeated patterns can be easier and harder to find bugs in depending on size.
Will continue trying to figure out a few things about how unit identification works.
I'm stuck in an example map trying to make a unit respawn if it dies. I've tried so many combinations and none has worked.
Collapse JASS:
return IsUnitIdType( 'nrwm', ConvertUnitType(GetUnitTypeId(GetTriggerUnit())) ) == true
doesn't work when the 'nrwm' dies, I've tried about 10 to 15 various ways to convert and compare the type though doesn't seem to be any proper method besides imitating the one used by gui triggers :| Which I do not want to, the tutorial where I am attempting to do this in is made for learning how to convert triggers into JASS/vJASS(I've got a hard time knowing what is vJASS and what isn't) from GUI->JASS conversion.
I want a function that auto-chooses the right conversion method to use :| Probably not possible since functions has to take <vartype> <var> and can't just take <var> then do if comparing to get <vartype>, eg.
Collapse JASS:
//THIS IS THEORETICAL JASS!!!
call IsUnitAuto('nrwm',DeadUnit())
function IsUnitAuto takes 1,2 returns boolean
if GetType(1) == unit then
 if GetType(2) == unit then
  IsUnitType(1,2) == true
 endif
elseif GetType(1) == unittype then
//And so on, probably using some other method which is cleaner.
endfunction
Now I'll attempt a few things to get this the respawn-function to work. Later
01-13-2009, 05:31 PM#12
Anitarf
Can't you just do return IsUnitTypeId(GetTriggerUnit())=='nrwm'
01-14-2009, 06:57 PM#13
bowzerbro
Note: This ended up being quite diff from intended. (topic that is) However, note that one can see the entire post progress in here as my road towards being able to use label system? ;p ..
Quote:
Originally Posted by Anitarf
Can't you just do return IsUnitTypeId(GetTriggerUnit())=='nrwm'
I thought unittypeid was different from unitid :p the descriptions in both JassCraft and NewGen WE states unittypeid and nothing converts unit into unitid. Got confused
I'm not sure I may be using that now :p I got it working somehow. I believe I converted into strings and then used the strings. Even though another map has the exact string it doesn't work for that mob for some reason.
Anyway, I'm trying to make mobs respawn as higher level when hero is higher than them but doesn't seem to work. I can set max hp and mana :p Would have to use abilities to make them stronger.

My current wacky code ::
Collapse JASS:
//there was a lot of messy code here, due to serious update it got removed

I assume I'd need to use unit properties and stuff to make them level up. Could probably use custom value and abilities and then use some calculation to make these abilities be added and lvld in a way so they do not quickly make the monsters imba :p ...
Anyway I've got like 30 min to spend before I go sleep. Getting up at 5am tomorrow and want to work to like 10 pm :p So wont be here tomorrow.
Good night

Good night again.. The code above is flawed, I uploaded map instead. :)
Attached Files
File type: w3xGUI2vJASSTest.w3x (14.3 KB)