Unit's cell width and height?

Started by Edward, March 16, 2018, 10:25:44 AM

Previous topic - Next topic

Edward

Hello.
It has been a loooong while since I was here, or even doing stuff on Creeper World. I come back to it from time to time, and oddly enough, despite being gone a while, I can still read this Reversed Polish Language.
... To a degree, which is why I come around today, to ask for some help.

ShowTraceLog
ClearTraceLog

(CurrentX (GetUnitAttribute(self CONST_CELLWIDTH) 2 div) sub) ->x1
(CurrentY (GetUnitAttribute(self CONST_CELLHEIGHT) 2 div) sub) ->y1
(CurrentX (GetUnitAttribute(self CONST_CELLWIDTH) 2 div) add) ->x2
(CurrentY (GetUnitAttribute(self CONST_CELLHEIGHT) 2 div) add) ->y2
0 ->creep
0 ->found
<-x1 "x" <-y1 "x" <-x2 "x" <-y2 concat concat concat concat concat concat trace
<-y2 <-y1 do
<-x2 <-x1 do
I J GetCreeper 0 gt if
1 ->found
else
0 ->found
endif
<-creep I J GetCreeper add ->creep
loop
loop
<-found 0 gt if
<-y2 <-y1 do
<-x2 <-x1 do
I J 0 SetCreeper
loop
loop
CurrentCoords RandUnitCoords 1 <-creep CreateSpore
endif

So I am attempting something. When there is creeper occupying all the spaces the tower is occupying, that creeper is to be launched to a unit as a spore. But that's not happening.
Tracing the GetUnitAttribute(self CONST_CELLWIDTH), it shows as a negative number. Why? What am I doing wrong here?

/Edward

TDplay

#1
First: Make sure you use the # symbol to comment your code so you (and anyone who wants to help you) can easily tell what a piece of code does. E.g:
(CurrentX (GetUnitAttribute(self CONST_CELLWIDTH) 2 div) sub) ->x1 #Find the leftmost edge of the unit

Second: The error is being caused by your use of warp notation.
(CurrentX (GetUnitAttribute(self CONST_CELLWIDTH) 2 div) sub) ->x1
Firstly, the outside brackets are putting this in front of the last thing on the stack. Get rid of them:
CurrentX (GetUnitAttribute(self CONST_CELLWIDTH) 2 div) sub ->x1
Or stick the ->x1 in front.
Now, the interpreter will see:
Self CONST_CELLWIDTH GetUnitAttribute 2 div CurrentX sub ->x1
It thinks you want it to find (width / 2) - (X position). This will result in a negative number, unless you happen to be at the very leftmost edge of the map in which case it will return 0.
You want the interpreter to see:
CurrentX Self CONST_CELLWIDTH GetUnitAttribute 2 div sub ->x1
Which means (X position) - (width / 2).
Now in more humanly readable form, with all 4 values you are finding:
CurrentX GetUnitAttribute (Self CONST_CELLWIDTH) 2 div sub ->x1 #Find leftmost edge of unit
CurrentY GetUnitAttribute (Self CONST_CELLHEIGHT) 2 div sub ->y1 #Find top edge of unit
CurrentX GetUnitAttribute (Self CONST_CELLWIDTH) 2 div add ->x2 #Find rightmost edge of unit
CurrentY GetUnitAttribute (Self CONST_CELLHEIGHT) 2 div add ->y2 #Find bottom edge of unit


I hope this helps :)

Edward

Ok. Thank you. Not always easy to understand in which order the "reverse" is in. Now I just need to adjust the "flow". Turns out it is just spewing every frame it can.

TDplay

#3
If you put Delay in the script with the amount of frames to wait (30 frames = 1 second) it will wait for that amount of frames before the CRPLCore continues. For example, wait 1 second after each launch, therefore meaning the max spore rate is 1 spore per second:
<-found 0 gt if
<-y2 <-y1 do
<-x2 <-x1 do
I J 0 SetCreeper
loop
loop
CurrentCoords RandUnitCoords 1 <-creep CreateSpore
30 Delay #Wait for 1 second
endif

Also one issue I've noticed is your way of checking all tiles:
<-y2 <-y1 do
<-x2 <-x1 do
I J GetCreeper 0 gt if
1 ->found
else
0 ->found
endif
<-creep I J GetCreeper add ->creep
loop
loop

The value of "found" is ultimately decided by the creeper on the coords (y1, x1) as those are the last checked coords and your code between I J GetCreeper 0 gt if and endif will set the value, but you are trying to test ALL the coords right?
I would recommend something like this:
Spoiler
Start of code:
0 ->found
Inside loops:
I J GetCreeper 0 gt if
<-found 1 add ->found
endif

After the loops:
<-found 9 eq if
1 ->found
else
0 ->found
endif

so if all tiles are full (found = 9) then it sets found to 1, otherwise sets it to 0
[close]
Thought of an easier way:
Before loops:
1 ->found
Inside loops:
I J GetCreeper 0 lte if
0 ->found
endif

Karsten75

Just a heads-up that the "delay" function in CRPL is borked over saves. Known issue that won't be fixed. A number of the mapmakers here can give you more details and possible workarounds.

Edward

Thanks TDplay. I don't know why I did an else in there.
Heh, now I can't decide if I want the spore to be set off when the whole area is filled or if it just picks up the first amount that touches it.

On another note, it says that all creeper in the area is set to 0 when shooting a Spore, but I have my doubts that is working. Does Digitalis follow other creeper commands?

TDplay

#6
Digi follows Digi commands - they work separately to Creep commands.

As for Delay being "borked" over saves, you can use "SetTimer0" to "SetTimer3" and "GetTimer0" to "GetTimer3" for the most important things that NEED to persist properly over saves. They also have the advantage that they can be read at any time, and unlike making a var that decreases per frame they also are not interfered with by the Delay function. Will that be fixed in CW4?

cornucanis

If you need more than three timers you can also emulate the effect using GetGameTimeFrames. For example:


$Delay:75

once
0 ->timer4
endonce

GetGameTimeFrames <-timer4 gte if
#Code you want to execute on a timer goes here
GetGameTimeFrames <-Delay add ->timer4
endif