Moving CRPL Core

Started by wolkiewicz, July 07, 2014, 04:31:42 AM

Previous topic - Next topic

wolkiewicz

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

Relli

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.

Grayzzur

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
"Fate. It protects fools, little children, and ships named 'Enterprise.'" -William T. Riker

wolkiewicz

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.

Grayzzur

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
"Fate. It protects fools, little children, and ships named 'Enterprise.'" -William T. Riker

ParkourPenguin

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).

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]
"Only a life lived for others is a life worthwhile."
-Albert Einstein

Relli

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

Grayzzur

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.
"Fate. It protects fools, little children, and ships named 'Enterprise.'" -William T. Riker

wolkiewicz

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?

ParkourPenguin

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/). 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).


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
"Only a life lived for others is a life worthwhile."
-Albert Einstein

Grayzzur

This link (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.)
"Fate. It protects fools, little children, and ships named 'Enterprise.'" -William T. Riker

wolkiewicz

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?

wolkiewicz

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

ParkourPenguin

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.
"Only a life lived for others is a life worthwhile."
-Albert Einstein

Grayzzur

If you're creating flying units, one thread you may want to read is Eduran's Flyer Movement Framework. He did a lot of work to make it easier to control flyers.
"Fate. It protects fools, little children, and ships named 'Enterprise.'" -William T. Riker