Knuckle Cracker

Creeper World 3 => The Coder's Corner => Topic started by: Courtesy on December 26, 2014, 12:52:49 PM

Title: So I want to make a special enemy CRPL core, but It's beyond me.
Post by: Courtesy on December 26, 2014, 12:52:49 PM
Alright, so... This cores functionality is as follows.

As for the enemy...

Is this possible to make? It's far beyond my understanding of the engine if so, and I'd love the help.
Title: Re: So I want to make a special enemy CRPL core, but It's beyond me.
Post by: kwinse on December 26, 2014, 06:48:59 PM
As far as I know, there is no way to do all that you want. You can't directly subtract energy (can't add it either, though people work around that by building energy crystals and syphons via CRPL). Also you can't access connections, so you'd have to imitate their behavior, which is probably very expensive computation-wise.
Title: Re: So I want to make a special enemy CRPL core, but It's beyond me.
Post by: Courtesy on December 27, 2014, 12:00:18 AM
By access, do you mean there isn't even a way to track them?
One method I could see working is to have the core move inbetween units, in a straight line, making it so that it's route will always coincide with the connections (barring a unit getting destroyed before it arrives of course).
Would there be any way to have that unit take a circuitous route to it's destination, by forcing it to hop along the coords of units that are close enough to each other to be connected? Considering this is the only CRPL that would be on that map, being a bit computation expensive might not be too much of a risk to dissuade me if a way to simulate that behavior is possible. :x

If generating negative amounts of energy isn't possible, I could discard that idea easily enough.

_______________________________
An idea, modifying on the concept that would give an appearance of using the connections, would be that the unit which spawns when the core is connected could be coded to seek a unit within X coords (the range of the connection), and move towards it. When it arrives, then tell it to perform an action, or move to another unit. I don't know what it would look like in CRPL code, but I'd imagine that prior to being turned into actually functioning code, it might look like this.

Core:Find_Nullifier_In_Range
If:Nullifier_In_Range
GetCoordinateAs:New_Coordinate
Goto:New_Coordinate
Execute:Order
If:No_Nullifier
Core:Find_Sniper_In_Range
If:Sniper_In_Range
GetCoordinateAs:New_Coordinate
Goto:New_Coordinate
Execute:Order
If_No Sniper
Core:Find_Blaster_In_Range
If:Blaster_In_Range
GetCoordinateAs:New_Coordinate
Goto:New_Coordinate
Execute:Order
If:No_Blaster
Core:Find_Relay_In_Range
If:Relay_In_Range
GetCoordinateAs:New_Coordinate
Goto:New_Coordinate
If:No_Relay
Core:Find_Collector_In_Range
If:Collector_In_Range
GetCoordinateAs:New_Coordinate
Goto:New_Coordinate
If:No_Collector
Execute:Order
Loop


Of course there is several very important things missing in that example. CRPL compatibility, for one, and as it stands it would teleport inbetween locations, instead of moving over a period of time. But the body I am attempting to simulate in this silly example is a core that would systematically go down it's list of priorities. If it finds none of them, it would then move to a relay in range, or a collector, and if it finds neither of those,release it's payload wherever it currently is. I could see several ways to trip up or glitch this rudimentary AI, but I think it would be functional enough for most situations, assuming it makes logical sense to the CRPL engine when translated.

(I hope I don't sound like a rambling lunatic right now)
Title: Re: So I want to make a special enemy CRPL core, but It's beyond me.
Post by: Courtesy on December 27, 2014, 12:35:52 PM
Can I get the Core to at least share this trait of collectors: Connecting to ANY unit?
Like, instead of it needing to connect to a collector, have it connect to a nullifier is that is set in range?
Title: Re: So I want to make a special enemy CRPL core, but It's beyond me.
Post by: J on December 27, 2014, 01:28:46 PM
The built-in mechanism for connecting and requesting packets only works with collectors and relays at collector distance. For anything else you must write a custom script that searches for a unit in range and draw a white line.

For the enemy, almost the same thing applies, completely rewrite what the game already can do. You don't need to draw the connection lines here, as they are already already visible. Search for the best route, queue all moves and it's ready to go.
Title: Re: So I want to make a special enemy CRPL core, but It's beyond me.
Post by: Courtesy on December 27, 2014, 02:06:42 PM
Alright. What range does a collector actually operate at so I can draw a line of appropriate size? I'm pretty certain I can jerry rig the enemy to operate at least similarly to what I wanted if I poke at this long enough, though I might have a few more questions while I try.
Title: Re: So I want to make a special enemy CRPL core, but It's beyond me.
Post by: stewbasic on January 05, 2015, 10:08:08 PM
Collectors form connections up to 9.99 cells, relays up to 18.99 cells. See here:

http://knucklecracker.com/wiki/doku.php?id=cw3:unit_data_overview

btw I wrote some code for computing all unit connections for the original PlayAsCreeper map, which may help. However this code was intended to run at edit time, not during play, so it may be slow. Of course you'll also have to figure out what to do if the network changes (eg player destroys unit) while your "packet" is moving.


$COLLECTOR:2
$RELAY:3
$REACTOR:1
$OREMINE:1
$SIPHON:1
$GUPPY:1
$SHIELD:1
$STRAFER:1
$BOMBER:1
$TERP:1
$PULSECANNON:1
$MORTAR:1
$SPRAYER:1
$BEAM:1
$SNIPER:1
$NULLIFIER:1

:SnapshotNetwork
CreateList ->unitX
CreateList ->unitY
CreateList ->unitType
CreateList ->connectionCount
CreateList ->adjacency
GetUnitsInRange(0 0 9999)
0 do
dup ->unit GetUnitType dup ->type <-! ->t
if(<-t)
GetUnitAttribute(<-unit CONST_COORDX) AppendToList(dup <-unitX swap)
GetUnitAttribute(<-unit CONST_COORDY) AppendToList(dup <-unitY swap)
AppendToList(<-unitType <-type)
CreateList ->neighbours
if(<-t 3 eq)
GetUnitsInRange(dup2 18.99) 0 do
->other
if(<-other <-unit neq)
if(GetUnitType(<-other) "RELAY" eq)
AppendToList(<-neighbours <-other)
endif
endif
loop
GetUnitsInRange(9.99) 0 do
->other
if(GetUnitType(<-other) <-!)
if(<-other <-unit neq)
if(GetUnitType(<-other) "RELAY" neq) # Avoid double counting
AppendToList(<-neighbours <-other)
endif
endif
endif
loop
else if(<-t 2 eq)
GetUnitsInRange(9.99) 0 do
->other
if(GetUnitType(<-other) <-!)
if(<-other <-unit neq)
AppendToList(<-neighbours <-other)
endif
endif
loop
else
GetUnitsInRange(9.99) 0 do
->other
if(GetUnitType(<-other) <-! 1 gt)
AppendToList(<-neighbours <-other)
endif
loop
endif endif
AppendToList(<-adjacency <-neighbours)
AppendToList(<-connectionCount GetListCount(<-neighbours))
endif
loop


Regarding the energy drain, you could put an invisible core on the command node which accepts packets (but the player could turn off ammo packets on the CN to get around it).