Knuckle Cracker

Creeper World 3 => The Coder's Corner => Topic started by: Grauniad on December 20, 2012, 12:31:44 PM

Title: Official CRPL examples
Post by: Grauniad on December 20, 2012, 12:31:44 PM
Please submit all new/future contributions to the wiki (http://knucklecracker.com/wiki/doku.php?id=crpl:crpltutorial:code_examples).

This thread contains CRPL code examples. Feel free to offer your own examples by posting them in a reply. If we accept them, they will be incorporated in the main body. If not, they will be deleted without comment. For consideration, please make sure that all steps are well documented.

Discussion of any examples should happen in a different thread. Non-relevant posts on this thread will be summarily removed.

Ex 1: Contributor: VirgilW
Purpose: Creates 10 units of Creeper every second at the unit's coordinates.

# Creates 10 units of Creeper every second at the units coordinates.
CurrentCoords 10 SetCreeper
30 Delay



Ex 2: Contributor: VirgilW
Purpose:

# Makes a runner at the units current coordinates every three seconds, but only if there is digitalis underneath.
# The runner moves at speed 2, has a health of 10, and carries 20 units of Creeper as a payload.
CurrentCoords GetDigitalis
if
  CurrentCoords 2 10 20 CreateRunner
  90 Delay
endif


Ex 3: Contributor: VirgilW
Purpose:

# Show the trace log, clear it, then show the numbers 0 through 9 in the log
ShowTraceLog
ClearTraceLog
5 0 do
  I Trace
loop


Ex 4: Contributor: VirgilW
Purpose:

#Emit Creeper along a line 5 cells wide and centered over the unit.
CurrentX 3 add CurrentX 2 sub
do
  I CurrentY 10000000 SetCreeper
loop



Ex 5: Contributor: VirgilW
Purpose:

#Emit Creeper over a 5x5 area centered on unit.
CurrentY 3 add CurrentY 2 sub
do
  CurrentX 3 add CurrentX 2 sub
  do
     I J 10 SetCreeper
  loop
loop


Ex 6: Contributor: VirgilW
Purpose:


# Fills the map with 1000 walls of varying health each game loop.
# The outer loop iterates 1000 times (hence the 1000 walls per game loop).
# Inside the loop, random map coordinates are chosen.
# Then, a random float is chosen to serve as the wall's health.
1000 0 do
  RandCoords RandFloat SetWall
loop


Ex 7: Contributor: VirgilW
Purpose:


# Creates a random wall 'matrix' pattern in the upper left hand corner of the map.
# When, and only when, the unit is destroyed emit 9 cells (a 3x3 grid) over the unit filled with the maximum amount of Creeper a cell can hold.
0 10 RandInt 0 10 RandInt RandFloat SetWall

:destroyed
CurrentY 2 add CurrentY 1 sub do
CurrentX 2 add CurrentX 1 sub do
I J 2000 SetCreeper
loop
loop


Ex 8: Contributor: VirgilW
Purpose:

# Mr. Evil to Zorg...
# Useless for gameplay, but interesting to look at.
10000 0 do
  CurrentCoords 50 RandCoordsInRange RandFloat 2000 mul
  SetCreeper
loop



Ex 9: Contributor: VirgilW
Purpose:


# Create a wandering emitter.  
# The emitter leaves a Creeper trail as it moves around.
# Whenever it changes directions, it leaves a pool of creeper.
# When destroyed, it emits a bunch of Creeper and fires spores at player units.

# Setup an initial movement.  
# This is so we don't leave a pool
# of Creeper on the first movement.
once
  RandCoords swap 2 div swap 1 QueueMove
endonce

# If the current movement queue is empty, pick a new spot to move to.
GetQueuedMoveCount eq0 if
  # We will move randomly around on the left side of the map.
  # So we pick Random Coordinates, but then divide
  # the X coordinate by 2 so it is on the left side of the map.
  RandCoords swap 2 div swap 1 QueueMove
 
  # Leave a pool of Creeper since we are changing
  #directions and moving to a new spot.
  CurrentCoords 100 AddCreeper
endif

# We want to leave a trail of Creeper behind.  So we emit 2 Creeper every 10 frames
GetTimer0 eq0 if
  CurrentCoords 2 AddCreeper
  10 SetTimer0
endif

# When Destroyed, emit a bunch of Creeper and choose 5 units and fire spores at them.
:destroyed
CurrentCoords 1000 AddCreeper
5 0 do
  CurrentCoords RandUnitCoords 1 20 CreateSpore
loop


Ex 10: Contributor: VirgilW
Purpose:


# Make a tower that moves around randomly leaving both a
# Creeper and a Digitalis trail.  Also deposits up to 10
# Runners as it moves.

GetQueuedMoveCount eq0 if
  RandCoords 3 QueueMove
endif

CurrentCoords 2 SetCreeper

CurrentY 2 add CurrentY 1 sub do
  CurrentX 2 add CurrentX 1 sub do
     I J true SetDigitalisGrowth
     I J 1 SetDigitalis
  loop
loop

GetRunnerCount 10 lt if
  GetTimer0 eq0 if
     CurrentCoords 1 10 10 CreateRunner
     150 SetTimer0
  endif
endif


Ex 11: Contributor: VirgilW
Purpose:


#Makes the tower move between two points.
#The points are defined once and assigned to local variables.

once
  10 ->x1
  20 ->y1
  40 ->x2
  50 ->y2
endonce

#Check to see if we are moving. If not queue up a movement
GetQueuedMoveCount eq0 if
  #If we are at the first position, move to the second.  
  #Otherwise move to the first position.
  CurrentX <-x1 eq if
     <-x2 <-y2 1 QueueMove
  else
     <-x1 <-y1 1 QueueMove
  endif
endif


Ex 12: Contributor: VirgilW
Purpose:


# Draw a grid of walls with spaces between each cell.
# The grid deposits 10 wall segments per frame.
once
  0 ->x
  0 ->y
  0 ->counter
  1 ->level
endonce

while
  <-y 50 lt
repeat
  <-x <-y <-level SetWall

  <-x 2 add ->x
  <-x 50 gt if
     0 ->x
     <-y 2 add ->y
  endif

  <-counter 10 gt if
     0 ->counter
     break
  endif
  <-counter 1 add ->counter
endwhile

<-y 50 gte if
  0 ->y
  <-level 0.2 add 1 mod ->level
endif


Ex: 13 Contributor: VirgilW
Purpose: Demonstrate function support.


# --- Main Body ---------------------
10 @emit

1 @chance if
  100 @relocate  #Move quickly
endif
#--------------------------------------

# --- Emit Creeper ---------------------
# --- Only emit creeper while not moving.
# --- [ Amt -- ]
:emit
->amt   #Grab the amount from the stack and store it in a var
GetQueuedMoveCount eq0 if
  CurrentCoords <-amt SetCreeper
endif
#--------------------------------------

# --- Relocate -------------------------
# --- Move  to a new location.
# --- [Speed -- ]
:relocate
->speed   #Grab the speed from the stack and store it in a var
RandCoords <-speed QueueMove

#--------------------------------------

# --- Roll a 100 sided die--------------
# --- Return true or false randomly.
# --- The value on the stack is the percentage chance.
# --- [ Chance_in_100 -- true/false]
:chance
# Take an item from the stack, divide by 100,
# then compare to a random float.
100.0 div RandFloat gt
#--------------------------------------
Title: Re: Official CRPL examples
Post by: knucracker on January 19, 2013, 01:48:21 PM
Image spinner.  Specify a rate and which image to rotate.  Positive rotation rates are counterclockwise and the rotation rate is in radians per frame.

$rotationRate:0.1
$imageToRotate:"main"

# Make a part spin around
Self <-imageToRotate GetImageRotation ->currentRotation
<-currentRotation <-rotationRate add ->currentRotation
Self <-imageToRotate <-currentRotation SetImageRotation

# This version is more terse and more efficient, but harder to read.
#Self <-imageToRotate Self <-imageToRotate GetImageRotation <-rotationRate add SetImageRotation



Alpha blink.  Can be used for making a blinking light.  Changes the transparency of an image from fully transparent to fully opaque in a cycle.  The red, green, and blue values can be used to tint the color of the image.

$name:"light"
$customImageName:"custom0"
$red:255
$green:255
$blue:255
$rate:10
$active:1

once
self <-name <-customImageName SetImage
self <-name -0.01 SetImagePositionZ
endonce



<-active if
<-alpha 0 lt if
0 ->alpha
<-rate abs ->rate
else
<-alpha 255 gt if
255 ->alpha
<-rate abs -1 mul ->rate
endif
endif

<-alpha <-rate add ->alpha

self <-name <-red <-green <-blue <-alpha SetImageColor
else
self <-name 0 0 0 0 SetImageColor
endif
Title: Re: Official CRPL examples
Post by: Grauniad on January 19, 2013, 01:52:23 PM
You can modify posts yourself. Feel free to put them up top where they belong. Saves me the editing. Next time. Now I'll just delete my two posts above and all will be hunky dory.
Title: Re: Official CRPL examples
Post by: Grauniad on January 19, 2013, 01:52:34 PM
More code examples
Title: Re: Official CRPL examples
Post by: Grauniad on January 19, 2013, 01:53:22 PM
Even more code examples (Hope springs eternal)
Title: Re: Official CRPL examples
Post by: J on February 05, 2013, 02:07:47 PM
# moves the core in a circle around x and y with a set speed
# ------------------------------------------
$speed:1
$size:16
$x:32
$y:32
$precision:0.2
once
0.0 ->step
endonce
GetQueuedMoveCount eq0 if
<-step cos <-size mul <-x add <-step sin <-size mul <-y add <-speed QueueMove
<-step <-precision add ->step
endif


Creates a moving wall of creeper.
You can adjust the speed of the wall, the amount of creeper it creates, the initial delay and if the wall should release all creeper after reaching the right side of the map, repeat with the creeper still in the wall or release all creeper and repeat from the left side (without creating any more creeper).

EDIT: I've updated to code, you can now keep other creeper out of the moving wall. If you have any ideas of features I could add to this script, please PM me. Also, it might not be a good idea to use this on high maps (wide no problem), as this script uses 50-100 opcodes/frame/mapheight, and 75-200 more when it moves (haven't counted them, 236 opcodes total).

# MoveWall.crpl
# Created on: 2/4/2013 8:00:55 PM
# Author: J
# This script creates a wall of creeper on the left side of the map that moves forward every x frames
# You may choose in-game if the wall should keep going or release the creeper at the end
# If RepeatAtEnd=2 the creeper is released at the right side of the map while a new (empty) wall will run over the map
# If you choose to enable KeepCreeperOut, it will try to keep all other creeper out of the wall
# Spacing is the number of cells the KeepCreeperOut will keep 100% clean of creeper
# ------------------------------------------
$MoveDelay:30
$InitialWallHeight:500
$InitialDelay:0
$RepeatAtEnd:1
$KeepCreeperOut:1
$Spacing:1

once
<-InitialDelay Delay false ->stop 0 ->stepx <-MoveDelay ->stept
MapHeight 0 do 0 I <-InitialWallHeight SetCreeper loop
endonce

<-stop not if
MapHeight 0 do
#move creeper back from the left side
<-stepx neq0 if
<-stepx I <-stepx 1 sub I GetCreeper AddCreeper
<-stepx 1 sub I 0 SetCreeper
endif
#move creeper back from the right side
<-stepx MapWidth 1 sub neq if
<-stepx I <-stepx 1 add I GetCreeper AddCreeper
<-stepx 1 add I 0 SetCreeper
endif
<-KeepCreeperOut if
#keep creeper out of the wall, left side
<-stepx 3 gte if
<-stepx 3 sub <-Spacing sub I <-stepx 2 sub <-Spacing sub I GetCreeper AddCreeper
<-stepx 2 sub <-Spacing sub I 0 SetCreeper
endif
#keep creeper out of the wall, right side
<-stepx <-Spacing add MapWidth 4 sub lte if
<-stepx 3 add <-Spacing add I <-stepx 2 add <-Spacing add I GetCreeper AddCreeper
<-stepx 2 add <-Spacing add I 0 SetCreeper
endif
endif
loop

<-stept 1 sub ->stept
#move creeper forward if stept is 0
<-stept eq0 if
<-stepx MapWidth 1 sub eq if
<-RepeatAtEnd eq0 if
true ->stop
endif
<-RepeatAtEnd neq0 if
<-MoveDelay ->stept
0 ->stepx
<-RepeatAtEnd 1 eq if
MapHeight 0 do
0 I MapWidth 1 sub I GetCreeper AddCreeper
MapWidth 1 sub I 0 SetCreeper loop
endif
endif
else
<-MoveDelay ->stept
MapHeight 0 do
#move the creeper in the wall forward
<-stepx 1 add I <-stepx I GetCreeper AddCreeper
<-stepx I 0 SetCreeper
#move the creeper in front of the wall forward
<-KeepCreeperOut if
<-stepx <-Spacing add MapWidth 5 sub lte if
<-stepx 4 add <-Spacing add I <-stepx 3 add <-Spacing add I GetCreeper AddCreeper
<-stepx 3 add <-Spacing add I 0 SetCreeper
endif
endif
loop
<-stepx 1 add ->stepx
endif
endif
endif

Old Code

# MoveWall.crpl
# Created on: 2/4/2013 8:00:55 PM
# Author: J
# This script creates a wall of creeper on the left side of the map that moves forward every x frames
# You may choose in-game if the wall should keep going from the left side or release the creeper at the end
# If RepeatAtEnd=2 the creeper is released at the right side of the map while a new (empty) wall will run over the map
# ------------------------------------------
$MoveDelay:30
$InitialWallHeight:1000
$InitialDelay:0
$RepeatAtEnd:1

once
<-InitialDelay Delay false ->stop 0 ->stepx <-MoveDelay ->stept
MapHeight 0 do 0 I <-InitialWallHeight SetCreeper loop
endonce

<-stop not if
MapHeight 0 do
#move creeper back from the left side
<-stepx neq0 if
<-stepx I <-stepx 1 sub I GetCreeper AddCreeper <-stepx 1 sub I 0 SetCreeper
endif
#move creeper back from the right side
<-stepx MapWidth neq if
<-stepx I <-stepx 1 add I GetCreeper AddCreeper <-stepx 1 add I 0 SetCreeper
endif
loop

<-stept 1 sub ->stept
#move creeper forward if stept is 0
<-stept eq0 if
<-stepx MapWidth 1 sub eq if
<-RepeatAtEnd eq0 if
true ->stop
endif
<-RepeatAtEnd neq0 if
<-MoveDelay ->stept
0 ->stepx
<-RepeatAtEnd 1 eq if
MapHeight 0 do
0 I MapWidth 1 sub I GetCreeper AddCreeper MapWidth 1 sub I 0 SetCreeper loop
endif
endif
else
<-MoveDelay ->stept
MapHeight 0 do
<-stepx 1 add I <-stepx I GetCreeper AddCreeper <-stepx I 0 SetCreeper loop
<-stepx 1 add ->stepx
endif
endif
endif
[close]

The next piece of code can remove ALL ammo from the nearest unit (if in range). It doesn't matter if it's energy or AC, all ammo will be removed. This also is a good example for unit attributes.

#Remove all ammo from the nearest unit within range

$KillAmmo:1      #you can turn it off in-game
$AmmoRange:15

<-KillAmmo neq0 if
<-AmmoRange ->range
@GetClosestUnit
<-closestUnit neq0 if
<-closestUnit CONST_AMMO GetUnitAttribute neq0 if
<-closestUnit CONST_AMMO 0 SetUnitAttribute
endif
<-closestUnit CONST_AMMOAC GetUnitAttribute neq0 if
<-closestUnit CONST_AMMOAC 0 SetUnitAttribute
endif
endif
endif

: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


Time for another piece of code
This will make the tower move at the edge of the map slowly creating more digi growth area:

#This script make the tower move around the edge of the map
#It will create more D growth area as it moves
#Works on all maps, creates D growth area faster on larger maps

$movespeed:1

once
1 ->x1
1 ->y1
MapWidth 2 sub ->x2
1 ->y2
MapWidth 2 sub ->x3
MapHeight 2 sub ->y3
1 ->x4
MapHeight 2 sub ->y4
0 MapWidth do
"DX" I concat 0 ->!
loop
0 MapHeight do
"DY" I concat 0 ->!
loop
endonce

#Create D and growth area on current position
CurrentY 2 add CurrentY 1 sub do
CurrentX 2 add CurrentX 1 sub do
I J true SetDigitalisGrowth
I J 1 SetDigitalis
loop
loop

# Add even more D growth area
CurrentX 1 gt CurrentX MapWidth 2 sub lt and if
RandFloat 0.99 MapHeight asfloat 1000 div sub gt if
"DX" CurrentX concat <-! ->numb
CurrentY 3 lt if
CurrentX <-numb 1 SetDigitalisGrowth
else
CurrentX MapHeight <-numb sub 1 SetDigitalisGrowth
endif
<-numb 1 add "DX" CurrentX concat ->!
endif
endif
CurrentY 1 gt CurrentY MapHeight 2 sub lt and if
RandFloat 0.99 MapWidth asfloat 1000 div sub gt if
"DY" CurrentY concat <-! ->numb
CurrentX 3 lt if
<-numb CurrentY 1 SetDigitalisGrowth
else
MapWidth <-numb sub CurrentY 1 SetDigitalisGrowth
endif
<-numb 1 add "DY" CurrentY concat ->!
endif
endif

#Check for a queued movement
GetQueuedMoveCount eq0 if
#queue moves
<-x2 <-y2 <-movespeed QueueMove
<-x3 <-y3 <-movespeed QueueMove
<-x4 <-y4 <-movespeed QueueMove
<-x1 <-y1 <-movespeed QueueMove
endif


And another piece of code to create runners randomly:

# runnerpower<3600: it will wait (3600-runnerpower) frames before creating any runners
# runnerpower>3600: First runner is extra strong

$runnerpower:0

#Create runners
<-runnerpower 1 add ->runnerpower
0 GetRunnerCount 5 add RandInt eq0 <-runnerpower 3600 gt and if
CurrentCoords 0.9 <-runnerpower 3598 sub 3 div <-runnerpower 3600 sub CreateRunner
3600 ->runnerpower
endif
Title: Re: Official CRPL examples
Post by: albrittbrat on October 18, 2013, 02:53:35 AM
I hope it's alright for non-beta and non-mod users to post example scripts here, if not just delete this post.

Create an emitter that increases its output rate over time

#Program to ramp creeper deployment rate over time
#Time is in seconds
#-------------------------------------------------------------------------
$BaseRate:25
$MaxRate:150
$RampTime:600
$NumIncrements:100
$DeployRate:15
once
<-BaseRate ->CRate
0 SetTimer0
<-RampTime 30 mul ->RampTime
<-RampTime <-NumIncrements div 0 round ->TimerRate
endonce
#If the queue is empty, queue next move
#Drop AC based on input parameters
GetTimer0 eq0 if
@DetermineCAmount
endif
CurrentCoords <-CRate SetCreeper
<-DeployRate Delay
#Function to determine amount of creeper to drop
#Range goes from BaseRate to MaxRate
:DetermineCAmount
<-CRate <-MaxRate lte if
<-CRate 1 add ->CRate
<-TimerRate SetTimer0
endif
#End DetermineCAmount Function
Title: Re: Official CRPL examples
Post by: Grauniad on October 18, 2013, 07:46:55 AM
We are happy to accept community contributions. Thank you.

We would also be delighted if you could add them to the wiki page for code examples (http://knucklecracker.com/wiki/doku.php?id=crpl:crpltutorial:code_examples).
Title: Re: Official CRPL examples
Post by: Xindaris on October 24, 2013, 11:16:46 AM
# HydraEmitter.crpl
# A basic emitter at first.
# Creates an emitter which spawns new emitters in random locations within a defined range when it dies, which themselves also spawn new emitters.
# Note that the decay rates are multiplied, so in theory you could make them bigger than 1 and have the rate/amount/range increase with each death rather than decrease.
# Note also, the spawn code checks to make sure it's not spawning on void. You can comment out that line if you want it to spawn in void, but be careful to not spawn outside of the map!
# ------------------------------------------
$rate:15
$amount:100
$rateDecay:1.0
$amountDecay:.5
$newHeads:3
$headLossPerDeath:1
$headRange:100
$headRangeDecay:.80

CurrentCoords <-amount AddCreeper
<-rate Delay

:destroyed
0 ->count
while <-count lt(<-newHeads) repeat
CurrentCoords <-headRange RandCoordsInRange ->deathX ->deathY
if(<-deathX <-deathY GetVoid not)
"CRPLCORE" <-deathX <-deathY CreateUnit ->currUnit
<-currUnit "main" "CustomEmitter" SetImage
<-currUnit "HydraEmitter.crpl" AddScriptToUnit
<-currUnit "HydraEmitter.crpl" "rate" <-rate mul(<-rateDecay) SetScriptVar
<-currUnit "HydraEmitter.crpl" "amount" <-amount mul(<-amountDecay) SetScriptVar
<-currUnit "HydraEmitter.crpl" "rateDecay" <-rateDecay SetScriptVar
<-currUnit "HydraEmitter.crpl" "amountDecay" <-amountDecay SetScriptVar
<-currUnit "HydraEmitter.crpl" "newHeads" <-newHeads sub(<-headLossPerDeath) SetScriptVar
<-currUnit "HydraEmitter.crpl" "headLossPerDeath" <-headLossPerDeath SetScriptVar
<-currUnit "HydraEmitter.crpl" "headRange" <-headRange mul(<-headRangeDecay) SetScriptVar
<-currUnit "HydraEmitter.crpl" "<-headRangeDecay" <-headRangeDecay SetScriptVar
<-count add(1) ->count
endif
endwhile


Hopefully this will be useful to somebody. Can't seem to find the edit button on the wiki.
Title: Re: Official CRPL examples
Post by: Grauniad on October 24, 2013, 11:34:27 AM
Quote from: Xindaris on October 24, 2013, 11:16:46 AM
Can't seem to find the edit button on the wiki.

This button is not visible?
(http://knucklecracker.com/forums/index.php?action=dlattach;topic=12255.0;attach=15763;image)
Title: Re: Official CRPL examples
Post by: Xindaris on October 24, 2013, 04:57:57 PM
I had a magnifying glass leading to a read-only version of the source, but then it occurred to me to try and log in, and now it's quite visible. Sorry about that.
Title: Re: Official CRPL examples
Post by: Grauniad on October 24, 2013, 05:38:13 PM
I forgot one had to be logged in.. :)
Title: Re: Official CRPL examples
Post by: eduran on October 25, 2013, 11:25:50 AM
Something I coded after unsuccessfully trying to get AscendToOrbit to work:

# Ascend.crpl
# Created on: 10/25/2013 4:05:03 PM
# ------------------------------------------

#Script to make a unit look like it is ascending to orbit.
$duration:60 #ascend duration in frames
$destroy:1  #if set to 1 the unit is destroyed after ascension
#if set to 0 it is just hidden by setting all image slots to "NONE"
$playSound:1

once
CreateList ->ImageSlots
#########################################################################
#add the name of all image slots of your unit here (usually just "main"):
"main"
"AdditionalImage1"
"AdditionalImage2"


#########################################################################
AppendStackToList(<-ImageSlots)
0 ->counter
if(<-playSound)
PlaySound("UnitTakeOff")
endif
endonce

<-counter mul(0.025) mul(60) div(<-duration) add(1) ->scale
<-counter mul(60) div(<-duration) ->position
do(GetListCount(<-ImageSlots 0))
SetImagePositionY(Self GetListElement(<-ImageSlots I)  <-position)
SetImageScale(Self GetListElement(<-ImageSlots I) <-scale <-scale)
loop
<-counter add(1) ->counter
if(gte(<-counter <-duration))
if(<-destroy)
Destroy(Self 0)
else
do(GetListCount(<-ImageSlots 0))
SetImage(Self GetListElement(<-ImageSlots I) "NONE")
loop
SetUnitAttribute(Self CONST_TAKEMAPSPACE 0)
endif
endif
Title: Re: Official CRPL examples
Post by: Tistel on October 25, 2013, 01:32:40 PM
Hi there are no need to write AscendToOrbit it already exists.
(found in Notepad++ autocomplete file)

[edit]
Tested a bit more.
It looks like AscendToOrbit only work ok after DropFromOrbit, it ascends from the cell it droped on (or lower left corner if not)


Example of an unit that lands and take off again

# visit.crpl
# Created on: 10/25/2013 7:18:48 PM
# ------------------------------------------

once
 SetUnitAttribute(Self CONST_COUNTSFORVICTORY False)
 SetUnitAttribute(Self CONST_CREATEPZ False)
 DropFromOrbit(CurrentCoords)
 SetTimer0(110)
endonce

GetTimer0 eq0 if
 once
   AscendToOrbit
 endonce
endif
Title: Re: Official CRPL examples
Post by: knucracker on October 25, 2013, 02:16:37 PM
There was a bug in AscendToOrbit that I just fixed in the last few hours.  I will be doing an updated build shortly (probably this weekend) and will make it available on the forums in an open beta.  That should have the fix....
Title: Re: Official CRPL examples
Post by: eduran on November 04, 2013, 07:08:49 AM

# BorderSpores.crpl
# Created on: 11/2/2013 6:48:09 PM
# ------------------------------------------
# This script tries to emulate CW1 spores. Spores spawn in random cells along the edge of the map and target random
# player units. The script also includes a warning indicator similar to the one spore towers create.


# map borders that are allowed to spawn spores are set below
# 0 means no spawn from that direction; has to be either 0 or 1
# at least one side has to be set to 1
$left:1
$right:1
$top:1
$bottom:1

# spore settings
$initialDelay:9000 # time before the first wave spawns in frames (1800 frames = 1 minute)
$nOfSpores:5 # number of spores spawned per interval
$interval:1800 # time between wave spawns in frames
$delay:30 # time between individual spores within a wave
$payload:10 # amount of creeper each spore carries
$health:1 # health of the spores; default is 1

# warning settings
$backgroundImg:"Custom0_256" # image slot for the red background of the warning message
$displayWarningTime:1800 # from this time point of the countdown onward the warning message is displayed (-1 to deactivate)
$playSoundTime:1800 # at this point of the countdown the warning sound is played (-1 to deactivate)
$alternativeMode:0 # set to 1 if you want to use this script and spore towers at the same time to avoid
# overlap of warning messages
$sound:"Misc19" # warning sound
$backgroundScaleX:29.15 # parameters to tweak the background image
$backgroundScaleY:8
$backgroundPosX:61.5

$name:"BorderSporeSpawner" # allows other CRPL cores to find the spawner by using GetCoresWithVar

once
@Setup
SetTimer0(<-initialDelay)
0 ->counter
0 ->soundPlayed
endonce

# check if spores need to be spawned
if(GetTimer0 eq0 and(GetTimer1 eq0))
if(<-counter lt(<-nOfSpores))
if (<-delay gt(0))
# create one spore and wait for the delay
@PickOrigin
@PickTarget
CreateSpore(<-originX <-originY <-targetX <-targetY <-health <-payload)
<-counter add(1) ->counter
SetTimer1(<-delay)
else
# create all spores at once
do(<-nOfSpores 0)
@PickOrigin
@PickTarget
CreateSpore(<-originX <-originY <-targetX <-targetY <-health <-payload)
loop
<-nOfSpores ->counter
endif
PlaySound("SporeFire")
else
# all spores spawned, reset timer and warning
SetTimer0(<-interval)
0 ->counter
0 ->soundPlayed
@DeactivateWarning
endif
endif

# display warning message
if(<-warningActive)
if(GetTimer0 mod(30) eq0)
@SetWarningText
endif
else
if(GetTimer0 lt(<-displayWarningTime))
@ActivateWarning
endif
endif

# play warning sound
if(not(<-soundPlayed) and(GetTimer0 lt(<-playSoundTime)))
1 ->soundPlayed
PlaySound(<-sound)
endif

:PickOrigin
# picks a random cell at the edge of the map
GetListElement(<-Sides RandInt(0 GetListCount(<-Sides))) ->side
if(<-side eq("left") or(<-side eq("right")))
RandInt(0 MapHeight) ->originY
if(<-side eq("left"))
0 ->originX
else
MapWidth ->originX
endif
else
RandInt(0 MapHeight) ->originX
if(<-side eq("top"))
0 ->originY
else
MapHeight ->originY
endif
endif

:PickTarget
# picks a random player unit as target, or a random cell if no unit is present
CreateList ->Targets
GetUnitsInRange(0 0 9999) ->nOfTargets
AppendStackToList(<-Targets)
GetListElement(<-Targets RandInt(0 <-nOfTargets)) ->target
if(<-target neq0)
GetUnitAttribute(<-target CONST_COORDY) ->targetY
GetUnitAttribute(<-target CONST_COORDX) ->targetX
else
RandCoords ->targetY ->targetX
endif

:ActivateWarning
# enables the red warning strip right above the build menu
if(not(<-warningActive))
SetImageColor(Self "background" 255 0 0 255)
@SetWarningText
1 ->warningActive
endif

:DeactivateWarning
# disables the red warning strip right above the build menu
if(<-warningActive )
SetImageColor(Self "background" 255 0 0 0)
SetText("")
0 ->warningActive
endif

:SetWarningText
# converts timer into text
GetTimer0 div(1800) ->minutes
GetTimer0 mod(1800) div(30) ->seconds
if(<-seconds lt(10))
"0" concat(<-seconds) ->seconds
endif
SetText(<-nOfSpores concat(" spore(s) in ") concat(<-minutes) concat(":") concat(<-seconds))

:Setup
# one-time setup for everything
SetUnitAttribute(Self CONST_COUNTSFORVICTORY 0)
SetUnitAttribute(Self CONST_TAKEMAPSPACE 0)
SetUnitAttribute(Self CONST_NULLIFIERDAMAGES 0)
# the following lines anchor the CRPL core to the top of the build menu
SetScreenMode(true)
SetScreenPixelCoordX(ScreenWidth div(2) sub(62))
if(<-alternativeMode)
SetScreenPixelCoordY(130)
else
SetScreenPixelCoordY(110)
endif
# configures text size and position, but does not display anything yet
SetText("")
SetTextSize(0.6)
SetTextColor(255 255 255 255)
SetTextAnchor("MiddleLeft")
# same for the text background
SetImage(Self "main" "NONE")
SetImage(Self "background" <-backgroundImg)
SetImageScale(Self "background" <-backgroundScaleX <-backgroundScaleY)
SetImagePositionX(Self "background" <-backgroundPosX)
SetImageColor(Self "background" 255 0 0 0)
# create a list of valid spawn locations, needed for @PickOrigin
<-left add(<-right) add(<-top) add(<-bottom) ->sideCount
CreateList ->Sides
if(<-left eq(1))
AppendToList(<-Sides "left")
endif
if(<-right eq(1))
AppendToList(<-Sides "right")
endif
if(<-top eq(1))
AppendToList(<-Sides "top")
endif
if(<-bottom eq(1))
AppendToList(<-Sides "bottom")
endif


CW1 spores, spawning at the edge of the map instead of at a tower. Includes a warning message similar to the build-in one.
(http://knucklecracker.com/forums/index.php?action=dlattach;topic=12255.0;attach=15953)
Title: Re: Official CRPL examples
Post by: jakeflee on January 19, 2014, 07:40:07 PM
radar makes a radar circle using creeper or anticreeper i would use a small amount of creeper
$xcoord:128
$ycoord:128
$amount:-.3
$d:5
$radmax:100

once
pi 180 div ->radcon
endonce

0 ->ang

while <-ang 360 lte repeat

<-ang <-radcon mul ->rads
<-ang 1 add ->ang
1 ->radius

while <-radius <-radmax lte repeat
<-rads sin ->xucirc
<-rads cos ->yucirc
<-xucirc <-radius mul ->xrad
<-yucirc <-radius mul ->yrad
<-xrad <-xcoord add ->xccoord
<-yrad <-ycoord add ->yccoord

<-radius 1 add ->radius
<-xccoord <-yccoord <-amount addcreeper
endwhile
<-d delay
endwhile


i like to break up my equations like this so don't pester me about that
Title: Re: Official CRPL examples
Post by: Flabort on February 03, 2014, 07:19:53 PM
After it's been used in a few maps, and Tek accidentally grabbed a version with a shield-key atached, I figured I should move this here:
The Flip-Emitter, V2.2
# 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
Title: Re: Official CRPL examples
Post by: Grauniad on February 03, 2014, 07:24:22 PM
Thank you for your contribution., It is indeed excellent.

The preferred location for code examples is the wiki.
Title: Spore Beacon - simple code exampe
Post by: First on February 10, 2014, 05:04:09 PM
Purpose: This tower attracts spores from the ether that detonate on the tower - a kind of emitter that can be defended against using beam weapons.
Illustrates timers, CreateSpore and RandCoordsInRange

$Range:50.0
$Payload:1000
$IntervalSeconds:2

once
#random start time between 1 and 2 intervalseconds
<-IntervalSeconds 30 mul <-IntervalSeconds 30 mul 2 mul RandInt SetTimer0
endonce

GetTimer0 eq0 if

CurrentCoords <-Range RandCoordsInRange CurrentCoords 1 <-Payload CreateSpore
<-IntervalSeconds 30 mul SetTimer0

endif
#delay might be better in this example
Title: Volcano - Simple Code Example
Post by: First on February 10, 2014, 05:12:21 PM
Purpose: Emulates an erupting volcano. Builds a cone by editing the local terrain. Emits spores land and detonate near the crater.
Illustrates timers, some coordinates API, Get/SetTerrain and basic flow control :)

# volcano.crpl
# Created on: 2/9/2014 2:13:15 PM
# Created by: First (jeffhfcotter@gmail.com)
# Defaults produce a fairly mild volcano that grows a cone and emits spore bombs
# ConeGrowthIntervalFrames is in game-frames
# SporeIntervalSeconds is in game-seconds
# ConeSize is a radius
# WTB: a better, more realistic looking cone growth algorithm
# WTB: <-xCurrent <-yCurrent <-Height GetNearestTerrain ->xNearest ->yNearest
#    Gets the location of nearest terrain that has height of Height
# WTB: cool looking crater image to replace the tower image
# ------------------------------------------
$ConeGrowthIntervalFrames:10
$ConeSize:10
$SporeIntervalSeconds:20
$SporeRange:20
$SporePayload:100

once
<-ConeGrowthIntervalFrames <-ConeGrowthIntervalFrames 2 mul RandInt SetTimer0
<-SporeIntervalSeconds 30 mul <-SporeIntervalSeconds 30 mul 2 mul RandInt SetTimer1
endonce

GetTimer0 eq0 if
0 ->CheckRange
while <-CheckRange <-ConeSize lt
repeat
CurrentCoords <-CheckRange RandCoordsInRange ->yTar ->xTar
CurrentCoords <-xTar <-yTar Distance ->Range
<-xTar <-yTar GetTerrain ->Height
10.0 <-Range 10.0 <-ConeSize div mul sub ->TargetHeight
<-TargetHeight <-Height gt if
<-xTar <-yTar <-Height 1 add SetTerrain
<-ConeSize ->CheckRange
else
<-CheckRange 1 add ->CheckRange
endif
endwhile
<-ConeGrowthIntervalFrames SetTimer0
endif

GetTimer1 eq0 if
CurrentCoords <-SporeRange RandCoordsInRange ->yTar ->xTar
CurrentCoords <-xTar <-yTar 1.0 <-SporePayload CreateSpore
<-SporeIntervalSeconds 30 mul SetTimer1
endif
Title: Re: Official CRPL examples
Post by: Grauniad on February 12, 2014, 10:22:59 AM
I am locking this topic. As with all multi-purpose threads, it  becomes increasingly more difficult to find specific contributions.  Please submit all future code examples to the wiki so that each contribution can have a header and a description and can be found without having to page through multiple pages of this thread.

Thank you.