So I want to make a special enemy CRPL core, but It's beyond me.

Started by Courtesy, December 26, 2014, 12:52:49 PM

Previous topic - Next topic

Courtesy

Alright, so... This cores functionality is as follows.


  • It releases creeper like a normal emitter.
  • It seeds digitalis
  • It performs all the functions of a normal emitter

  • Additionally, it can connect to the command node via the connection line you normally would feed something packets with. It connects from further away than a relay.
  • The core generates negative amounts of energy
  • It does not accept packets: it simply connects to the command node.
  • When connected to the command node, it generates a unique CRPL enemy, at a rate of 1 immediately, and 1 additional unit every 7 seconds.
As for the enemy...

  • The enemy appears similar to a packet, and travels along the connection line, much like runners travel along digitalis. It is not a packet. When this enemy reaches its destination, it automatically destroys any unit in the same coordinate as it was, and releases another CRPL core.
  • The enemy can be destroyed by being shot 3 times with a sniper, and prioritizes it's targets as follows. Nullifier(any):Nearest_Sniper:Nearest_Weapon:Nearest_Shield:Nearest_Reactor:Command_Node

  • This new core releases 15 creeper every 0.33 seconds for 5 seconds and seeding digtalis, and then destroys itself. The core can be destroyed earlier with 2 shots from a sniper to minimize damage.

Is this possible to make? It's far beyond my understanding of the engine if so, and I'd love the help.

kwinse

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.

Courtesy

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)

Courtesy

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?

J

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.

Courtesy

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.

stewbasic

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