Knuckle Cracker

Creeper World 3 => Custom Map Discussion => Topic started by: wolkiewicz on July 07, 2014, 04:31:42 AM

Title: Moving CRPL Core
Post by: wolkiewicz on July 07, 2014, 04:31:42 AM
Hi
Again i have problem with CRPL. I'm creating a script, and i see strange problem. If i'm putting that script on CRPL core, it moves always to the same point of map. I tested it on 2 maps. Plz help.
Script:

#Name: UnitMemories
#Author: wolkiewicz
#------------------
$cannon:2
$mortar:1
$beam:3
$sniper:1
$strafer:2
$titans:0
$shield:1
$siphon:0
$reactor:0
$guppy:2
#------------------
once
Self false CONST_CREATEPZ SetUnitAttribute
Self false CONST_COUNTSFORVICTORY SetUnitAttribute
endonce
CurrentCoords GetCreeper neq0 if
SetBuildLimit("PULSECANNON" <-cannon)
SetBuildLimit("MORTAR" <-mortar)
SetBuildLimit("BEAM" <-beam)
SetBuildLimit("SNIPER" <-sniper)
SetBuildLimit("STRAFER" <-strafer)
SetBuildLimit("BERTHA" <-titans)
SetBuildLimit("FORGE" <-titans)
SetBuildLimit("SHIELD" <-shield)
SetBuildLimit("SIPHON" <-siphon)
SetBuildLimit("REACTOR" <-reactor)
SetBuildLimit("GUPPY" <-guppy)
Self true CONST_ISBUILDING SetUnitAttribute
Self 100 CONST_BUILDCOST SetUnitAttribute
Self "Custom0" 255 0 0 255 SetImageColor
endif
CurrentCoords GetCreeper eq0 if
Self true CONST_CONNECTABLE SetUnitAttribute
endif
Self CONST_BUILDCOST GetUnitAttribute eq0 if
Self "Custom0" 255 255 255 255 SetImageColor
SetBuildLimit("PULSECANNON" -1)
SetBuildLimit("MORTAR" -1)
SetBuildLimit("BEAM" -1)
SetBuildLimit("SNIPER" -1)
SetBuildLimit("STRAFER" -1)
SetBuildLimit("BERTHA" -1)
SetBuildLimit("FORGE" 1)
SetBuildLimit("SHIELD" -1)
SetBuildLimit("SIPHON" -1)
SetBuildLimit("REACTOR" -1)
SetBuildLimit("GUPPY" -1)
endif
Title: Re: Moving CRPL Core
Post by: Relli on July 07, 2014, 09:09:29 AM
There's nothing in this code that should make the Core move, nothing at all. So for that, I have no answer.
But there are a few things that I can help with. For all the times you use SetUnitAttribute, you need the value of it (true/false/100) to appear /after/ the CONST_WHATEVER rather than before.
Also, this line

Self CONST_BUILDCOST GetUnitAttribute eq0 if

will not do what you're probably hoping it will. The buildcost is the number of packets it takes to complete, and that number does not go down as it gets packets. So even once it's completely built, the buildcost remains 100. If you want a command to tell when the core has all 100 packets, change it to something like this.

Self CONST_ISBUILDING GetUnitAttribute not if

I hope this helps out. If you have any more problems, let us know.
Title: Re: Moving CRPL Core
Post by: Grayzzur on July 07, 2014, 09:42:09 AM
Actually, there is.

Because you have the arguments in the wrong order, you're inadvertently moving the unit.

As Relli said, you have the true/false and CONST reversed. "TRUE" is 1, and "CONST_COORDX" also happens to be 1 (though normally you don't care what the CONST* values are behind the scenes). "CONST_ISBUILDING" happens to be 4.

Getting your arguments in the wrong order can cause strange behavior.

Your incorrect command of:
Self true CONST_ISBUILDING SetUnitAttribute
is probably being interpreted as:
Self CONST_COORDX 4 SetUnitAttribute


As a tip, I see you're jumping back and forth between stack and warp notation. The following pairs of commands are identical, and you should probably stick to one or the other until you're more comfortable with the whole stack programming concept.

These two lines are identical:
SetBuildLimit("PULSECANNON" <-cannon)
"PULSECANNON" <-cannon SetBuildLimit

So are these:
SetUnitAttribute(Self CONST_CONNECTABLE true)
Self CONST_CONNECTABLE true SetUnitAttribute
Title: Re: Moving CRPL Core
Post by: wolkiewicz on July 07, 2014, 12:50:30 PM
Now i have following problems:
1.After "taking damage" by creeper it don't change color to red
2. The core is always connectable
3. It don,t recive packets after killing creeper.
Title: Re: Moving CRPL Core
Post by: Grayzzur on July 07, 2014, 03:15:53 PM
It would help if you posted the current version of your script. It's hard for us to guess what changes you've made to it.  ;D
Title: Re: Moving CRPL Core
Post by: ParkourPenguin on July 07, 2014, 04:14:52 PM
1. After "taking damage" by creeper it don't change color to red
Try replacing "Custom0" with "main" wherever you invoke SetImageColor. As stated in the CRPL Reference, "The slot named 'main' refers to the primary unit image (the one that can be set in the editor)." (https://knucklecracker.com/wiki/doku.php?id=crpl:docs:setimagecolor (https://knucklecracker.com/wiki/doku.php?id=crpl:docs:setimagecolor)).

2. The core is always connectable
Well, you tried to made it connectable by setting CONST_CONNECTABLE to true in the second if statement (by the way, as Grayzzur stated, you switched true and CONST_CONNECTABLE here); however, you failed to set CONST_CONNECTABLE false anywhere else. If you don't want it to be connectable, you should set that attribute to be false somewhere in your code. For instance, if you don't want it to connect if it's in creep, make it false inside the if statement where it checks if it's in creep.

3: It don,t recive packets after killing creeper.
I'm afraid I don't know exactly what you mean by that. You didn't set the attribute CONST_REQUESTPACKETS anywhere, nor is anything implemented in your code such that it could destroy creeper.

If you mean when the creeper underneath it is destroyed then it should request build packets, then you have a little bit more work to do.

First of all, CONST_BUILDCOST only defines how many packets are required to build the unit. You should probably set this somewhere in your once...endonce block and remove it from inside the first if statement since it serves no useful purpose there.

Secondly, the argument in your last if statement doesn't make sense, as you're checking to see if the build cost is equal to 0 before rescinding the build limitations. Instead, you should be checking whether or not it's finished building by getting the CONST_ISBUILDING attribute. Just make sure you invert that result using the "not" operator because you want to check if it's not being built.

Third, you need to allow the CRPL tower to request packets by setting the attribute CONST_REQUESTPACKETS to true inside your once...endonce block. Otherwise, it will never receive build packets.



TL;DR or just in case you missed anything, here is a modified version of your original script with everything that I could see fixed:
Spoiler
#Name: UnitMemories
#Author: wolkiewicz
#------------------
$cannon:2
$mortar:1
$beam:3
$sniper:1
$strafer:2
$titans:0
$shield:1
$siphon:0
$reactor:0
$guppy:2
#------------------
once
Self CONST_CREATEPZ false SetUnitAttribute
Self CONST_COUNTSFORVICTORY false SetUnitAttribute
Self CONST_BUILDCOST 100 SetUnitAttribute
Self CONST_REQUESTPACKETS true SetUnitAttribute
endonce
CurrentCoords GetCreeper neq0 if
SetBuildLimit("PULSECANNON" <-cannon)
SetBuildLimit("MORTAR" <-mortar)
SetBuildLimit("BEAM" <-beam)
SetBuildLimit("SNIPER" <-sniper)
SetBuildLimit("STRAFER" <-strafer)
SetBuildLimit("BERTHA" <-titans)
SetBuildLimit("FORGE" <-titans)
SetBuildLimit("SHIELD" <-shield)
SetBuildLimit("SIPHON" <-siphon)
SetBuildLimit("REACTOR" <-reactor)
SetBuildLimit("GUPPY" <-guppy)
Self CONST_ISBUILDING true SetUnitAttribute
Self CONST_CONNECTABLE false SetUnitAttribute
Self "main" 255 0 0 255 SetImageColor
endif
CurrentCoords GetCreeper eq0 if
Self CONST_CONNECTABLE true SetUnitAttribute
endif
Self CONST_ISBUILDING GetUnitAttribute not if
Self "main" 255 255 255 255 SetImageColor
SetBuildLimit("PULSECANNON" -1)
SetBuildLimit("MORTAR" -1)
SetBuildLimit("BEAM" -1)
SetBuildLimit("SNIPER" -1)
SetBuildLimit("STRAFER" -1)
SetBuildLimit("BERTHA" -1)
SetBuildLimit("FORGE" 1)
SetBuildLimit("SHIELD" -1)
SetBuildLimit("SIPHON" -1)
SetBuildLimit("REACTOR" -1)
SetBuildLimit("GUPPY" -1)
endif
[close]
Title: Re: Moving CRPL Core
Post by: Relli on July 08, 2014, 09:14:38 AM
Quote from: Grayzzur on July 07, 2014, 09:42:09 AM
Actually, there is.

Because you have the arguments in the wrong order, you're inadvertently moving the unit.

"TRUE" is 1, and "CONST_COORDX" also happens to be 1 (though normally you don't care what the CONST* values are behind the scenes). "CONST_ISBUILDING" happens to be 4.
Wow, I had no idea. This is pretty cool stuff. I can see learning all these numbers and using them as a sort of shorthand. Though I would imagine that's bad practice since it makes the code harder to immediately understand when reading it.

PS: *Looks at ParkourPenguin's new avatar*
You have good taste, sir :D
Title: Re: Moving CRPL Core
Post by: Grayzzur on July 08, 2014, 10:43:13 AM
Quote from: Relli on July 08, 2014, 09:14:38 AM
I can see learning all these numbers and using them as a sort of shorthand. Though I would imagine that's bad practice since it makes the code harder to immediately understand when reading it.
You are correct. Use the keywords. Maintainability and readability are more important than "compact" code. It doesn't make it any more efficient, the compiler still takes it down to the same number of opcodes. If you try to be cute with the numbers in your code, you won't be able to read your own scripts in 3 weeks!

It's just good to understand what's going on underneath the hood when you have to debug stuff.
Title: Re: Moving CRPL Core
Post by: wolkiewicz on July 08, 2014, 12:46:48 PM
Thank you guys for help! I really need it now because i am newbie in scripting. Now it works :). But i have an another questions, not about thit script. If i haven't got too much questions :p.
1. Can I create a projectiles or somethink like that? I know it is possible, but i don't know how.
2. How can i add last created unit named (for example CRPL1) to script?
Title: Re: Moving CRPL Core
Post by: ParkourPenguin on July 08, 2014, 03:12:58 PM
Quote from: wolkiewicz on July 08, 2014, 12:46:48 PM
Thank you guys for help! I really need it now because i am newbie in scripting. Now it works :). But i have an another questions, not about thit script. If i haven't got too much questions :p.
1. Can I create a projectiles or somethink like that? I know it is possible, but i don't know how.
2. How can i add last created unit named (for example CRPL1) to script?
Don't worry about asking too many questions- we're always happy to help!  ;)

1. Yes, but it can get significantly more complicated than what you are doing here. Virgil showed off a couple scripts that made a tower and created a projectile on one of his previous blog posts (http://knucklecracker.com/blog/index.php/2013/01/chimera/ (http://knucklecracker.com/blog/index.php/2013/01/chimera/)). I've attached both of those scripts he used to this post.

2. I'm afraid I don't know what you're asking; however, you might be able to find what you're looking for using the list of all available commands in the reference page of the wiki (http://knucklecracker.com/wiki/doku.php?id=crpl:crplreference (http://knucklecracker.com/wiki/doku.php?id=crpl:crplreference)).


Quote from: Relli on July 08, 2014, 09:14:38 AM
PS: *Looks at ParkourPenguin's new avatar*
You have good taste, sir :D
PS: July 24th is when season 2 premieres. Can't wait!  ;D
Title: Re: Moving CRPL Core
Post by: Grayzzur on July 08, 2014, 03:14:20 PM
This link (http://knucklecracker.com/wiki/doku.php?id=crpl:examine_map_resources (http://knucklecracker.com/wiki/doku.php?id=crpl:examine_map_resources)) shows you how to extract the scripts from another map and take a look at them.

The map you want is in the Alpha sector, Virgil's Chimera map (Alpha, virgilw, Chimera). This map has some CRPL gun turrets that create projectiles, and is a great baseline for both your questions. It creates the projectiles as separate CRPL cores, and adds the projectile script to them.

(You don't add a CRPL core to a script, you add a script to a core and it runs its own instance of that script.)
Title: Re: Moving CRPL Core
Post by: wolkiewicz on July 09, 2014, 04:31:11 AM
Hmm i read a scripts from chimera map and i found that:
@GetClosestUnit
I found @Function on crpl reference but it isn't simple for me.
Could you explain me how it works?
Title: Re: Moving CRPL Core
Post by: wolkiewicz on July 09, 2014, 06:47:05 AM
NVM i know it now. But i have next question, now about rotating :p
When my unit is moving to target at X,Y coords, how can i rotate the image to target? It looks bad when my bomber flying to target...sideway
Title: Re: Moving CRPL Core
Post by: ParkourPenguin on July 09, 2014, 11:10:47 AM
Quote from: wolkiewicz on July 09, 2014, 06:47:05 AM
NVM i know it now. But i have next question, now about rotating :p
When my unit is moving to target at X,Y coords, how can i rotate the image to target? It looks bad when my bomber flying to target...sideway
Mathematics. More specifically, trigonometry. But I'll assume you don't know anything about trig.

So, to begin, let's assume your target is at X,Y as you stated. What you need is the offset: the distance between your CRPL core and your target. This can be done fairly easily, like so:
<-X CurrentX sub ->OffsetX
<-Y CurrentY sub ->OffsetY


Then, you'll need to use trig to calculate an angle that you need:
<-OffsetY <-OffsetX atan2 ->Angle
For any other math person out there, take note that the range of the atan2 command is (-pi,pi], making it quite robust as it can give you a reasonable answer for any input values y,x. I'd recommend playing around with it before you use it.

But I digress. In the Creeper World 3 coordinate system, moving to the right increases the x-coordinate, and moving down will increase the y-coordinate (moving left/up will decrease the x/y coordinate, respectively).However, SetImageRotation will rotate it counterclockwise for positive input angles. This means that you simply have to invert the angle when you invoke SetImageRotation:
self "main" <-Angle neg SetImageRotation

I suppose you could do all of this on a single line of code if you wanted to, however:
self "main" <-Y CurrentY sub <-X CurrentX sub atan2 neg SetImageRotation
It was just easier for me to explain what was happening if I broke it up.
Title: Re: Moving CRPL Core
Post by: Grayzzur on July 09, 2014, 11:28:21 AM
If you're creating flying units, one thread you may want to read is Eduran's Flyer Movement Framework (http://knucklecracker.com/forums/index.php?topic=15387.0). He did a lot of work to make it easier to control flyers.
Title: Re: Moving CRPL Core
Post by: wolkiewicz on July 09, 2014, 02:30:35 PM
Can I use movement functions from Flyer Movement Framework on my own script, or i must use FlyerMovement.crpl ? I tried to do somethink but without effect. Flier demo looks very nice!
All scripts i'm using:
Bomb:
# Bomb.crpl
# Created on: 7/9/2014 10:25:53 AM
# ------------------------------------------

$targetX:0
$targetY:0
$speed:1
$payload:20
#----------------

once
SetUnitAttribute(self CONST_CREATEPZ FALSE)
SetUnitAttribute(self CONST_TAKEMAPSPACE FALSE)
SetUnitAttribute(Self CONST_SUPPORTSDIGITALIS FALSE)
SetUnitAttribute(Self CONST_NULLIFIERDAMAGES FALSE)
SetUnitAttribute(Self CONST_COUNTSFORVICTORY FALSE)
QueueMove(<-targetX <-targetY <-speed)
endonce
If (GetQueuedMoveCount eq0)
CurrentCoords <-payload SetCreeper
Destroy(Self 0)
endif

Bomber:
# Bomber.crpl
# Created on: 7/9/2014 10:38:06 AM
# ------------------------------------------

$range:8
$payload:20
$speed:1.5
$delay:30
$acceleration:0
#-------------------------------------------

once
SetUnitAttribute(self CONST_CREATEPZ FALSE)
SetUnitAttribute(self CONST_TAKEMAPSPACE FALSE)
SetUnitAttribute(Self CONST_SUPPORTSDIGITALIS FALSE)
SetUnitAttribute(Self CONST_NULLIFIERDAMAGES FALSE)
SetUnitAttribute(Self CONST_COUNTSFORVICTORY FALSE)
SetUnitAttribute(Self CONST_BEAMTARGET TRUE)
SetUnitAttribute(Self CONST_MAXHEALTH 3)
SetUnitAttribute(Self CONST_HEALTH 3)
Self "main" -0.02 SetImagePositionZ
    0 ->targetX
    0 ->targetY
endonce

@GetClosestUnit ->closestUnit


<-closestUnit neq0 if
<-closestUnit CONST_COORDX GetUnitAttribute ->targetX
<-closestUnit CONST_COORDY GetUnitAttribute ->targetY
else
-1 ->targetX -1 ->targetY
endif

once
@TakeoffNow
@QueueMove(<-targetX <-targetY -1 <-speed <-acceleration -1)
endonce

CurrentCoords <-range GetUnitCountInRange neq0 if
GetTimer0 eq0 if
PlaySound("Weapons4")
@CreateBomb
<-delay SetTimer0
endif
endif




:CreateBomb
"CRPLCore" CurrentX CurrentY CreateUnit ->unit
<-unit "Bomb.crpl" AddScriptToUnit
<-unit "Bomb.crpl" "targetX" <-targetX SetScriptVar
<-unit "Bomb.crpl" "targetY" <-targetY SetScriptVar
<-unit "Bomb.crpl" "payload" <-payload SetScriptVar
<-unit "main" "Custom2" SetImage
<-unit "main" 0 120 255 255 SetImageColor
<-unit "main" -0.01 SetImagePositionZ
#End


:GetClosestUnit
99999999 ->closestDistance
0 ->closestUnit
GetUnitsInRange(CurrentCoords 99999999)  ->unitCount
do (<-unitCount 0)
->unit
CurrentCoords <-unit CONST_COORDX GetUnitAttribute <-unit CONST_COORDY GetUnitAttribute Distance ->d
if (<-d lt(<-closestDistance))
GetUnitType(<-unit) ->ut
if ( not(<-ut eq ("POWERZONE") or (<-ut eq ("TECHARTIFACT")) or (<-ut eq("MESSAGEARTIFACT")) or (<-ut eq("SHIELDKEY"))) )
<-d ->closestDistance
<-unit ->closestUnit
endif
endif
loop
<-closestUnit
#End


:QueueMove
# arguments: X and Y (cell coordinates), direction on arrival, speed (pixel per tick), acceleration (change in speed per tick), turn radius (pixels)
# direction has to be a positive angle (0 to 2*PI), set to -1 to allow any direction
# speed, acceleration and turn radius can be set to -1 to keep them unchange
# x1 y1 f1 f2 f3 f4 -
CreateList ->Waypoint
do(4 0)
->item
PrependToList(<-Waypoint <-item)
loop
CellToPixel
do(2 0)
->item
PrependToList(<-Waypoint <-item)
loop
AppendToList(GetScriptVar(Self <-movementScriptName "QueuedWaypoints") <-Waypoint)
#End


:TakeoffNow
# starts the takeoff animation without queueing a waypoint
SetScriptVar(Self <-movementScriptName "changeFlightState" 1)
#end

Script Settings from Flyer.crpl
once
# FlyerMovement.crpl settings
"Bomber.crpl"  ->movementScriptName
SetScriptVar(Self <-movementScriptName "initialFlightState" 0) # initial flight state, 0 means landed, 2 means in the air

# initial setup
CreateList ->QueuedWaypoints
SetScriptVar(Self <-movementScriptName "QueuedWaypoints" <-QueuedWaypoints)
SetScriptVar(Self <-movementScriptName "waitForInitialization" 0)
endonce


Wow, scripting is very hard....
Title: Re: Moving CRPL Core
Post by: Grayzzur on July 09, 2014, 05:29:34 PM
I believe it was designed to be added as a second script to your unit. You don't really call functions in the other script, but you can set variables in the other script (like targetX/targetY) to adjust it's behavior. The sample flyer is doing that by setting the QueuedWaypoints (and some other variables) of the other script.

If you want to rip parts of it out and put it in your own script, there's nothing stopping you. The polite thing to do at that point is add a comment to the top of your script stating something like "Portions of this script taken from FlyerMovement.crpl by Eduran." Give credit where credit is due!
Title: Re: Moving CRPL Core
Post by: wolkiewicz on July 10, 2014, 07:31:53 AM
The problem is, it don't work when i add 2 scripts to unit. Look at my "Bomber" script. I added :QueueMove function to script, and "Settings" script to bomber, but it still don't moving. But when i'm using <-targetX <-targetY QueueMove , it moves to target, but texture is in wrong rotation. I going to do somethink like Demoflyer, but with diffrent track.