Phase A: Black Wax economy — resource layer, digger harvester, pressing plant, amp stack, vault, seeded maps, cash HUD, placeholder sprites
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
030b3f2698
commit
86ca71b9a2
@ -4,3 +4,15 @@ Container@PLAYER_WIDGETS:
|
||||
LogicTicker@SIDEBAR_TICKER:
|
||||
MenuButton@OPTIONS_BUTTON:
|
||||
Key: escape
|
||||
Container@CASH_COUNTER:
|
||||
Logic: IngameCashCounterLogic
|
||||
X: PARENT_WIDTH - WIDTH - 10
|
||||
Y: 10
|
||||
Width: 120
|
||||
Height: 23
|
||||
Children:
|
||||
LabelWithTooltip@CASH:
|
||||
Width: PARENT_WIDTH
|
||||
Height: 23
|
||||
Align: Right
|
||||
Font: TinyBold
|
||||
|
||||
@ -2,3 +2,13 @@ Cursors:
|
||||
cursors/assets/default.png:
|
||||
default:
|
||||
Start: 0
|
||||
harvest:
|
||||
Start: 0
|
||||
enter:
|
||||
Start: 0
|
||||
enter-blocked:
|
||||
Start: 0
|
||||
move:
|
||||
Start: 0
|
||||
move-blocked:
|
||||
Start: 0
|
||||
|
||||
@ -8,3 +8,16 @@ faction-vinylgod =
|
||||
.name = Vinylgod
|
||||
.description = Vinylgod Faction
|
||||
Provide your own faction description here.
|
||||
|
||||
## economy.yaml
|
||||
actor-digger =
|
||||
.name = Crate Digger
|
||||
actor-pressplant =
|
||||
.name = Pressing Plant
|
||||
actor-ampstack =
|
||||
.name = Amp Stack
|
||||
actor-vault =
|
||||
.name = Record Vault
|
||||
|
||||
## world.yaml (resources)
|
||||
resource-wax = Black Wax
|
||||
|
||||
Binary file not shown.
@ -28,3 +28,12 @@ Players:
|
||||
Faction: Random
|
||||
|
||||
Actors:
|
||||
Actor1: pressplant
|
||||
Owner: Creeps
|
||||
Location: 12,12
|
||||
Actor2: digger
|
||||
Owner: Creeps
|
||||
Location: 15,14
|
||||
Actor3: ampstack
|
||||
Owner: Creeps
|
||||
Location: 10,14
|
||||
|
||||
Binary file not shown.
@ -12,6 +12,7 @@ Notifications:
|
||||
|
||||
Rules:
|
||||
vinylgod|rules/vinylgod.yaml
|
||||
vinylgod|rules/economy.yaml
|
||||
vinylgod|rules/mpspawn.yaml
|
||||
vinylgod|rules/palettes.yaml
|
||||
vinylgod|rules/player.yaml
|
||||
@ -19,6 +20,7 @@ Rules:
|
||||
|
||||
Sequences:
|
||||
vinylgod|sequences/vinylgod.yaml
|
||||
vinylgod|sequences/economy.yaml
|
||||
vinylgod|sequences/mapeditor.yaml
|
||||
vinylgod|sequences/mpspawn.yaml
|
||||
|
||||
|
||||
100
mods/vinylgod/rules/economy.yaml
Normal file
100
mods/vinylgod/rules/economy.yaml
Normal file
@ -0,0 +1,100 @@
|
||||
^EconSprite:
|
||||
BodyOrientation:
|
||||
QuantizeFacingsFromSequence:
|
||||
RenderSprites:
|
||||
WithSpriteBody:
|
||||
SelectionDecorations:
|
||||
AppearsOnRadar:
|
||||
HitShape:
|
||||
HiddenUnderFog:
|
||||
|
||||
digger:
|
||||
Inherits: ^EconSprite
|
||||
Tooltip:
|
||||
Name: actor-digger.name
|
||||
Selectable:
|
||||
Bounds: 1024, 1024
|
||||
Health:
|
||||
HP: 60000
|
||||
Armor:
|
||||
Type: Heavy
|
||||
Mobile:
|
||||
Locomotor: wheeled
|
||||
Speed: 72
|
||||
Harvester:
|
||||
Resources: Wax
|
||||
BaleUnloadDelay: 1
|
||||
SearchFromProcRadius: 15
|
||||
SearchFromHarvesterRadius: 8
|
||||
StoresResources:
|
||||
Capacity: 20
|
||||
Resources: Wax
|
||||
DockClientManager:
|
||||
RevealsShroud:
|
||||
Range: 5c0
|
||||
MapEditorData:
|
||||
Categories: Units
|
||||
|
||||
^EconBuilding:
|
||||
Inherits: ^EconSprite
|
||||
Tooltip:
|
||||
Health:
|
||||
HP: 90000
|
||||
Armor:
|
||||
Type: Wood
|
||||
RevealsShroud:
|
||||
Range: 5c0
|
||||
MapEditorData:
|
||||
Categories: Buildings
|
||||
|
||||
pressplant:
|
||||
Inherits: ^EconBuilding
|
||||
Tooltip:
|
||||
Name: actor-pressplant.name
|
||||
Selectable:
|
||||
Bounds: 2048, 2048
|
||||
Building:
|
||||
Footprint: xx ==
|
||||
Dimensions: 2,2
|
||||
TerrainTypes: Clear
|
||||
Refinery:
|
||||
DockHost:
|
||||
Type: Unload
|
||||
DockOffset: 0, 512, 0
|
||||
StoresPlayerResources:
|
||||
Capacity: 2000
|
||||
Power:
|
||||
Amount: -30
|
||||
FreeActor:
|
||||
Actor: digger
|
||||
SpawnOffset: 0, 2
|
||||
|
||||
ampstack:
|
||||
Inherits: ^EconBuilding
|
||||
Tooltip:
|
||||
Name: actor-ampstack.name
|
||||
Selectable:
|
||||
Bounds: 1024, 1024
|
||||
Health:
|
||||
HP: 40000
|
||||
Building:
|
||||
Footprint: x
|
||||
Dimensions: 1,1
|
||||
TerrainTypes: Clear
|
||||
Power:
|
||||
Amount: 100
|
||||
|
||||
vault:
|
||||
Inherits: ^EconBuilding
|
||||
Tooltip:
|
||||
Name: actor-vault.name
|
||||
Selectable:
|
||||
Bounds: 1024, 1024
|
||||
Health:
|
||||
HP: 30000
|
||||
Building:
|
||||
Footprint: x
|
||||
Dimensions: 1,1
|
||||
TerrainTypes: Clear
|
||||
StoresPlayerResources:
|
||||
Capacity: 3000
|
||||
@ -1,6 +1,8 @@
|
||||
^palettes:
|
||||
PaletteFromGrayscale@greyscale:
|
||||
Name: greyscale
|
||||
PaletteFromGrayscale@terrain:
|
||||
Name: terrain
|
||||
PlayerColorPalette@player:
|
||||
BasePalette: greyscale
|
||||
PlayerColorShift:
|
||||
|
||||
@ -5,6 +5,11 @@
|
||||
player:
|
||||
Inherits: ^baseplayer
|
||||
DeveloperMode:
|
||||
PlayerResources:
|
||||
DefaultCash: 5000
|
||||
ResourceValues:
|
||||
Wax: 25
|
||||
PowerManager:
|
||||
|
||||
editorplayer:
|
||||
Inherits: ^baseplayer
|
||||
|
||||
@ -29,12 +29,47 @@ world:
|
||||
SpawnMapActors:
|
||||
SpawnStartingUnits:
|
||||
StartingUnits@Vinylgod:
|
||||
BaseActor: vinylgod
|
||||
BaseActor: pressplant
|
||||
SupportActors: ampstack
|
||||
Factions: vinylgod
|
||||
ClassName: options-starting-units.unlabeled
|
||||
BuildingInfluence:
|
||||
PathFinder:
|
||||
Locomotor@WHEELED:
|
||||
Name: wheeled
|
||||
TerrainSpeeds:
|
||||
Clear: 100
|
||||
Wax: 80
|
||||
ResourceLayer:
|
||||
RecalculateResourceDensity: true
|
||||
ResourceTypes:
|
||||
Wax:
|
||||
ResourceIndex: 1
|
||||
TerrainType: Wax
|
||||
AllowedTerrainTypes: Clear
|
||||
MaxDensity: 12
|
||||
ResourceRenderer:
|
||||
ResourceTypes:
|
||||
Wax:
|
||||
Sequences: wax01
|
||||
Name: resource-wax
|
||||
ResourceClaimLayer:
|
||||
|
||||
editorworld:
|
||||
Inherits: ^baseworld
|
||||
EditorResourceLayer:
|
||||
RecalculateResourceDensity: true
|
||||
ResourceTypes:
|
||||
Wax:
|
||||
ResourceIndex: 1
|
||||
TerrainType: Wax
|
||||
AllowedTerrainTypes: Clear
|
||||
MaxDensity: 12
|
||||
ResourceRenderer:
|
||||
ResourceTypes:
|
||||
Wax:
|
||||
Sequences: wax01
|
||||
Name: resource-wax
|
||||
BuildableTerrainOverlay:
|
||||
AllowedTerrainTypes:
|
||||
Palette:
|
||||
|
||||
BIN
mods/vinylgod/sequences/assets/ampstack.png
Normal file
BIN
mods/vinylgod/sequences/assets/ampstack.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 157 B |
BIN
mods/vinylgod/sequences/assets/digger.png
Normal file
BIN
mods/vinylgod/sequences/assets/digger.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 129 B |
BIN
mods/vinylgod/sequences/assets/pressplant.png
Normal file
BIN
mods/vinylgod/sequences/assets/pressplant.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 251 B |
BIN
mods/vinylgod/sequences/assets/vault.png
Normal file
BIN
mods/vinylgod/sequences/assets/vault.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 157 B |
BIN
mods/vinylgod/sequences/assets/wax.png
Normal file
BIN
mods/vinylgod/sequences/assets/wax.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 582 B |
19
mods/vinylgod/sequences/economy.yaml
Normal file
19
mods/vinylgod/sequences/economy.yaml
Normal file
@ -0,0 +1,19 @@
|
||||
resources:
|
||||
wax01:
|
||||
Filename: sequences/assets/wax.png
|
||||
|
||||
digger:
|
||||
idle:
|
||||
Filename: sequences/assets/digger.png
|
||||
|
||||
pressplant:
|
||||
idle:
|
||||
Filename: sequences/assets/pressplant.png
|
||||
|
||||
ampstack:
|
||||
idle:
|
||||
Filename: sequences/assets/ampstack.png
|
||||
|
||||
vault:
|
||||
idle:
|
||||
Filename: sequences/assets/vault.png
|
||||
@ -7,6 +7,8 @@ General:
|
||||
Terrain:
|
||||
TerrainType@Clear:
|
||||
Type: Clear
|
||||
TerrainType@Wax:
|
||||
Type: Wax
|
||||
|
||||
Templates:
|
||||
Template@255:
|
||||
|
||||
77
tools/gen_placeholders.py
Normal file
77
tools/gen_placeholders.py
Normal file
@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generate placeholder sprite PNGs for Phase A (stdlib only).
|
||||
|
||||
OpenRA PngSheet slices multi-frame sheets via an embedded tEXt chunk
|
||||
"FrameSize: w,h" (see engine PngSheetLoader.cs). Real art replaces these in
|
||||
Phase D — keep the filenames.
|
||||
"""
|
||||
import os, struct, zlib
|
||||
|
||||
OUT = os.path.join(os.path.dirname(__file__), '..', 'mods', 'vinylgod', 'sequences', 'assets')
|
||||
|
||||
PINK = (255, 45, 150, 255)
|
||||
DARK = (30, 26, 32, 255)
|
||||
GREY = (90, 85, 95, 255)
|
||||
CLEAR = (0, 0, 0, 0)
|
||||
|
||||
|
||||
def chunk(tag, data):
|
||||
return struct.pack('>I', len(data)) + tag + data + struct.pack('>I', zlib.crc32(tag + data))
|
||||
|
||||
|
||||
def write_png(path, w, h, px, text=None):
|
||||
raw = b''.join(b'\x00' + b''.join(bytes(px[y * w + x]) for x in range(w)) for y in range(h))
|
||||
out = b'\x89PNG\r\n\x1a\n' + chunk(b'IHDR', struct.pack('>IIBBBBB', w, h, 8, 6, 0, 0, 0))
|
||||
for k, v in (text or {}).items():
|
||||
out += chunk(b'tEXt', k.encode() + b'\x00' + v.encode())
|
||||
out += chunk(b'IDAT', zlib.compress(raw)) + chunk(b'IEND', b'')
|
||||
open(path, 'wb').write(out)
|
||||
print(f'wrote {path} {w}x{h}')
|
||||
|
||||
|
||||
def canvas(w, h, fill=CLEAR):
|
||||
return [fill] * (w * h)
|
||||
|
||||
|
||||
def rect(px, w, x0, y0, x1, y1, c):
|
||||
for y in range(y0, y1):
|
||||
for x in range(x0, x1):
|
||||
px[y * w + x] = c
|
||||
|
||||
|
||||
def disc(px, w, cx, cy, r, c):
|
||||
for y in range(int(cy - r), int(cy + r) + 1):
|
||||
for x in range(int(cx - r), int(cx + r) + 1):
|
||||
if (x - cx) ** 2 + (y - cy) ** 2 <= r * r:
|
||||
px[y * w + x] = c
|
||||
|
||||
|
||||
def box_sprite(path, size, body, accent):
|
||||
px = canvas(size, size)
|
||||
m = size // 8
|
||||
rect(px, size, m, m, size - m, size - m, body)
|
||||
rect(px, size, m, m, size - m, m + 2, accent) # top trim
|
||||
disc(px, size, size / 2, size / 2, size // 5, accent) # centre disc
|
||||
write_png(path, size, size, px)
|
||||
|
||||
|
||||
os.makedirs(OUT, exist_ok=True)
|
||||
|
||||
# wax: 12 density frames, 32x32, horizontal strip
|
||||
W, H, N = 32, 32, 12
|
||||
px = canvas(W * N, H)
|
||||
blob = [(9, 9), (22, 12), (14, 21), (24, 24), (7, 24), (17, 7), (26, 17), (11, 15),
|
||||
(20, 19), (15, 27), (5, 16), (27, 8)]
|
||||
for f in range(N):
|
||||
for i in range(f + 1):
|
||||
cx, cy = blob[i]
|
||||
for dx in range(W): # draw into frame f's slice
|
||||
pass
|
||||
gx = f * W + cx
|
||||
disc(px, W * N, gx, cy, 3, PINK if i % 3 == 0 else DARK)
|
||||
write_png(os.path.join(OUT, 'wax.png'), W * N, H, px, text={'FrameSize': '32,32'})
|
||||
|
||||
box_sprite(os.path.join(OUT, 'digger.png'), 24, PINK, DARK)
|
||||
box_sprite(os.path.join(OUT, 'pressplant.png'), 64, DARK, PINK)
|
||||
box_sprite(os.path.join(OUT, 'ampstack.png'), 32, GREY, PINK)
|
||||
box_sprite(os.path.join(OUT, 'vault.png'), 32, DARK, GREY)
|
||||
30
tools/seed_wax.py
Normal file
30
tools/seed_wax.py
Normal file
@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Seed Wax resource cells into an OpenRA map.bin (format 2, no height data).
|
||||
|
||||
Layout (engine Map.cs SaveBinaryData): u8 fmt, u16 w, u16 h, u32 tilesOff(17),
|
||||
u32 heightsOff(0), u32 resOff; tiles = w*h*(u16,u8) column-major (i*h+j);
|
||||
resources = w*h*(u8 type, u8 density), same order.
|
||||
|
||||
Usage: seed_wax.py <map.bin> cx,cy,r [cx,cy,r ...] (circular blobs, density
|
||||
scales down toward each blob's edge; type byte 1 = Wax ResourceIndex)
|
||||
"""
|
||||
import struct, sys
|
||||
|
||||
path = sys.argv[1]
|
||||
data = bytearray(open(path, 'rb').read())
|
||||
fmt, w, h = data[0], *struct.unpack_from('<HH', data, 1)
|
||||
tiles_off, heights_off, res_off = struct.unpack_from('<III', data, 5)
|
||||
assert fmt == 2 and heights_off == 0 and res_off == 3 * w * h + 17, 'unexpected map format'
|
||||
|
||||
for spec in sys.argv[2:]:
|
||||
cx, cy, r = map(int, spec.split(','))
|
||||
for x in range(cx - r, cx + r + 1):
|
||||
for y in range(cy - r, cy + r + 1):
|
||||
d2 = (x - cx) ** 2 + (y - cy) ** 2
|
||||
if d2 <= r * r and 0 <= x < w and 0 <= y < h:
|
||||
density = max(2, round(12 * (1 - (d2 ** 0.5) / (r + 1))))
|
||||
o = res_off + 2 * (x * h + y)
|
||||
data[o], data[o + 1] = 1, density
|
||||
|
||||
open(path, 'wb').write(data)
|
||||
print(f'{path}: seeded {len(sys.argv) - 2} blob(s) on {w}x{h} map')
|
||||
Loading…
Reference in New Issue
Block a user