a question for (or challenge to) the coders out there

Started by teknotiss, August 19, 2013, 04:05:21 PM

Previous topic - Next topic

teknotiss

can someone tell me if it's possible to CRPL script a new player unit that acts as a deployable "field"? if it helps imagine a shield unit that allows AC in from "behind" and pushes it across the (i'm thinking a rectangular field) shield zone and out the "front".
i'm still a total novice and i'm happy messing about with the basics for a while, and i think this is beyond me at the moment, but this proposed unit would make some interesting play options in some maps i'm building!
give it some thought, or work!  ;)
"Is God willing to prevent evil, but not able? Then he is not omnipotent.... Is he able, but not willing? Then he is malevolent.... Is he both able and willing? Then whence cometh evil?.... Is he neither able nor willing? Then why call him God?" --- Epicurus

knucracker

From "Ruine":

if (InvocationCount eq (1))
@DeployFields(118 119 15 80000000)
endif


:DeployFields
->S
->R
->y
->x
do (<-y add(<-R) add(1) <-y sub(<-R))
do (<-x add(<-R) add(1) <-x sub(<-R))
if ( I gte(0) and (J gte(0)) and (I lt MapWidth) and (J lt MapHeight) )
<-x sub(I) mul(<-x sub(I)) add (<-y sub(J) mul(<-y sub(J))) ->d2
if (<-d2 lt (<-R mul(<-R)) and (<-d2 neq0))
I sub (<-x) asfloat ->deltaX
J sub (<-y) asfloat ->deltaY
sqrt(<-d2) ->d

atan2(<-deltaY <-deltaX) ->a
<-a add (PI mul (-0.25) mul (<-d div(<-R))) ->a
cos(<-a) mul (<-S) mul (-1) ->deltaX
sin(<-a) mul (<-S) mul (-1) ->deltaY

SetFieldCell(I J <-deltaY <-deltaX <-deltaY div(5000) <-deltaX div(5000))
endif
endif
loop
loop


Here, the secret to custom fields like this is knowing they don't persist across save games.  You have to deploy them each time the script runs.  That why there is check for InvocationCount.  InvocationCount is the number of times the script has been called, and it always starts at 1 each time the game is loaded.

That now understood, the DeployFields function above will create a spiral field that points in.   'x' and 'y' are the coordinates, 'R' is the range, and 'S' is the strength.
If you want some other pattern then it's a simple matter of changing what 'deltaX' and 'deltaY' are in the call to SetFieldCell.

teknotiss

groovy, cheers for the reply V  :o, but can this be added to/part of a player moveable unit?
i'll have a play with the values of this and i think i can use this in one of  my next maps
"Is God willing to prevent evil, but not able? Then he is not omnipotent.... Is he able, but not willing? Then he is malevolent.... Is he both able and willing? Then whence cometh evil?.... Is he neither able nor willing? Then why call him God?" --- Epicurus

knucracker

Note that if you want a field that pulls in, pushes out, or is a spiral the easiest way (by far) is to use the built in tower field support.
For instance, from "Mistet"

EnableTowerField(9999 <-fieldStrength mul(-1) <-fieldStrength mul (-1) 0 FALSE)


That sets a field that follows a unit that has a range of 9999 (the whole map).  It pulls in with a strength of 'fieldStrength' (the negative value means inward rather than outward.  It pull straight in (hence the 0 value for the angle).  It has a constant strength across the entire range, hence the final FALSE.  If the final argument is TRUE, the field decays linearly with distance.

If you make that call on a unit, the unit can even move around, be destroyed, etc.  The internal workings will make sure to update everything accordingly. 

Now, if you want a custom pattern like in the prior example (which, btw, could have been replaced by the tower field...) then you have to manage the fields yourself.  If you move a unit, you have to 'undeploy' the field then deploy it again.  So every time the x or y coordinate of the unit changes, you have to reverse whatever fields you deployed at its previous location.  Then you can deploy the fields again at the new location.

That is exactly what EnableTowerField does internally (or the shield unit for that matter).  So if you just want regular fields, by all means use the single EnableTowerField call.  Fancier stuff, means more work...

teknotiss

well i have bitten off a bit more than i can immediately chew  ::)
i'll try messing about with the fieldtower stuff instead, then i need to work out how i call a unit for a script to act on it right? (is the call function in the wiki? GetUnitsInRange perhaps?)
hmm a bit of work to do then  :D
curse you V for not reading my mind some months ago and creating an unspecified number of specialist units so i wouldn't have to learn a new (and backwards! curses!!!) code!  ;)
"Is God willing to prevent evil, but not able? Then he is not omnipotent.... Is he able, but not willing? Then he is malevolent.... Is he both able and willing? Then whence cometh evil?.... Is he neither able nor willing? Then why call him God?" --- Epicurus

knucracker

If you use the warp operator, even though the underlying language is RPL, you hardly ever write RPL.
ex:

if ( <-state eq (<-STATE_BUILT) )
   SetScriptVar(<-ringCore "RingCore.crpl" "ringBuilt" TRUE)
endif


That looks like infix and prefix notation rather than postfix (RPL).

teknotiss

so let me get this straight? you have a reverse language that we can program in a non-reverse fashion ??? ? so just as i'm starting to bend my mind to the RPL style i find i can just (sort of) turbo or C++ it?
wow lots to get my head around for now. cheers dude!  8)
"Is God willing to prevent evil, but not able? Then he is not omnipotent.... Is he able, but not willing? Then he is malevolent.... Is he both able and willing? Then whence cometh evil?.... Is he neither able nor willing? Then why call him God?" --- Epicurus

knucracker

#7
'Reverse' is a relative term... just like language modifiers come before nouns/verbs in some human languages and after in others.  I woke up early this morning and was half awake and started thinking about this very thing.  Both language styles require memory, some require memory of the modifier and some of the noun/verb.  Reverse the order in english and you speak like yoda.  I wonder if they reverse the order when Yoda is dubbed in Spanish or French... Hmmm.  Food for thought.  :)

The following is a description of the different notations and why CRPL is the way it is.  Read on if this sort of thing interests you:

--
Better terms are prefix, infix, and postfix.

+ 3 4 :  Prefix notation
3 + 4 : Infix notation
3 4 + : Postfix notation

Which do you prefer, which is most natural?  Most people would say infix notation.  But what if the operator was a name rather than a symbol?
Add(3 4)
3 Add(4)
3 4 Add

None of them look that bad, actually.  But only postfix notation doesn't require scoping (the use of parenthesis).
Take this example written using infix notation:
3 + 4 - 5 + 2

What do I mean?  Whoops, I accidentally meant (3 + 4) - (5 + 2).
Written in postfix notation it looks like this:
3 4 add 5 2 add sub

Written in postfix, no parenthesis or other scoping symbol is required.  The processor that interprets the statement can also be written using only a stack to hold items.  The processor can also process left to right and never look back at anything.

So, which is best and which is backwards? :)

If you are doing arithmetic on a calculator, most of the time you use infix notation.  If you are using an old school HP calculator you will be using postfix notation and loving every minute of it.  If you are programming in java you will be using prefix and infix notation most of the time.  Same for C#, php, javascript, etc.  Programming in java bytecode, postscript, etc, you will be using postfix notation.

How does all of this relate to CRPL?  At the core (pun intended), CRPL is a kind of assembly language for a very specialized virtual CPU.  When you type in commands in CRPL, they all get converted to numbers (literally 0, 1, 2, 3, 4).  The instruction pointer for the CRPL CPU moves through the list of commands.  The 'microcode' for each command does things related to the game engine.  The CRPL CPU has access to a persistent randomly accessible memory (indexed by string) and to a stack of memory.  So, without any magic, postfix notation falls out of this kind of architecture and is the natural choice.
"3 4 add" literally compiles to:
PUSH 3
PUSH 4
ADD
This means push 3 to the stack, push 4 to the stack, call 'Add' which internally pops two items from the stack adds them, and pushes the result back to the stack.

If I did nothing else, that would be a usable and extensible computing platform.  The usefulness is dictated by the instructions the CRPL CPU provides.  But, knowing that most people are so used to prefix notation and thinking of things as function arguments, I added the 'warp' operator.  All the warp operator does is rearrange the commands in the source you type in.  It literally just causes a rearrangement of words.  I scan over the source string, rearrange based on parenthesis, then compile as usual.

So:
"3 Add(4)" becomes "3 4 Add" and then it gets compiled.
The command before an opening parenthesis gets moved to after the closing parenthesis.  That small slight of hand, allows you to think in prefix notation 95% of the time.

teknotiss

very interesting, and i suspect that my difficulty with languages (i'm awful at learning languages, my father and sister are awesome  ::)), is something to do with why my head hurts when coding. i'm not really using english anymore am i, cos it's essentially a basic understanding system (so we don't have to work in hex, or worse binary!  ;)) not my language.
still the warp operation will make it readable for me so no excuses i guess.
but i still think this will take me a while to really know what i'm doing

also, i too wondered about how yoda would sound in a "backwards functioning" language, just can't learn one to find out how.  ::) much better with history, psychology, sociology and physics.
"Is God willing to prevent evil, but not able? Then he is not omnipotent.... Is he able, but not willing? Then he is malevolent.... Is he both able and willing? Then whence cometh evil?.... Is he neither able nor willing? Then why call him God?" --- Epicurus

thepenguin

#9
Us: they are the dark side of the force.
Yoda: the dark side of the force are they.
Reverse: "they" "dark side" "force" of are
or maybe in CRPL:
They <-force <-darkside GetListElement 3 TRUE @be
# @be takes the following parameters:
# Subject Object Person IsPlural @be
or with warp:
They @be(<-force GetListElement(<-darkside))

:P :) :P
We have become the creeper...