Knuckle Cracker

Creeper World 3 => The Coder's Corner => Topic started by: eduran on October 13, 2013, 09:10:10 AM

Title: CRPL related questions
Post by: eduran on October 13, 2013, 09:10:10 AM
Edit: Since I don't want to flood the forum with new threads for every question about CRPL that I can't answer myself I renamed this thread. Feel free to add your own questions to mine.


As soon as I try anything higher than a value of 1.3 for SetCreeperFlowRate (http://knucklecracker.com/wiki/doku.php?id=crpl:docs:setcreeperflowrate) the creeper is all over the map and randomly turning into anti-creeper. The same happens with SetCreeperFlowRateOnDigitalis. Is that a bug or am I doing something wrong?
This is the script I was using:
once
2 SetCreeperFlowRate
endonce

Title: Re: CRPL: SetCreeperFlowRate bugged?
Post by: J on October 13, 2013, 09:20:59 AM
Use values from 0 to 1, if it is 1 the creeper will be divided equally over the cell with creeper and the 4 cells next to it. If it is higher than 1.3, it will move more creeper than present and thus, it will create AC. You might be able to prevent this by emitting creeper in a 2x2 region.
Title: CPRL
Post by: eduran on October 13, 2013, 01:37:22 PM
Thank you, that clears things up.

In the meantime I managed to hit another problem, so I am going to repurpose this thread to ask any questions I come up with.
Here goes:
Trace(div(4 2)) #displays '2' in trace log
Trace(div(2 4)) #displays '0'
Trace(div(2.0 4.0) #displays '0.5'

My layman's guess is that the output of div matches the input. When I put integers in, I get an integer as output. Is there a way around having to add .0 everywhere? And is there a way to force variables to be floating point?
Title: Re: CRPL related questions
Post by: jsmith45 on October 13, 2013, 01:58:26 PM
You can force a value to be floating-point via the "asfloat" command. So if you have an internal variable you can force it to be floating point by including that command before stroing the value in the variable.
For a $variable exposed to the editor, simply make sure the default value is a float, and it should take care of the rest.
Title: Re: CRPL related questions
Post by: Lost in Nowhere on October 13, 2013, 10:23:00 PM
Whenever I try to make a CRPL tower create more CRPL towers, brokenness happens.
For example, this:
Lots of code
Attached to tower
Code (GolehmLoop) Select
# GolehmLoop.crpl
# Created on: 10/9/2013 5:38:32 PM
# ------------------------------------------

$Range:40
$Wait:1800
$HP:12
$MaxDrones:12
$Radius:12
$RotateTime:180 #HAS TO BE A MULTIPLE OF Wait FOR THE ANGLES TO WORK PROPERLY!

once
while CurrentCoords <-Range GetUnitCountInRange eq0
repeat
30 Delay
endwhile
<-MaxDrones 0 do
0 "Drone" I concat ->!
loop
endonce

<-MaxDrones 0 do
"Drone" I concat <-! ->cdrone
<-cdrone "CONST_ISDESTROYED" GetUnitAttribute 1 eq <-cdrone eq0 or if
CurrentCoords "crplcore" CreateUnit ->NewUnit
<-NewUnit "Drone" I concat ->!
<-NewUnit "GolehmDrone" AddScriptToUnit
<-NewUnit "GolehmDrone" "Master" Self SetScriptVar
<-NewUnit "GolehmDrone" "Angle" 360 <-MaxDrones div @degtorad SetScriptVar
<-NewUnit "GolehmDrone" "Radius" <-Radius SetScriptVar
<-NewUnit "GolehmDrone" "RotateTime" <-RotateTime SetScriptVar
<-NewUnit "GolehmDrone" "HP" <-HP SetScriptVar
<-NewUnit "CONST_COUNTSFORVICTORY" 0 SetUnitAttribute
<-NewUnit "CONST_NULLIFIERDAMAGES" 0 SetUnitAttribute
<-NewUnit "CONST_CREATEPZ" 0 SetUnitAttribute
<-NewUnit "CONST_DESTROYMODE" 1 SetUnitAttribute
<-NewUnit "CONST_DESTROYONDAMAGE" 1 SetUnitAttribute
<-NewUnit "CONST_SNIPERTARGET" 1 SetUnitAttribute
<-NewUnit "CONST_SUPPORTSDIGITALIS" 0 SetUnitAttribute
<-NewUnit "CONST_TAKEMAPSPACE" 0 SetUnitAttribute
endif
loop

<-Wait Delay

:degtorad
PI mul 180 div

:destroy
<-MaxDrones 0 do
"Drone" I concat <-! 1 Destroy
loop

Code (GolehmLoop2) Select
# GolehmLoop2.crpl
# Created on: 10/9/2013 5:38:41 PM
# ------------------------------------------

$Range:540
$Speed:2
$Delay1:30
$Delay2:60
$Amount:500
$Amount2:200
$Amount3:100
$Event1D:6
$Event1A:10
$Event2D2:150
$Event2R:5


once
while CurrentCoords <-Range GetUnitCountInRange eq0
repeat
30 Delay
endwhile
CurrentX ->StartX
CurrentY ->StartY
endonce

<-StartX <-Range neg <-Range RandInt add <-StartY <-Range neg <-Range RandInt add <-Speed QueueMove

while GetQueuedMoveCount neq0
repeat
1 Delay
endwhile

50 @Chance if
#Default
<-Delay1 Delay
CurrentCoords <-Amount SetCreeperNoLower
<-Delay2 Delay
else
50 @Chance if
#Event 1
<-Delay1 Delay
<-Event1A 0 do
CurrentCoords <-StartX <-StartY <-Range RandCoordsInRange 2 <-Amount2 CreateSpore
<-Event1D Delay
loop
<-Delay2 Delay
else
#Event 2
<-Delay1 Delay
CurrentX <-Event2R add CurrentX <-Event2R sub do
CurrentY <-Event2R add CurrentY <-Event2R sub do
J I <-Amount3 SetCreeperNoLower
J I 1 SetDigitalisGrowth
J I 1 SetDigitalis
loop
loop
<-Event2D2 Delay
endif
endif

:Chance
0 100 RandInt gte

Not attached to the tower:
Code (GolehmDrone) Select
# GolehmDrone.crpl
# Created on: 10/9/2013 5:38:47 PM
# ------------------------------------------

$Master:0
$Angle:0
$Radius:12
$RotateTime:180
$HP:12

once
<-Angle asfloat @degtorad ->ca
360 <-RotateTime div @degtorad ->step
Self "CONST_MAXHEALTH" <-HP SetUnitAttribute
Self "CONST_HEALTH" <-HP SetUnitAttribute
Self "main" "Custom4" SetImage
Self "second" "Custom1" SetImage
Self "beam" "Custom0" SetImage
Self "main" 2 2 SetImageScale
Self "second" 2 2 SetImageScale
Self "beam" <-Radius 2 SetImageScale
Self "main" -0.2 SetImagePositionZ
Self "beam" -0.15 SetImagePositionZ
Self "second" -0.1 SetImagePositionZ
endonce

<-ca <-step add ->ca
<-ca cos <-Radius asfloat mul <-Master "CONST_XCOORD" GetUnitAttribute add SetCurrentX
<-ca sin <-Radius asfloat mul <-Master "CONST_YCOORD" GetUnitAttribute add SetCurrentY
Self "main" <-ca SetImageRotation
Self "second" <-ca SetImageRotation
Self "beam" <-ca SetImageRotation
Self "beam" <-Master "CONST_XCOORD" GetUnitAttribute CurrentX @avg SetImagePositionX
Self "beam" <-Master "CONST_YCOORD" GetUnitAttribute CurrentY @avg SetImagePositionY

:degtorad
PI mul 180 div
:avg
add 2 div
[close]
is supposed to make the tower move around, emitting creeper and spores, which it does fine, although it occasionally teleports randomly.
However, it is supposed to be surrounded by a bunch of drones to block attacks, which don't even appear.
So, what is the problem with it?
Title: Re: CRPL related questions
Post by: albrittbrat on October 14, 2013, 12:31:40 AM
Lost in Nowhere...wow, you are doing alot there. In the map I am working on I have a CRPL tower that makes another CRPL tower and gives it a script to act like a Runner's nest. It works perfectly, but it is nowhere near as complex as what you are trying to accomplish.
I have no idea what '!' does in your drone loop in 'GolehmLoop.crpl'.
I have attached a copy of my two scripts, they might help, but I am not sure. Sounds like an awesome concept though! Look forward to playing your map.
Spoiler


# Primary custom tower code
# If there are no player units within outer digitalis, blue conditions
# If there are player units within outer digitalis, green conditions
# If there are player units within inner digitalis, red conditions
# Changing conditions should change color of creeper on the map
# Outer digitalis bounds: TL(66,66); TR(190,66); BL(66,190); BR(190,190)
# Inner digitalis bounds: T1L(117,98); T1R(139,98)
#                         T2L(98,117); T2R(158,117)
#                         T3L(98,139); T3R(158,139)
#                         T4L(117,158);T4R(139,158)
#-----------------------------------------------------------------------
$range:200
$sleepy:30
@GetClosestUnit ->closestUnit
<-closestUnit neq0 if
<-closestUnit CONST_COORDX GetUnitAttribute ->targetX
<-closestUnit CONST_COORDY GetUnitAttribute ->targetY
else
0 ->targetX
0 ->targetY
endif

#first check to see if there any units in range
<-targetX neq0 <-targetY neq0 and if
#second check to see if X & Y are both between 36 and 220
<-targetX 36 gte <-targetX 220 lte and <-targetY 36 gte and <-targetY 220 lte and if
#third condition to check is if X & Y are both between 66 and 190
<-targetX 66 gte <-targetX 190 lte and <-targetY 66 gte and <-targetY 190 lte and if
#fourth condition to check if X & Y are both between 100 and 156
<-targetX 100 gte <-targetX 156 lte and <-targetY 100 gte and <-targetY 156 lte and if
#Red conditions here, execute if within inner digitalis (kinda)
once
@SetColorRed
#Place a CRPL core to act as a runners nest
"CRPLCORE" CurrentCoords CreateUnit ->unit2
<-unit2 "Mimic Runner.crpl" AddScriptToUnit
<-unit2 "main" "CustomRunnerNest" SetImage
#Seed active digitalis into entire center grid
158 98 do
158 98 do
I J true SetDigitalisGrowth
I J 1 SetDigitalis
loop
loop
endonce
128 128 75 RandCoordsInRange ->randsinRange
<-randsinRange 5 QueueMove
60 Delay
AbortMove
CurrentCoords 250 SetCreeper
#end Red conditions
endif
#Green conditions here, execute if within outer digitalis
once
@SetColorGreen
endonce
#Plant 25 creeper 5 times in random locations
5 1 do
RandCoords 25 AddCreeper
loop
#Launch 1 spore with 1 health, 100 payload at random coordinates
CurrentCoords RandCoords 1 100 CreateSpore <-numb 1 add ->numb
#end Green conditions
endif
#Blue conditions here, execute on outer perimeter of where player units are
#This is more of just a warning with little consequences
once
@SetColorBlue
endonce
CurrentCoords 50 SetCreeper
#end Blue conditions
endif
endif
<-sleepy Delay

#Function to find UID of closest unit
:GetClosestUnit
99999999 ->closestDistance
0 ->closestUnit
CurrentCoords <-range GetUnitsInRange ->unitCount
<-unitCount neq0 if
<-unitCount 0 do
->unit
CurrentCoords <-unit CONST_COORDX GetUnitAttribute <-unit CONST_COORDY GetUnitAttribute Distance ->d
<-d <-closestDistance lt if
<-d ->closestDistance
<-unit ->closestUnit
endif
loop
endif
<-closestUnit
#End of GetClosestUnit function
#Function to change color to dark blue
:SetColorBlue
   GetCreeperColors ->acB ->acG ->acR ->creeperB ->creeperG ->creeperR
   0 ->creeperR
   0 ->creeperG
   60 ->creeperB
   SetCreeperColors(<-creeperR <-creeperG <-creeperB <-acR <-acG <-acB)
#End of SetColorBlue function
#Function to change color to green
:SetColorGreen
   GetCreeperColors ->acB ->acG ->acR ->creeperB ->creeperG ->creeperR
   0 ->creeperR
   160 ->creeperG
   0 ->creeperB
   SetCreeperColors(<-creeperR <-creeperG <-creeperB <-acR <-acG <-acB)
#End of SetColorGreen function
#Function to change color to red
:SetColorRed
   GetCreeperColors ->acB ->acG ->acR ->creeperB ->creeperG ->creeperR
   160 ->creeperR
   0 ->creeperG
   0 ->creeperB
   SetCreeperColors(<-creeperR <-creeperG <-creeperB <-acR <-acG <-acB)
#End of SetColorRed function


#Simple script to mimic a runner's nest
#--------------------------------------
30 ->sleep
GetRunnerCount 15 lte if
CurrentCoords 2 25 100 CreateRunner
<-sleep Delay
endif

[close]
Title: Re: CRPL related questions
Post by: eduran on October 14, 2013, 04:36:57 AM
Quote from: Lost in Nowhere on October 13, 2013, 10:23:00 PM

CurrentCoords "crplcore" CreateUnit ->NewUnit

However, it is supposed to be surrounded by a bunch of drones to block attacks, which don't even appear.

You have to switch the coordinates and the unit type:

"crplcore" CurrentCoords CreateUnit ->NewUnit


No idea what's up with the random teleporting. To me your movement code seems fine.
Title: Re: CRPL related questions
Post by: J on October 14, 2013, 08:43:00 AM
Quote from: Lost in Nowhere on October 13, 2013, 10:23:00 PM
However, it is supposed to be surrounded by a bunch of drones to block attacks, which don't even appear.
So, what is the problem with it?
Add this line:
<-NewUnit "main" "Default" SetImageYou must set an image for a crpl core to appear.
Title: Re: CRPL related questions
Post by: Lost in Nowhere on October 14, 2013, 05:40:19 PM
J, the image is set in the drone script... which doesn't seem to be working anyways.
The drones appear to be being created, but just sit there and have no image. I forgot to mention that whenever the activation code finishes, the boss teleports to the left side of the screen and waits some more for it to start actually doing stuff.
Wiki articles for the <-! (http://knucklecracker.com/wiki/doku.php?id=crpl:docs:refread) and ->! (http://knucklecracker.com/wiki/doku.php?id=crpl:docs:refwrite) operators.
I'm going to mess around with it a bit to see if I can get it to work...
edit - Managed to get rid of the random teleportation to the left side of the screen.
edit 2 - Just found the issue with the drones - the script name was "GolehmDrone" instead of "GolehmDrone.crpl".
Aaaaaaaaaaaand, now the drones are acting weird...
Title: Re: CRPL related questions
Post by: eduran on October 15, 2013, 08:12:22 AM
Two quick questions:
1) Is it possible to pause/unpause the game with CRPL?
2) Is it possible to track player input (mouse clicks/key presses) while the game is paused?
Title: Re: CRPL related questions
Post by: Lost in Nowhere on October 15, 2013, 09:57:11 AM
Is it possible to directly set a unit's position to something that is not an integer?
Title: Re: CRPL related questions
Post by: thepenguin on October 15, 2013, 06:36:13 PM
Quote from: eduran on October 15, 2013, 08:12:22 AM
Two quick questions:
1) Is it possible to pause/unpause the game with CRPL?
2) Is it possible to track player input (mouse clicks/key presses) while the game is paused?
yes and no. in that order. The command is PauseGame I know virgil used it in the credits scripts. (It's at the last line)

# CRPLChest.crpl
# Created on: 9/14/2013 2:57:04 PM
# ------------------------------------------

$score:200

once
GetCoresWithVar("name" "Player") pop ->player
endonce

if (Distance(CurrentCoords GetUnitAttribute(<-player CONST_COORDX) GetUnitAttribute(<-player CONST_COORDY)) lte(2))
@ApplyPoints
PlaySound("Retro20")
Destroy(Self 1)
endif

:ApplyPoints
AddAdditionalScore(<-score)
CreateUnit("CRPLCORE" CurrentCoords) ->fadingPoints
AddScriptToUnit(<-fadingPoints "FadingPoints.crpl")
SetScriptVar(<-fadingPoints "FadingPoints.crpl" "pointAmt" <-score)

ClearConversation
AddConversationMessage(7 "You may have noticed that this mission is substantially different from most of the other missions in the game....")
AddConversationMessage(7 "How?  CRPL... Creeper Reverse Polish Language.  That's the scripting language available in CW3.")
AddConversationMessage(7 "Everything from the Gold Man, to his bullets, to the chests... even the walls that Creeper can't overflow.... all implemented using CRPL.")
AddConversationMessage(7 "What's even better is that you can use CRPL to make maps like this or almost anything else you can think up!")
AddConversationMessage(7 "Visit KnuckleCracker.com to learn more about CRPL, and making your own custom maps.")
ShowConversation
PauseGame
Title: Re: CRPL related questions
Post by: Cotters on October 17, 2013, 06:39:43 PM

How do you use the "CreateEffect"? I read the wiki about it, and the example works; but i would like to know how to change the effect.
From wiki:
CreateEffect(14 CellToPixel(CurrentCoords) -1 1.5 1.5 0.05)

I have a feeling it's using effect "0", but I can't figure out how to add in the variable for 1-16 effects.

Title: Re: CRPL related questions
Post by: albrittbrat on October 17, 2013, 08:24:03 PM
Question:
Is there a way to make it so that packets cannot traverse creeper or digitalis, similar to how packets got destroyed when they came into contact with creeper in CW2?
I want to build a maze map, but don't want to have to make 10 wide walls to prevent bridging.
Title: Re: CRPL related questions
Post by: Michionlion on October 17, 2013, 09:49:23 PM
Quote from: Cotters on October 17, 2013, 06:39:43 PM

How do you use the "CreateEffect"? I read the wiki about it, and the example works; but i would like to know how to change the effect.
From wiki:
CreateEffect(14 CellToPixel(CurrentCoords) -1 1.5 1.5 0.05)

I have a feeling it's using effect "0", but I can't figure out how to add in the variable for 1-16 effects.



If you take a look at the CreateEffect wiki page, you missed the vital part.




Arguments Notation
Effect_Num,X,Y,Z,ScaleX,ScaleY,Speedn1 x1 y1 z1 f1 f2 f3 -

Those 'Arguments' - they list what you pass into the method.  the very first arg - 'Effect_Num' - is what you need to change.  In the examples case, it is the number '14'.
Title: Re: CRPL related questions
Post by: Cotters on October 17, 2013, 10:35:32 PM
Quote from: Michionlion on October 17, 2013, 09:49:23 PM



Arguments Notation
Effect_Num,X,Y,Z,ScaleX,ScaleY,Speedn1 x1 y1 z1 f1 f2 f3 -

Those 'Arguments' - they list what you pass into the method.  the very first arg - 'Effect_Num' - is what you need to change.  In the examples case, it is the number '14'.
Aha! thanks so much!  :)
I mistook the 14 as the pixel ratio.
Title: Re: CRPL related questions
Post by: Lost in Nowhere on October 17, 2013, 11:06:39 PM
Why isn't this working?
# CreeperCannon.crpl
# Created on: 10/9/2013 8:02:23 AM
# ------------------------------------------

$RADIUS:7
$POWER:1.2 #Larger=weaker
$EXTRACREEPER:1
$CHARGETIME:7200
$RELOADTIME:1800

once
1 SetPopupTextAlwaysVisible
<-CHARGETIME 0 do
1 Delay
I asfloat <-CHARGETIME asfloat div 100 asfloat mul floor "%" Concat SetPopupText
loop
endonce

GetTimer0 0 lte if
<-RELOADTIME SetTimer0
#create bullet here
@GetClosestUnit ->closestUnit
"crplcore" CurrentCoords CreateUnit ->NewUnit
<-NewUnit "MegaBullet.crpl" AddScriptToUnit
<-NewUnit "MegaBullet.crpl" "TARGETX" <-closestUnit CONST_COORDX GetUnitAttribute SetScriptVar
<-NewUnit "MegaBullet.crpl" "TARGETY" <-closestUnit CONST_COORDY GetUnitAttribute SetScriptVar
<-NewUnit "MegaBullet.crpl" "RADIUS" <-RADIUS SetScriptVar
<-NewUnit "MegaBullet.crpl" "POWER" <-POWER SetScriptVar
<-NewUnit "MegaBullet.crpl" "EXTRACREEPER" <-EXTRACREEPER SetScriptVar
<-NewUnit "CONST_COUNTSFORVICTORY" 0 SetUnitAttribute
<-NewUnit "CONST_NULLIFIERDAMAGES" 0 SetUnitAttribute
<-NewUnit "CONST_CREATEPZ" 0 SetUnitAttribute
<-NewUnit "CONST_DESTROYMODE" 1 SetUnitAttribute
<-NewUnit "CONST_SUPPORTSDIGITALIS" 0 SetUnitAttribute
<-NewUnit "CONST_TAKEMAPSPACE" 0 SetUnitAttribute
<-NewUnit "main" "Custom1" SetImage
endif
<-RELOADTIME GetTimer0 sub <-RELOADTIME div 100 mul floor "%" Concat SetPopupText

:GetClosestUnit
99999999 ->closestDistance
0 ->closestUnit
CurrentCoords 1000 GetUnitsInRange ->unitCount
<-unitCount neq0 if
<-unitCount 0 do
->unit
CurrentCoords <-unit CONST_COORDX GetUnitAttribute <-unit CONST_COORDY GetUnitAttribute Distance ->d
<-d <-closestDistance lt if
<-d ->closestDistance
<-unit ->closestUnit
endif
loop
endif
<-closestUnit

:destroyed
CurrentCoords 1000 AddCreeper

The tower just sits there, displaying "0%."
It's supposed to wait for CHARGETIME and then wait for RELOADTIME between firing bullets, with the text displaying how close it is to building/firing.
Title: Re: CRPL related questions
Post by: eduran on October 19, 2013, 11:44:01 AM
Quote from: Lost in Nowhere on October 17, 2013, 11:06:39 PM
It's supposed to wait for CHARGETIME and then wait for RELOADTIME between firing bullets, with the text displaying how close it is to building/firing.
I think you need an asfloat in your second SetPopupText.
Another question:
I am trying to make a custom emitter that looks exactly like a normal emitter. How do I get SetPopupText to display two lines?
Title: Re: CRPL related questions
Post by: ThirdParty on October 21, 2013, 11:46:55 PM
Quote from: eduran on October 19, 2013, 11:44:01 AMHow do I get SetPopupText to display two lines?
As far as I know there are no escape codes; you have to type the return directly into your script.  e.g.:

SetPopupTextAlwaysVisible(True)
SetPopupText("Line 1
Line 2")
Title: Re: CRPL related questions
Post by: Lost in Nowhere on October 30, 2013, 10:43:23 PM
This isn't working:
# LifeEngine.crpl
# Created on: 10/30/2013 7:23:43 PM
# ------------------------------------------

$Width:37
$Height:36
$CellAmt:2
$Period:15

once
1 ->state
@awake
endonce

<-state if
#Gets creeper state

CurrentCoords ->y ->x
<-Height <-y add <-y do
<-Width <-x add <-x do
I J GetCreeper 0 gt "x" I concat "y" J concat concat ->!
loop
loop

1 Delay
endif
<-state not if
#Recalculates creeper
CurrentCoords ->y ->x

<-Height <-y add <-y do
<-Width <-x add <-x do
I J @GetSurroundingNum ->n

"x" I concat "y" J concat concat <-! if #if the cell is "alive"
<-n 2 eq <-n 3 eq or if #if it has 2 or 3 neighbors
I J <-CellAmt SetCreeper
else #otherwise
I J 0 SetCreeper
endif
else #if the cell is "dead"
<-n 3 eq if #if it has 3 neighbors
I J <-CellAmt SetCreeper
endif
endif
loop
loop

<-Period 1 sub Delay
endif

<-state not ->state

:awake
CurrentCoords ->y ->x
<-Height 0 do
<-Width 0 do
<-x I add <-y J add TRUE FALSE SetPinFieldCell
loop
loop

:GetSurroundingNum
->y2 ->x2
0 ->t
<-y2 1 add <-y2 1 sub do
<-x2 1 add <-x2 1 sub do
<-t "x" I concat "y" J concat concat <-! add ->t
loop
loop
<-t "x" <-x2 concat "y" <-y2 concat concat <-! sub ->t

It is supposed to simulate Conway's Game of Life using creeper in the area specified, but it just erases all creeper.
(In the case that you don't know what that is: http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life (http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life))
Title: Re: CRPL related questions
Post by: ThirdParty on October 30, 2013, 11:16:16 PM
Quote from: Lost in Nowhere on October 30, 2013, 10:43:23 PMThis isn't working:

I find your reverse polish syntax really hard to read, but I think the "->t" at the end of :GetSurroundingNum was maybe meant to be a "return".
Title: Re: CRPL related questions
Post by: Grayzzur on October 30, 2013, 11:24:50 PM
Another thing to consider is your do loops.

3 0 do
  # runs for 0, 1 and 2. Does not run for 3
loop

I think you may be trying to work on a 3x3 grid around a starting point. If that's the case, you may want to try:
   <-y2 2 add <-y2 1 sub do
      <-x2 2 add <-x2 1 sub do
Title: Re: CRPL related questions
Post by: Lost in Nowhere on October 31, 2013, 09:24:24 AM
ThirdParty: No, that last line is meant to just make it not count the cell in question. I completely forgot the return.
Grayzzur: I just thought about that while I was laying in bed, half-asleep.
And yay, it works now!
Title: Re: CRPL related questions
Post by: knucracker on October 31, 2013, 10:46:31 AM
Note that you can set walls (and unset them) with great efficiency as well.  So if you are using Creeper because it is fast to set (in your game of life sim), also consider walls since they are equally fast.  You could also create a 'GUI' the player could click on or for display purposes at the top or bottom of the map that would allow you to clear the grid, create well known structures (gliders, etc.), or allow you to click to paint or erase.  See the Credits mission for some code on how to create GUI.
Title: Re: CRPL related questions
Post by: Lost in Nowhere on October 31, 2013, 05:28:43 PM
I'm mostly using it because it is very easy to kill, though using walls could also work.
I made a script that creates a glider, which worked. I also tried a glider gun, but it dies shortly after emitting a glider... which it destroys.
Also, somewhere else you mentioned that there is a limit of 500,000 or so operations per tower per frame. What exactly constitutes a operation in this context?
Title: Re: CRPL related questions
Post by: J on October 31, 2013, 05:35:00 PM
Quote from: Lost in Nowhere on October 31, 2013, 05:28:43 PM
Also, somewhere else you mentioned that there is a limit of 500,000 or so operations per tower per frame. What exactly constitutes a operation in this context?
Every opcode is counted. so1 2 addcounts as 3 operations/opcodes
Title: Re: CRPL related questions
Post by: Grauniad on October 31, 2013, 05:50:18 PM
Quote from: J on October 31, 2013, 05:35:00 PM
Quote from: Lost in Nowhere on October 31, 2013, 05:28:43 PM
Also, somewhere else you mentioned that there is a limit of 500,000 or so operations per tower per frame. What exactly constitutes a operation in this context?
Every opcode is counted. so1 2 addcounts as 3 operations/opcodes

J: Actually I believe that is one opcode with two operands. :)
Title: Re: CRPL related questions
Post by: MagmaMcFry on October 31, 2013, 07:36:08 PM
No, those are three opcodes, there is no such thing as operands in the syntax of a simple stack-based language. The first opcode pushes a 1 to the stack, the second opcode pushes a 2 to the stack, and the third opcode pops two values and pushes their sum. This leads to something that looks like reverse polish notation, but is actually caused by something else. /tmyk
Title: Re: CRPL related questions
Post by: Grauniad on October 31, 2013, 07:38:37 PM
My bad, I conflated CRPL with assembler. You are right.
Title: Re: CRPL related questions
Post by: Lost in Nowhere on November 07, 2013, 07:58:57 PM
Why does CRPL seem to not like me?
Anyways:
This is supposed to fire exploding globs of creeper that function similar to the Mass orbital weapons, but create more creeper.
# GremlinTower.crpl
# Created on: 11/7/2013 3:39:55 PM
# ------------------------------------------

$Build:1800
$Wait:1800
$Amt:50.0 #Amount of creeper is divided by this
$Height:0.5

once
FALSE ->Built
CurrentX ->x
CurrentY ->y
Self "CONST_MAXAMMO" <-Build SetUnitAttribute
Self "CONST_SHOWAMMOBAR" TRUE SetUnitAttribute
endonce

<-Built if
Self "CONST_AMMO" GetUnitAttribute ->a
<-a Self "CONST_MAXAMMO" GetUnitAttribute gte if
#fire a bullet
"CRPLCORE" CurrentCoords CreateUnit ->u
@GetClosestUnit ->v
<-u "CRBullet.crpl" AddScriptToUnit
<-u "GremlinBullet.crpl" "TX" <-v "CONST_XCOORD" GetUnitAttribute SetScriptVar
<-u "GremlinBullet.crpl" "TY" <-v "CONST_YCOORD" GetUnitAttribute SetScriptVar
0 ->p
CurrentY 2 add CurrentY 1 sub do
CurrentX 2 add CurrentX 1 sub do
I J GetCreeper <-p add ->p
I J 0 SetCreeper
loop
loop
<-u "GremlinBullet.crpl" "Power" <-p SetScriptVar
<-u "GremlinBullet.crpl" "Height" <-Height SetScriptVar
Self "CONST_AMMO" 0 SetUnitAttribute
else
Self "CONST_AMMO" <-a 1 add SetUnitAttribute
endif
else
Self "CONST_AMMO" GetUnitAttribute ->a
<-a Self "CONST_MAXAMMO" GetUnitAttribute gte if
Self "CONST_MAXAMMO" <-Wait SetUnitAttribute
Self "CONST_AMMO" 0 SetUnitAttribute
TRUE ->Built
else
Self "CONST_AMMO" <-a 1 add SetUnitAttribute
endif
endif

<-x <-y SetCurrentCoords

:GetClosestUnit
99999999 ->closestDistance
0 ->closestUnit
CurrentCoords 9999 GetUnitsInRange ->unitCount
<-unitCount neq0 if
<-unitCount 0 do
->unit
CurrentCoords <-unit CONST_COORDX GetUnitAttribute <-unit CONST_COORDY GetUnitAttribute Distance ->d
<-d <-closestDistance lt if
<-d ->closestDistance
<-unit ->closestUnit
endif
loop
endif
<-closestUnit

# GremlinBullet.crpl
# Created on: 11/7/2013 3:42:35 PM
# ------------------------------------------

$Power:100
$TX:0
$TY:0
$Height:0.5

once
<-TX <-TY 8 QueueMove
Self "main" "Custom0" SetImage
Self "CONST_NULLIFIERDAMAGES" FALSE SetUnitAttribute
Self "CONST_SUPPORTSDIGITALIS" FALSE SetUnitAttribute
Self "CONST_COUNTSFORVITORY" FALSE SetUnitAttribute
Self "CONST_SUPPORTSDIGIALIS" FALSE SetUnitAttribute
Self "CONST_TAKESMAPSPACE" FALSE SetUnitAttribute
endonce

GetQueuedMoveCount eq0 if
.75 <-Power mul PI div 1 3 div pow ->Radius
CurrentCoords GetTerrain ->t
<-Radius 1 add <-Radius neg do
<-Radius 1 add <-Radius neg do
I 2 pow J 2 pow add ->a
<-a <-Radius lte if
<-a sqrt <-Height mul ->b
I J <-b 2 mul AddCreeper
I J GetTerrain ->n <-t <-b sub min 1 max ->c
I J <-c SetTerrain
endif
loop
loop

CurrentCoords <-Radius GetUnitsInRange ->unitCount
<-unitCount neq0 if
<-unitCount 0 do
2 Destroy
loop
endif
Self 2 Destroy
endif
Title: Re: CRPL related questions
Post by: kwinse on November 08, 2013, 12:12:25 AM
Quote from: Lost in Nowhere on November 07, 2013, 07:58:57 PM
Self "CONST_SUPPORTSDIGITALIS" FALSE SetUnitAttribute
Self "CONST_COUNTSFORVITORY" FALSE SetUnitAttribute
Self "CONST_SUPPORTSDIGIALIS" FALSE SetUnitAttribute

Haven't really picked through it but I noticed two typoed lines, one of them being a repeated command. Should be "CONST_COUNTSFORVICTORY".
Title: Re: CRPL related questions
Post by: Grayzzur on November 08, 2013, 09:00:11 AM
Quote from: Lost in Nowhere on November 07, 2013, 07:58:57 PM
Why does CRPL seem to not like me?
Anyways:
This is supposed to fire exploding globs of creeper that function similar to the Mass orbital weapons, but create more creeper.

In GremlinTower:
* You added the script "CRBullet.crpl" to your new bullet unit, instead of "GremlinBullet.crpl" like I think you intended.
* The next two lines, I think you need to fix the GetUnitAttribute parameters. Take the quotes off the consts
  ... <-v CONST_COORDX GetUnitAttributes ...
  ... <-v CONST_COORDY GetUnitAttributes ...

In GremlinBullet:
* What the previous poster mentioned. You misspelled some of the unit attribute constants. Also, they shouldn't have quotes around the constant names.
  Self CONST_SUPPORTDIGITALIS FALSE SetUnitAttribute
  - etc.

I recommend Notepad++ with the CRPL add-ons you can download from the Wiki. It really helps get the spelling of all the commands and constants correctly.
Title: Re: CRPL related questions
Post by: Lost in Nowhere on November 08, 2013, 06:50:38 PM
I have Notepad++, but not the syntax highlighter thing... I guess I'll get that...
Aaaand, I can't find it.
Title: Re: CRPL related questions
Post by: Grayzzur on November 08, 2013, 11:01:20 PM
Quote from: Lost in Nowhere on November 08, 2013, 06:50:38 PM
I have Notepad++, but not the syntax highlighter thing... I guess I'll get that...
Aaaand, I can't find it.

http://knucklecracker.com/wiki/doku.php?id=crpl:overview

Bottom of the page, section called "Creating CRPL Scripts" -- has links to download config files for Notepad++, and tells you what to do with them.
Title: Re: CRPL related questions
Post by: Lost in Nowhere on November 10, 2013, 06:32:25 PM
Quote from: Grayzzur on November 08, 2013, 11:01:20 PM
Quote from: Lost in Nowhere on November 08, 2013, 06:50:38 PM
I have Notepad++, but not the syntax highlighter thing... I guess I'll get that...
Aaaand, I can't find it.

http://knucklecracker.com/wiki/doku.php?id=crpl:overview

Bottom of the page, section called "Creating CRPL Scripts" -- has links to download config files for Notepad++, and tells you what to do with them.
Okay, now I just can't figure out how to get it to use it...
I have used all of the given instructions.
Edit - Never mind, it just doesn't apply to the files that are already open.
Title: Re: CRPL related questions
Post by: eduran on November 11, 2013, 09:27:12 AM
Is it possible to access the player's key bindings? I'd like to do something when the pause key is pressed. In principle, GetKeyDown does what I need, except that i don't know what key pause/unpause is bound to.
Title: Re: CRPL related questions
Post by: knucracker on November 11, 2013, 09:44:43 AM
There's no way to read those bindings right now...

Thinking about this, though, I wonder if an intrinsic function callback might meet the need.  For instance, if whenever the game was paused an "OnGamePaused" function would be called on any script.  The complication I can see is with the 'step' functionality (pressing 'n').  That basically allows a game to advance by one frame while in the paused state.  So even while paused, a game can advance.  Of course if you only want to do something at the moment of a pause, the callback would work fine (assuming it doesn't re-fire every time 'n' is pressed).
Title: Re: CRPL related questions
Post by: eduran on November 11, 2013, 10:37:00 AM
I am trying to use a couple of custom UI elements, which stop working during pause mode. What I need is a way to make sure they are left in a 'save' state when the game is paused. A OnGamePause function would work for that.
Title: Re: CRPL related questions
Post by: Lost in Nowhere on November 11, 2013, 08:57:55 PM
How would one make a "sandstorm" effect that covers the whole map, especially while paused?
Title: Re: CRPL related questions
Post by: eduran on November 12, 2013, 04:27:18 AM
Quote from: Lost in Nowhere on November 11, 2013, 08:57:55 PM
especially while paused?
CRPL scripts never run while the game is paused. The best one could do in that regard is set up a (still) image that shows during pause without any additional effect.
Title: Re: CRPL related questions
Post by: pawel345 on November 17, 2013, 06:58:31 AM
How does GetEnemyUnitsInRange work????? Because for some reason it counts my strafer and bombers as enemies?????????? also the code posted on the wiki as example doesn't work.....

Specifically I need a code to count all enemies on map on map. But the GetEnemyUnitsInRange counts also totems, ore deposits (but that's on I can simply subtract them). But out of random it also started including strafes and bombers ??? and that I can't take into account at first? bdw. still sitting on 1.04 build.
Title: Re: CRPL related questions
Post by: Grauniad on November 17, 2013, 09:52:31 AM
Ut-oh. Virgil made a recent change in how Strafers and Bombers are treated, to correct their ISLANDED attribute. I'll alert him to this and he may have to loo at a further fix. :)
Title: Re: CRPL related questions
Post by: pawel345 on November 17, 2013, 11:43:29 AM
I use the old build so it can't be that.
Title: Re: CRPL related questions
Post by: knucracker on November 18, 2013, 11:38:08 AM
Maybe the bomber itself counts, not the bomber pad.  The bomber and the bomber pad are actually two different 'units' to the game.  They are related internally, but are two distinct things nonetheless. So maybe the pad doesn't count, but the bomber does.  The part of your description the confuses me is this:
"But out of random it also started including strafes and bombers".

What do you mean by random?  Do you have a test map where they weren't being counted at some point, then they started being counted?
Title: Re: CRPL related questions
Post by: pawel345 on November 18, 2013, 01:56:49 PM
Sorry I had a test map where the emitter output was scaled (max - number of enemies on map)*20 and it worked fine but when while testing i build a bomber and a strafer they started emitting AC(meaning nr. enemies on map has gone up) when i destroyed the bomber and strafer the emmiters behaved normally again. I used something like

0 ->count
0 0 99999 GetEnemiesInRange do
<-count add(1) ->count
enddo
<-count

this count included the ore deposits and totems on map as well.
Title: Re: CRPL related questions
Post by: knucracker on November 18, 2013, 02:40:21 PM
Alright I see some issues with this I will fix and put in the next beta build.  Looks like I left out the strafer and bomber in a routine for some reason.

As a note on your CRPL, you can do this for improved efficiency:

GetEnemyUnitsInRange(0 0 99999) ->count ClearStack

Note that you have to be running with an empty stack prior to this line since it clears the stack.  But this will give you the count and then throw away all of the unit UIDs that were pushed to the stack without requiring that you pop each one off.
Title: Re: CRPL related questions
Post by: Clean0nion on November 20, 2013, 02:09:48 PM
If I use GetUnitAt on a coord with multiple units on it, in which order are the UIDs returned?
Edit: answered by V and eduran. eduran says only returns one UID. V says returns all UIDs in order of age.
Title: Re: CRPL related questions
Post by: knucracker on November 20, 2013, 08:16:50 PM
It should only return one, that's for sure.   If you want all, then you could probably use a GetAllUnitsInRange call with a short range (like 1).

I just checked and when you ask for one, the one you get back (if units are stacked) is not defined.  Translation, it's hash order and won't make any sense and can change across loads or as units get created and destroyed.
Title: Re: CRPL related questions
Post by: kwinse on November 20, 2013, 09:19:14 PM
I was messing around with that the other day and noticed the problem with GetUnitAt and stacked units (in my case, a cannon and a flying strafer). A 0 range on your choice of unit in range function should work.
Title: Re: CRPL related questions
Post by: Lost in Nowhere on November 24, 2013, 10:27:13 AM
Ok, I am trying to make a player-controlled spaceship, similar to the credits mission.
Currently, it immediately explodes and teleports while doing so, despite it having no reason to do so.
# PlayerShip.crpl
# Created on: 11/23/2013 8:06:21 PM
# ------------------------------------------

$Name:"Player"

$MaxHealth:100
$HealRate:0.1
$CreeperDamage:0.6

$SelectedWeapon:0

$LaserCooldown:10
$LaserCreeperDamage:100
$LaserStructureDamage:100

$MaxMissiles:0
$Missiles:0
$MissileCooldown:30
$MissileCreeperDamage:10000
$MissileStructureDamage:200

$MaxSuperLasers:0
$SuperLasers:0
$SuperLaserCooldown:30
$SuperLaserStructureDamage:500

$MaxSpeed:4.0
$Acceleration:0.05
$TurnSpeedDeg:4

once
# initialize more variables and set some unit attributes
SetUnitAttribute(Self CONST_MAXHEALTH <-MaxHealth)
SetUnitAttribute(Self CONST_HEALTH <-MaxHealth)
SetUnitAttribute(Self CONST_DESTROYONDAMAGE TRUE)
SetUnitAttribute(Self CONST_HEALRATE <-HealRate)

0.0 ->dir
0.0 ->speed
endonce

@UpdateHealth
@UpdatePosition
@UpdateImage

:awake
TRUE EnableAlternateControlMode
:UpdateHealth
if (@OverCreeper)
GetUnitAttribute(Self CONST_HEALTH) ->health
<-health sub(<-CreeperDamage) ->health
if (<-health lte(0))
0 ->health
endif
SetUnitAttribute(Self CONST_HEALTH <-health)
endif
#if (@OverWall)
# 0 ->health
#endif
#Stick stuff for other enemies here
if (<-health lte(0))
Self 2 Destroy
endif
:OverCreeper
do(2 -1)
do (2 -1)
if (GetCreeper(CurrentX add(I) CurrentY add(J)) gt(0))
return (TRUE)
endif
loop
loop
FALSE
:OverWall
do(2 -1)
do (2 -1)
if (GetTerrainOverride(CurrentX add(I) CurrentY add(J)) gt(500))
return (TRUE)
endif
loop
loop
FALSE
:UpdateImage
Self "main" <-dir SetImageRotation
:UpdatePosition
"LeftArrow" GetKey or("A" GetKey) if
<-TurnSpeedDeg @DegToRad <-dir add ->dir
endif
"RightArrow" GetKey or("D" GetKey) if
<-TurnSpeedDeg @DegToRad <-dir sub ->dir
endif
"UpArrow" GetKey or("W" GetKey) if
<-speed <-Acceleration add <-MaxSpeed min ->speed
endif
"DownArrow" GetKey or("S" GetKey) if
<-speed <-Acceleration sub 0.0 max ->speed
endif
CurrentPixelCoords ->px ->py
<-dir cos mul (<-speed 8 mul) add (<-px) ->px
<-dir sin mul (<-speed 8 mul) add (<-py) ->py
Self CONST_PIXELCOORDX <-px SetUnitAttribute
Self CONST_PIXELCOORDY <-py SetUnitAttribute
:FireProjectile
"Alpha1" GetKey if
1 ->SelectedWeapon
endif
"Alpha2" GetKey if
2 ->SelectedWeapon
endif
"Alpha3" GetKey if
3 ->SelectedWeapon
endif

<-SelectedWeapon 1 eq if
    #Stuff
endif
<-SelectedWeapon 2 eq and (<-Missiles 0 gt) if
    #Stuff
endif
<-SelectedWeapon 3 eq and (<-SuperLasers 0 gt) if
    #Stuff
endif
:DegToRad
asfloat PI mul 180.0 div
:destroyed
#FailMission

Its teleportation also seems to be across the line y=MapHeight-x, running diagonally across the map...
Edit - fixed the teleporting
Title: Re: CRPL related questions
Post by: Kingo on November 24, 2013, 10:59:25 AM
Quote from: Lost in Nowhere on November 24, 2013, 10:27:13 AM
Ok, I am trying to make a player-controlled spaceship, similar to the credits mission.
Currently, it immediately explodes and teleports while doing so, despite it having no reason to do so.
# PlayerShip.crpl
# Created on: 11/23/2013 8:06:21 PM
# ------------------------------------------

$Name:"Player"

$MaxHealth:100
$HealRate:0.1
$CreeperDamage:0.6

$SelectedWeapon:0

$LaserCooldown:10
$LaserCreeperDamage:100
$LaserStructureDamage:100

$MaxMissiles:0
$Missiles:0
$MissileCooldown:30
$MissileCreeperDamage:10000
$MissileStructureDamage:200

$MaxSuperLasers:0
$SuperLasers:0
$SuperLaserCooldown:30
$SuperLaserStructureDamage:500

$MaxSpeed:4.0
$Acceleration:0.05
$TurnSpeedDeg:4

once
# initialize more variables and set some unit attributes
SetUnitAttribute(Self CONST_MAXHEALTH <-MaxHealth)
SetUnitAttribute(Self CONST_HEALTH <-MaxHealth)
SetUnitAttribute(Self CONST_DESTROYONDAMAGE TRUE)
SetUnitAttribute(Self CONST_HEALRATE <-HealRate)

0.0 ->dir
0.0 ->speed
endonce

@UpdateHealth
@UpdatePosition
@UpdateImage

:awake
TRUE EnableAlternateControlMode
:UpdateHealth
if (@OverCreeper)
GetUnitAttribute(Self CONST_HEALTH) ->health
<-health sub(<-CreeperDamage) ->health
if (<-health lte(0))
0 ->health
endif
SetUnitAttribute(Self CONST_HEALTH <-health)
endif
#if (@OverWall)
# 0 ->health
#endif
#Stick stuff for other enemies here
if (<-health lte(0))
Self 2 Destroy
endif
:OverCreeper
do(2 -1)
do (2 -1)
if (GetCreeper(CurrentX add(I) CurrentY add(J)) gt(0))
return (TRUE)
endif
loop
loop
FALSE
:OverWall
do(2 -1)
do (2 -1)
if (GetTerrainOverride(CurrentX add(I) CurrentY add(J)) gt(500))
return (TRUE)
endif
loop
loop
FALSE
:UpdateImage
Self "main" <-dir SetImageRotation
:UpdatePosition
"LeftArrow" GetKey or("A" GetKey) if
<-TurnSpeedDeg @DegToRad <-dir add ->dir
endif
"RightArrow" GetKey or("D" GetKey) if
<-TurnSpeedDeg @DegToRad <-dir sub ->dir
endif
"UpArrow" GetKey or("W" GetKey) if
<-speed <-Acceleration add <-MaxSpeed min ->speed
endif
"DownArrow" GetKey or("S" GetKey) if
<-speed <-Acceleration sub 0.0 max ->speed
endif
CurrentPixelCoords ->px ->py
<-dir cos mul (<-speed 8 mul) add (<-px) ->px
<-dir sin mul (<-speed 8 mul) add (<-py) ->py
Self CONST_PIXELCOORDX <-px SetUnitAttribute
Self CONST_PIXELCOORDY <-py SetUnitAttribute
:FireProjectile
"Alpha1" GetKey if
1 ->SelectedWeapon
endif
"Alpha2" GetKey if
2 ->SelectedWeapon
endif
"Alpha3" GetKey if
3 ->SelectedWeapon
endif

<-SelectedWeapon 1 eq if
    #Stuff
endif
<-SelectedWeapon 2 eq and (<-Missiles 0 gt) if
    #Stuff
endif
<-SelectedWeapon 3 eq and (<-SuperLasers 0 gt) if
    #Stuff
endif
:DegToRad
asfloat PI mul 180.0 div
:destroyed
#FailMission

Its teleportation also seems to be across the line y=MapHeight-x, running diagonally across the map...
Edit - fixed the teleporting

Have you checked to see if the health is resetting to zero somewhere in the code?
Title: Re: CRPL related questions
Post by: Lost in Nowhere on November 24, 2013, 11:19:55 AM
No, it's not. It also started working, so, it definitely isn't.
Title: Re: CRPL related questions
Post by: Clean0nion on December 01, 2013, 02:32:40 PM
Why does RandCoords run 25 times in succession always give the same set of 25 coords(?)
Title: Re: CRPL related questions
Post by: Grauniad on December 01, 2013, 02:47:12 PM
For repeatability? :P
Title: Re: CRPL related questions
Post by: knucracker on December 01, 2013, 03:02:31 PM
"health" only gets initialized if the ship is over Creeper.  But there is a check that if health is <= 0, then destroy.  Either this has to be done every frame:
GetUnitAttribute(Self CONST_HEALTH) ->health
or GetUnitAttribute(Self CONST_HEALTH) has to be called for determining whether to call Destroy.
Title: Re: CRPL related questions
Post by: Clean0nion on December 08, 2013, 11:43:30 AM
Command request!
WinMission: the opposite of FailMission
Title: Re: CRPL related questions
Post by: kwinse on December 08, 2013, 12:17:09 PM
Alternatively, you can blow up all enemy units to trigger normal victory, as in the connect totems to win (http://knucklecracker.com/wiki/doku.php?id=crpl:crpltutorial:code_examples#connect_totems_to_win) code example.
Title: Re: CRPL related questions
Post by: Annonymus on December 08, 2013, 12:21:49 PM
He tried (he used destroyallenemyunits) but for some reason it doesn't win the map!
Title: Re: CRPL related questions
Post by: Clean0nion on December 08, 2013, 12:24:02 PM
Quote from: Annonymus on December 08, 2013, 12:21:49 PM
He tried (he used destroyallenemyunits) but for some reason it doesn't win the map!
...or destroy the units.
Title: Re: CRPL related questions
Post by: pawel345 on December 19, 2013, 03:40:29 PM
Collectors is a list with some UID's of CPRL cores. Since the player can destroy them, every game loop I check if any have been destroyed and remove them form this list using such a code:

<-Collectors GetListCount 0 do
<-Collectors I GetListElement CONST_ISDESTROYED GetUnitAttribute if
<-Collectors I RemoveListElement
endif
loop

Can someone tell me why it doesn't work? I'm getting that RemoveListElement it taking item from an empty stack?
Title: Re: CRPL related questions
Post by: knucracker on December 19, 2013, 04:04:13 PM
You are modifying the list as you loop over it, so the indexes change (the list gets shorter).  Imagine you have a list 5 elements long.  0, 1, 2, 3, 4 are the indexes of the elements.  You are looping from 0 through 4 inclusive.  Say that when you are on index 2 you remove the element.  That shrinks the list to 4 elements in length but you will still loop over 5 elements.

This is a common problem that shows up in many situations in many languages and scenarios; modifying a list while iterating over it.  Some languages have iterators that help you deal with it.  CRPL is old school, though, so you have to use an old school solution.  You could use a while/repeat/endwhile loop to go over the list and keep up with an index variable yourself.  Another solution would be to not modify the list but to build a new list each time (leaving out the items you want to discard).

If I had the time I'd work up an couple examples for you. But, I'm rushing to get Colonial Space done this week...
Title: Re: CRPL related questions
Post by: J on December 19, 2013, 05:12:36 PM
Try adding one to a variable each time you remove an element. Substruct this value from I.
0 ->numb
<-Collectors GetListCount 0 do
 <-Collectors I <-numb sub GetListElement CONST_ISDESTROYED GetUnitAttribute if
   <-Collectors I <-numb sub RemoveListElement
   <-numb 1 add ->numb
 endif
loop
Title: Re: CRPL related questions
Post by: Lost in Nowhere on December 22, 2013, 11:16:02 PM
For whatever reason, this isn't functioning properly:
# CircleDecay.crpl
# Created on: 11/23/2013 12:50:12 PM
# ------------------------------------------

$rad:30
$Increase:1
$Decrease:1
$Range:3

once
  PlaySound("Retro25")
  1 ->row
endonce

if (<-row lt (<-rad))
@GetRow
@DoRow
<-row add(1) ->row
endif

:GetRow
<-row 12 mul asfloat PI mul ->circ
<-circ 0 gt if
<-circ 0 do
I @GetCoords ->x ->y
<-x <-y GetTerrain ->t
<-t "x" <-x concat "y" <-y concat concat ->!
loop
endif

:DoRow
<-row 2 mul asfloat PI mul ->circ
<-circ 0 gt if
<-Range 2 mul 1 add ->tr
<-circ 0 do
I @GetCoords ->x ->y
"x" <-x concat "y" <-y concat concat <-! ->t
I ->n
0 ->total
<-n <-Range add <-n <-Range sub do
I @GetCoords swap GetTerrain <-total add ->total
loop
<-total <-tr asfloat div ceil ->nt
<-t <-nt @Check ->ft
<-x <-y <-ft SetTerrain
loop
endif

:GetCoords
->b
<-b <-circ div cos <-row mul CurrentX add ->xgc
<-b <-circ div sin <-row mul CurrentY add ->ygc
<-ygc <-xgc

:Check # oldT newT -> finalT
->newT ->oldT
<-Increase not if
<-newT <-oldT gt if
<-oldT ->newT
endif
endif
<-Decrease not if
<-newT <-oldT lt if
<-oldT ->newT
endif
endif
<-newT

It's supposed to decay higher areas in a circular manner, which it does for about 1/8 of the area; elsewhere, it does nothing.
Title: Re: CRPL related questions
Post by: Flabort on December 30, 2013, 01:58:35 AM
It's not exactly CRPL, but recently I tried to set the middle 3 upgrades at the forge to "-1", meaning you can infinitely upgrade your energy production and ore production, as long as you can afford the increasing price. However, it acted as if I had put in 0. There's a pretty obvious formula for producing the prices for the first 10, but no matter what I try, I can't make it go over 10.
Not that that's a pressing issue, but maybe in a future patch an ability to go over those current bounds would be nice.

Meanwhile, I was wondering, does anyone have a script that changes a core between two states depending on whether it's sitting on creeper or anticreeper? Such as an emitter, that releases 50 AC every 2 seconds if the last thing that was under it was AC, or 100 creeper every 2 seconds if the last thing that was under it was creeper. I'm having trouble with the figuring out whether it's on creeper or not bit.
Title: Re: CRPL related questions
Post by: kwinse on December 30, 2013, 02:29:44 AM
CurrentCoords GetCreeper should work (though you may have to be more creative if you want anti/creeper under any part of it to affect its output). Positive number should be creeper, negative ac. Having it change output like that shouldn't be hard.
Title: Re: CRPL related questions
Post by: Grauniad on December 30, 2013, 07:48:53 AM
Quote from: Flabort on December 30, 2013, 01:58:35 AM
It's not exactly CRPL, but recently I tried to set the middle 3 upgrades at the forge to "-1", meaning you can infinitely upgrade your energy production and ore production, as long as you can afford the increasing price. However, it acted as if I had put in 0. There's a pretty obvious formula for producing the prices for the first 10, but no matter what I try, I can't make it go over 10.
Not that that's a pressing issue, but maybe in a future patch an ability to go over those current bounds would be nice.
Those are hard limits.
Quote

Meanwhile, I was wondering, does anyone have a script that changes a core between two states depending on whether it's sitting on creeper or anticreeper? Such as an emitter, that releases 50 AC every 2 seconds if the last thing that was under it was AC, or 100 creeper every 2 seconds if the last thing that was under it was creeper. I'm having trouble with the figuring out whether it's on creeper or not bit.

Obtain the unit coordinates, the do "getcreeper" at those coordinates and examine the return value.
Title: Re: CRPL related questions
Post by: Flabort on December 30, 2013, 03:15:33 PM
Well, with the first one, I was trying to make a map with two totems, a single ore patch, a free forge, and not enough room to build an energy economy that would support >1 blaster. With only 3 energy upgrades available, but infinite ore upgrades. However, if it's a hard limit, and that's not going to be changing any time soon, I'll just have to go without.  8)

And, oh, OK, so I was obviously getting my notation backwards, the coordinates go before the getcreeper. And I would use an if statement, but... what about staying in it's last state when neither AC or C is present?
Title: Re: CRPL related questions
Post by: Michionlion on December 30, 2013, 03:47:29 PM
Quote from: Flabort on December 30, 2013, 03:15:33 PM
Well, with the first one, I was trying to make a map with two totems, a single ore patch, a free forge, and not enough room to build an energy economy that would support >1 blaster. With only 3 energy upgrades available, but infinite ore upgrades. However, if it's a hard limit, and that's not going to be changing any time soon, I'll just have to go without.  8)

And, oh, OK, so I was obviously getting my notation backwards, the coordinates go before the getcreeper. And I would use an if statement, but... what about staying in it's last state when neither AC or C is present?

Set a variable, that way, as long as you don't change the var except to change to the opposite type, you can emit based on the variables value.
Title: Re: CRPL related questions
Post by: Flabort on January 03, 2014, 12:44:37 AM
Right, so let me know if I did anything wrong here:
$amtCreeper:50
$amtAnti:-25
$interval:60
CurrentCoords GetCreeper 0 gt if
1 ->state
endif
CurrentCoords GetCreeper 0 lt if
0 ->state
endif
<-state if
CurrentCoords <-amtCreeper SetCreeper
else
CurrentCoords <-amtAnti SetCreeper
endif
<-interval Delay

As I imagine it, it starts as an AC emitter, but a much stronger emitter quickly overtakes it, converting it to a regular creeper emitter, but stronger. You can change it back if you can spray enough AC at it... Is there flaws in my logic/script?

edit: Yes, I missed several "<-"s. Except for that. Edited those in.

Edit2: I can confirm it works as intended, and am playing a map I threw together with it. It's very fun, somewhat difficult (not too much), and I am attaching a picture of the map in progress.
Title: Re: CRPL related questions
Post by: Grayzzur on January 03, 2014, 11:04:50 AM
The only thing I would do is add this after your initial variables before the rest of the code:

once
   0 ->state
endonce

This little script works without it, because you're relying on uninitialized variables to have a value of zero at the start. That's a bad practice and might get you into unintended behavior in future script projects. Always initialize your variables.
Title: Re: CRPL related questions
Post by: knucracker on January 03, 2014, 03:07:32 PM
I posted a slight update to your script in your map discussion thread:
http://knucklecracker.com/forums/index.php?topic=15081.msg110691#msg110691

This update makes it so that friendly flip emitters don't have to be nullified to win the map.
Title: Re: CRPL related questions
Post by: Flabort on January 04, 2014, 07:10:40 PM
OK, after having played Nano in Neon, which is just evil genius in it's use of colors, I went and tried to make a script that continually messes with the color of creeper. After some trial and error, finding out that the Get and Set commands use two different number formats, and discovering I had used lte when I wanted gte, I got it to work. I was going to ask how to fix it here, but I'll just share it instead.
Spoiler
# psychedelicCreeper.crpl
# Created on: 1/4/2014 4:00:31 PM
# ------------------------------------------

once #Initializing my variables. Actually, this may as well be ripped off the official examples page for changing creeper color to red. Except I use blue. And the whol Mul thing, that's due to the floating point vs whole number.
GetCreeperColors 255 mul ->acB 255 mul ->acG 255 mul ->acR 255 mul ->creeperB 255 mul ->creeperG 255 mul ->creeperR
20 ->creeperR 20 ->creeperG 220 ->creeperB
SetCreeperColors(<-creeperR <-creeperG <-creeperB <-acR <-acG <-acB)
endonce

#Start the loop by getting the current colors. Pop off the AC colors to make sure I don't mess with them by accident. Same as initialization.
GetCreeperColors 255 mul ->acB 255 mul ->acG 255 mul ->acR 255 mul ->creeperB 255 mul ->creeperG 255 mul ->creeperR

#manipulate two colors, making sure not to touch the third if it's at it's lowest point.
<-creeperR 20 lte <-creeperB <-creeperR gte Or <-creeperG <-creeperR gt and if
<-creeperG 20 sub ->creeperG
<-creeperB 20 add ->creeperB
endif
#Same thing. Note that when one of the two I manipulated reaches it's lowest point, it triggers TRUE in the next one.
<-creeperG 20 lte <-creeperR <-creeperG gte Or <-creeperB <-creeperG gt and if
<-creeperB 20 sub ->creeperB
<-creeperR 20 add ->creeperR
endif
#And the third pair of colors. Pattern should be Blue to Purple to Red to Orange/Yellow to Green to Cyan to Blue.
<-creeperB 20 lte <-creeperG <-creeperB gte Or <-creeperR <-creeperB gt and if
<-creeperR 20 sub ->creeperR
<-creeperG 20 add ->creeperG
endif
#Update the color set, and wait a little bit so as not to lag the game too much.
SetCreeperColors(<-creeperR <-creeperG <-creeperB <-acR <-acG <-acB)
10 Delay
[close]
Title: Re: CRPL related questions
Post by: Flabort on January 12, 2014, 08:28:36 PM
Actually working on a non-theoretical script, and I'm stuck. VirgilW himself told me to try marrying the Flip Emitter concept with the Slip Emitter concept.

So I concieved two new scripts. Everything works except the X coordinate of the Slip Emitter. Much of the code was stolen from the Phantom Emitter script on... I forget which world.
The Converterv2.crpl script goes on a core with the SlipEmitSet.crpl code. You set the variables for where you want the slip emitter to go, and do not actually make a core for the child emitter, the script does that.

The scripts:
Converterv2.crpl
# Converterv2.crpl
# Created on: 1/3/2014 1:53:35 PM
# ------------------------------------------
$amtCreeper:50
$amtAnti:-25
$interval:60
$startState:0
#Initializes state, thanks to Grayzzur for the idea.
Once
<-startState ->state
"
" ->lineBreak
endonce
#Checks if there is creeper, if there is, sets the converter to make creeper.
CurrentCoords GetCreeper 0 gt if
1 ->state
SetPopUpText("amt: " <-amtCreeper <-lineBreak "delay: " <-interval 30 div concat concat concat concat)
SetUnitAttribute(Self CONST_COUNTSFORVICTORY TRUE)
endif
#Checks if there is anticreeper, if there is, sets the converter to make AC
CurrentCoords GetCreeper 0 lt if
0 ->state
#the linebreak is on purpose, and concat because the amt isn't always the same.
SetPopUpText("amt: " <-amtAnti <-lineBreak "delay: " <-interval 30 div concat concat concat concat)
SetUnitAttribute(Self CONST_COUNTSFORVICTORY FALSE)
endif
#Checks the state, remember if there was nothing under it, it will use it's last state!
<-state if
CurrentCoords <-amtCreeper SetCreeper
else
CurrentCoords <-amtAnti SetCreeper
endif
<-interval Delay
[close]
SlipEmitSet.crpl
# SlipEmitSet.crpl
# Created on: 1/12/2014 5:48:16 PM
# ------------------------------------------

$childX:10
$childY:10
$percentEmit:20
$interval:15
once
"CRPLCore" <-childX <-childY CreateUnit ->child
<-child "SlipEmitasChild.crpl" AddScriptToUnit
<-child "SlipEmitasChild.crpl" "interval" <-interval setScriptVar
endonce
Self "Converterv2.crpl" "state" GetScriptVar if
<-child "SlipEmitasChild.crpl" "amtCreeper" Self "Converterv2.crpl" "amtCreeper" getScriptVar <-percentEmit mul 100 div setScriptVar
else
<-child "SlipEmitasChild.crpl" "amtCreeper" Self "Converterv2.crpl" "amtAnti" getScriptVar <-percentEmit mul 100 div setScriptVar
endif

:destroyed
<-child 0 Destroy
[close]
SlipEmitasChild.crpl
# SlipEmitasChild.crpl
# Created on: 1/12/2014 5:48:07 PM
# ------------------------------------------

$interval:15
$amtCreeper:5

once
Self "CONST_CANREQUESTAMMO"  setUnitAttribute
Self "CONST_CELLHEIGHT" 3 setUnitAttribute
Self "CONST_CELLWIDTH" 3 setUnitAttribute
Self "CONST_COUNTSFORVICTORY" false setUnitAttribute
Self "CONST_CREATEPZ" false setUnitAttribute
Self "CONST_DESTROYONDAMAGE" false setUnitAttribute
Self "CONST_NULLIFIERDAMAGES" false setUnitAttribute
Self "CONST_TAKEMAPSPACE" true setUnitAttribute
Self "Main" "Custom2" SetImage
endonce

if (GetTimer0 eq0)
SetCreeper(CurrentX CurrentY <-amtCreeper)
@FullAlphaImage
SetTimer0(<-interval)
endif
@FadeImage

:FadeImage
GetImageColor(Self "main") ->alpha ->blue ->green ->red
if (<-alpha gt(0))
<-alpha sub(15) ->alpha
SetImageColor(Self "main" <-red <-green <-blue <-alpha)
endif

:FullAlphaImage
GetImageColor(Self "main") ->alpha ->blue ->green ->red
SetImageColor(Self "main" <-red <-green <-blue 255)
[close]

Basically my problem is when I start up the map, the slip emitters all appear on the left edge of the map. They have their proper Y coordinate, but not the X coordinate.
Title: Re: CRPL related questions
Post by: Michionlion on January 12, 2014, 09:41:47 PM
spoilers don't work well with code tags...
Title: Re: CRPL related questions
Post by: Flabort on January 12, 2014, 09:59:05 PM
Nothing appears wrong with the BBcode on my end. I can open the spoilers and find the code block within, and from there scroll through my code.

As to the CRPL... what did I do wrong?
Title: Re: CRPL related questions
Post by: eduran on January 13, 2014, 04:19:54 AM
Quote from: Flabort on January 12, 2014, 09:59:05 PM
As to the CRPL... what did I do wrong?

Nothing, actually. I copied the code to a new project without any changes and the slip emitter shows up at 10/10. Check if you manually set childX on the core to a different value. If that's not it, make sure you are really using the code you pasted here and that you compiled it (that one never gets old for me: fix a bug, forget to compile, bug still exists, go off on a wild-goose chase to find cause of the no-longer-existing bug ;D)
Title: Re: CRPL related questions
Post by: Flabort on January 17, 2014, 10:56:31 PM
 ???
Well, I copied the one I pasted to the forum into a new project too, laid out terrain, and just compiled and attached the scripts to a core. No dice. It showed up at 1/10. Also tried to set one to 85/62 afterwards... it showed up at 1/62.

So it's not that I didn't compile this time. Still, thank you for checking, that would have made my week.
Title: Re: CRPL related questions
Post by: eduran on January 18, 2014, 06:00:58 AM
Found the reason why it worked for me: I got the name of the child script wrong, so it was never attached to the slip emitter. That script is causing the problem. Remove the quotation marks from all CONST_SOMETHING and you should be good.
Title: Re: CRPL related questions
Post by: Flabort on January 18, 2014, 02:25:24 PM
...quotes around the CONSTs.  ::) I should have known, thank you so much. It works perfectly now.  ;D
Title: Re: CRPL related questions
Post by: jakeflee on January 20, 2014, 12:47:06 AM
is there a way to make a button on the screen i don't see a draw pixel like functions only camera and image functions but i don't want to use an image function->
Title: Re: CRPL related questions
Post by: Clean0nion on January 20, 2014, 03:03:23 AM
Quote from: jakeflee on January 20, 2014, 12:47:06 AM
is there a way to make a button on the screen i don't see a draw pixel like functions only camera and image functions but i don't want to use an image function->
You can't put a custom image on the screen without using an image function.
Title: Re: CRPL related questions
Post by: jakeflee on January 20, 2014, 05:48:19 PM
dam ok
Title: Re: CRPL related questions
Post by: eduran on January 21, 2014, 05:41:42 AM
Say you have two scripts, parent and child. Parent is attached to a CRPL core, creates a new core and attaches child to that new core. Obviously parent will execute before child on the first frame, because child only exists if parent was executed at least once. But what happens now? Will parent always execute first or can the order switch around?
Title: Re: CRPL related questions
Post by: Clean0nion on January 21, 2014, 08:54:05 AM
Quote from: eduran on January 21, 2014, 05:41:42 AM
Say you have two scripts, parent and child. Parent is attached to a CRPL core, creates a new core and attaches child to that new core. Obviously parent will execute before child on the first frame, because child only exists if parent was executed at least once. But what happens now? Will parent always execute first or can the order switch around?
I suppose it depends entirely on the length of the script.
Title: Re: CRPL related questions
Post by: Relli on January 21, 2014, 01:49:12 PM
Quote from: eduran on January 21, 2014, 05:41:42 AM
Say you have two scripts, parent and child. Parent is attached to a CRPL core, creates a new core and attaches child to that new core. Obviously parent will execute before child on the first frame, because child only exists if parent was executed at least once. But what happens now? Will parent always execute first or can the order switch around?
I would have to assume that they happen simultaneously. If they in some way rely on each other frame-by-frame, like one changing the details of the other, then I couldn't say for certain when the change would take effect. Though you might be able to set up a trace log thing that would show you for certain.
Title: Re: CRPL related questions
Post by: eduran on January 21, 2014, 02:31:04 PM
To add some context to why I am even asking:
I created a custom unit, the Creeper Tunnel. For the player it looks like two cores (with custom images) connected by a line. This line is an image added to one of the cores, stretched and rotated to connect the two. The core that has the line attached checks the position of both cores and does the strechtching and rotating. Works like a charm.
Then I allowed the cores to move around. At that point I noticed that the line was slightly trailing one of the cores (the one that didn't draw the line). Instead of connecting to the center it connected to where its center was the last frame. Using GetUnitAttribute(<-otherCoreUID CONST_PIXELCOORDX/Y) actually returns x/y values corresponding to otherCore's position during the previous frame. If I run that command on both cores and trace the result, they are different.
At least they were until I deleted both cores, placed them again and added the scripts in a different order (core without line first, core with line second). Doing that, the script works as intended. Adding the scripts in reverse order causes the 'bug' I described. Looks like a text-book race condition.

I guess what I need to know is: is it 'save' to make a map like this, finalize and upload it? Will it run on everyone's machines if I've got the order right on mine? Or can the same bug pop up randomly on other computers/times of day/phases of the moon?
Title: Re: CRPL related questions
Post by: Grauniad on January 21, 2014, 02:44:31 PM
One of the reasons I'm against these Omnibus threads is that Virgil doesn't always look at later posts in a thread. People here have a tendency to drag topics off-line and then continue them ad-infinitum. If you want to ask a question that Virgil is best positioned to answer, then start your own thread with a topic title that pertains to the question.

My take is that it may depend on a number of factors and I just don't know, apart from that the order of execution has never been explicitly defined.
Title: Re: CRPL related questions
Post by: knucracker on January 21, 2014, 03:59:48 PM
The execution order of units is the order of this Unity API:
FindGameObjectsWithTag

And that is basically undefined.  This means you can't rely on the order of execution with a given frame.  Save/Load could also perturb the order along with unit creation and destruction.
Now I could probably make the execution order be defined.  The order would always be latter units execute later than earlier units (creation order).  This would introduce a small performance loss, though, and of course would only show up in future builds.
Title: Re: CRPL related questions
Post by: knucracker on January 21, 2014, 06:42:20 PM
Actually... let's try this for the next build.  Unit updating per frame will be done from oldest to youngest.  This is based off of the unit UID.  Basically the unit UID is an int and this int only ever goes up as units are created.  Updating happens on a sorted list of these units per frame.

There should be a very slight performance degradation that should be worse the more units that are on a map.  But I doubt it will ever be noticed as it will be a tee-tiny fraction of what is going on in the game.

So try the upcoming 165 build and see if everything seems ok with this...
Title: Re: CRPL related questions
Post by: eduran on January 22, 2014, 05:50:09 AM
Wow, that was fast. I did some quick tests and everything seems to work as you described. With 1.64 I am sometimes able to change the execution order by saving/reloading and by just having stuff happen (not sure what exactly caused it). In 1.65 it is unperturbed by anything I tried to mess it up. Now I just hope that doesn't ruin the frame rate on lower end machines.

Quote from: Grauniad on January 21, 2014, 02:44:31 PM
One of the reasons I'm against these Omnibus threads is that Virgil doesn't always look at later posts in a thread. People here have a tendency to drag topics off-line and then continue them ad-infinitum. If you want to ask a question that Virgil is best positioned to answer, then start your own thread with a topic title that pertains to the question.
Yes, sorry about that. I didn't have much time when I first posted the question and just threw it in here. Making a separate thread would have been better.
Title: Re: CRPL related questions
Post by: Grauniad on January 30, 2014, 01:09:51 PM
I'm now locking this topic. Please ask each question in a separate thread. It makes finding things a lot easier.