CurrentCoords -10 AddCreeper
Delay 10
CurrentCoords 10 AddCreeper
Delay 10
SetTerrain
91 185 2
CurrentCoords -10 AddCreeper
Delay 10
CurrentCoords 10 AddCreeper
Delay 10
SetTerrain
88 188 2
CurrentCoords -10 AddCreeper
Delay 10
CurrentCoords 10 AddCreeper
Delay 10
SetTerrain
94 188 2
CurrentCoords -10 AddCreeper
Delay 10
CurrentCoords 10 AddCreeper
Delay 10
SetTerrain
91 191 2
CurrentCoords -10 AddCreeper
Delay 10
CurrentCoords 10 AddCreeper
Delay 10
SetVoid
91 185
CurrentCoords -10 AddCreeper
Delay 10
CurrentCoords 10 AddCreeper
Delay 10
SetVoid
88 188
CurrentCoords -10 AddCreeper
Delay 10
CurrentCoords 10 AddCreeper
Delay 10
SetVoid
94 188
CurrentCoords -10 AddCreeper
Delay 10
CurrentCoords 10 AddCreeper
Delay 10
SetVoid
91 191
I'm having trouble with this making the terrain move up and down all it does now is raise the terrain to level 10 in 3 of the 4 spots
You have to put up the arguments first.
So instead of:
Delay 10
SetTerrain
91 185 2
You'll have to write:
10 Delay
91 185 2 SetTerrain
Hope that helps
So, I modified it a bit.
First, I added a function for the repetitive part (the setcreeper part) to make the code a bit clearer.
Second, I used the warp operator. By the structure of your code, it looks like you're more familiar with the non-reverse notations, and the warp operator works very well for that :)
Overall, the code should be much smaller now and much easier to look at.
# ShadowDragon1.crpl
# Created on: 5/29/2013 2:06:17 PM
# Created by: ShadowDragon7015
# ---------------------------------
@spawnCreeper
SetTerrain(91 185 2)
@spawnCreeper
SetTerrain(88 188 2)
@spawnCreeper
SetTerrain(94 188 2)
@spawnCreeper
SetTerrain(91 191 2)
@spawnCreeper
SetVoid(91 185)
@spawnCreeper
SetVoid(88 188)
@spawnCreeper
SetVoid(94 188)
@spawnCreeper
SetVoid(91 191)
:spawnCreeper
CurrentCoords -10 AddCreeper
Delay(10)
CurrentCoords 10 AddCreeper
Delay(10)
It looks pretty cool when you put the creeplecore in the middle of the terraforming, kinda like a little factory of sorts. Neat stuff :)
Thanks Molay it worked perfectly!
i need to make this smaller and make it possible to change the variables multiple times in one CRPL core please help
$X:154
$Y:253
$RANGE:3
$UNITTYPE:"RELAY"
$DESTROYTYPE:2
@KillUnitsInRange(<-X <-Y <-RANGE <-UNITTYPE <-DESTROYTYPE)
# Usage @KillUnitsInRange(x y range "UNITTYPE" destroyType)
:KillUnitsInRange
->destroyType
->unitType
->range
->y
->x
do (GetUnitsInRange(<-x <-y <-range) 0)
->unitUID
if (GetUnitType(<-unitUID) eq(<-unitType))
Destroy(<-unitUID <-destroyType)
endif
loop
You can add the same script to a single core more than once. So if you just need to target two ranges on the map, or two unit types in the same location, you can just add the Killer.crpl script to a core twice then configure it differently for each one (without changing any of the code).
Now if you are wanting to kill different unit types (say 4 different things) in the same range, then it would be more efficient to modify the code to take a list of unit types to destroy. This could be done by adding $UNITTYPE2, $UNITTYPE3, $UNITTYPE4, etc. variables and checking for any of them in the 'if' that's inside GetUnitsInRange. Or you could ask me to add a string 'split' function to CRPL so you could put all of the items in one variable and separate them with spaces. Or you could ask me to add array support to CRPL and the editor, so you could add them as an array of data.
Or, if you just want to get it done, copy and paste the 'if' clause inside GetUnitsInRange and type in each unit type that you want to kill.
Can you add an array so it takes multiple units and multiple coordinates?
So you want to nuke some number of units (by type) in more than one range?
If that is the case it would better to loop through all units on the map and do the range calculations and type checking in that one loop. GetUnitsInRange is going to be the expensive call, so you only want to do that once. Just do it at coords 0,0 with a range of like 9999. That will get all units on the map. Then you can check the type of each unit and the range of each unit and destroy as appropriate.
Unfortunately, I'm not going to take the 15 minutes it would take to write that for you since I've got a full plate already. But you already have examples of all of the requires API's necessary to do this.
i want to kill units that get put on certain spots throughout the map
How many spots and are the spots just single coordinates (no range necessary)? Are you wanting to kill any player unit, or only units of certain types. If certain types, how many?
set single spots and i want to kill relays and collectors on those spots
If somebody builds a relay one cell to the right of one of your spots, what should happen? Note that units take up 3x3 areas.
i want to prevent them from putting them on powerzones. 8)
Ok, so your actual requirement for your map is:
- Prevent the player from building collectors and relays on power zones.
That means you would like to 'destroy' the unit before it is even built, correct? Else the player would waste time building a relay only to have it blow up.
In the next build I have added a 'GetUnitAt' call that will return a unit at any coordinates you specify. It will return any unit, even if it is building. Unfortunately, it only returns one unit. So stacked units (like a unit on a power zone) means you would get unpredictable results.
The GetUnitsInRange calls only return units that are built.
You need a more fundamental API that returns all units regardless of state, then you need to check to see if any collectors or relays overlap any power zones. That would work but what a pain.
An IsOverPowerZone call would be nice in this case. So you'd want something like this to work:
do (GetAllUnitsInRange(0 0 999) 0)
->unitUID
GetUnitType(<-unitUID) ->unitType
if (<-unitType eq("COLLECTOR) or (<-unitType eq("RELAY")))
if (IsOverPowerZone(<-unitUID))
Destroy(<-unitUID 0)
endif
endif
loop
If the IsOverPowerZone function existed that would work perfectly, yes.
I'm trying to get this to work. It is supposed to wait for all other enemy units to die before it activates but it automatically activates at the moment can someone please help?
# Can't fight this.crpl
# Created on: 5/29/2013 10:46:25 PM
# ------------------------------------------
if
(GetEnemyUnitsInRange(0 0 9999)) eq 1
QueueMove(RandCoords 3)
SetCreeper (currentcoords 200)
delay(15)
endif
You probably mean:
if ( GetEnemyUnitsInRange(0 0 9999) eq (1) )
You have the parenthesis messed up in your 'if'.
Withour parens it would be:
0 0 9999 GetEnemyUnitsInRange 1 eq if
now it isn't moving.
The condition probably is never true, then.
Put a trace inside the condition. (And a ShowTraceLog at the top of the script).
Aside from that, what you have in the condition doesn't really look 'healthy'. You are going to call QueueMove twice a second whether your unit is already moving or not. That will build up an ever growing list of movements.
Inside your outer 'if' that checks for enemy units, you want a nested 'if' that calls GetQueuedMoveCount. Only of that is 0 do you want to queue a new move.
Lastly, why are you checking for enemy units equal to 1? I don't know anything about your mission and what counts and enemy or not... but just trace the result of GetEnemyUnitsInRange and see what the number is. It is probably either 0 or more than 1...
if he checks if there's only one enemy left, that means that is the core that is running that script.
if (GetEnemyUnitsInRange(0 0 9999) eq (1))
if (GetQueuedMoveCount eq (0))
QueueMove(RandCoords 3)
SetCreeper (currentcoords 200)
endif
endif
if you want to emit creeper twice a second instead of when it queues a new movement, use timing functions outside the GetQueuedMoveCount block of code
if (GetEnemyUnitsInRange(0 0 9999) eq (1))
if (GetQueuedMoveCount eq (0))
QueueMove(RandCoords 3)
endif
GetTimer0 0 lte if
SetCreeper (currentcoords 200)
15 SetTimer0
endif
endif