Phase B: production loop — MCV pop-up van, conyard, classic queues, sidebar palette, buildable roster

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
type-two 2026-07-20 04:27:37 +10:00
parent 86ca71b9a2
commit 71879139c2
27 changed files with 357 additions and 26 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 305 B

View File

@ -389,3 +389,16 @@ editor:
tools: 136, 68, 16, 16
history: 136, 51, 16, 16
erase: 50, 187, 16, 16
production-icons:
Image: chrome/assets/production-icons.png
Regions:
building: 0, 0, 16, 16
building-disabled: 16, 0, 16, 16
building-alert: 32, 0, 16, 16
infantry: 0, 16, 16, 16
infantry-disabled: 16, 16, 16, 16
infantry-alert: 32, 16, 16, 16
vehicle: 0, 32, 16, 16
vehicle-disabled: 16, 32, 16, 16
vehicle-alert: 32, 32, 16, 16

View File

@ -16,3 +16,57 @@ Container@PLAYER_WIDGETS:
Height: 23
Align: Right
Font: TinyBold
Container@SIDEBAR_PRODUCTION:
Logic: ClassicProductionLogic
X: WINDOW_WIDTH - 240
Y: 45
Width: 232
Height: WINDOW_HEIGHT - 60
Children:
LogicTicker@PRODUCTION_TICKER:
ProductionPalette@PRODUCTION_PALETTE:
X: 34
Y: 1
Columns: 3
IconSize: 64, 48
IconMargin: 1, 1
ReadyText: production-ready
HoldText: production-hold
Container@PRODUCTION_TYPES:
X: 0
Y: 1
Width: 30
Height: 96
Children:
ProductionTypeButton@BUILDING:
Width: 30
Height: 30
Background: button
ProductionGroup: Building
Children:
Image@ICON:
X: 7
Y: 7
ImageCollection: production-icons
ProductionTypeButton@INFANTRY:
Y: 33
Width: 30
Height: 30
Background: button
ProductionGroup: Infantry
Children:
Image@ICON:
X: 7
Y: 7
ImageCollection: production-icons
ProductionTypeButton@VEHICLE:
Y: 66
Width: 30
Height: 30
Background: button
ProductionGroup: Vehicle
Children:
Image@ICON:
X: 7
Y: 7
ImageCollection: production-icons

View File

@ -12,3 +12,7 @@ Cursors:
Start: 0
move-blocked:
Start: 0
deploy:
Start: 0
deploy-blocked:
Start: 0

View File

@ -5,3 +5,7 @@ mod-windowtitle = Vinylgod
# To silence "Warning: Missing key `loadscreen-loading` in mod ftl files required by `LogoStripeLoadScreen.Loading`"
# Because https://github.com/OpenRA/OpenRA/issues/20693 wasn't fixed.
loadscreen-loading = .
## chrome (production palette)
production-ready = READY
production-hold = ON HOLD

View File

@ -21,3 +21,15 @@ actor-vault =
## world.yaml (resources)
resource-wax = Black Wax
## economy.yaml (phase B)
actor-popupvan =
.name = Pop-Up Van
actor-popupshop =
.name = Pop-Up Shop
actor-merchtable =
.name = Merch Table
actor-garage =
.name = Garage
actor-djgrunt =
.name = DJ

View File

@ -8,12 +8,25 @@
HitShape:
HiddenUnderFog:
digger:
^Unit:
Inherits: ^EconSprite
Tooltip:
Name: actor-digger.name
Selectable:
Bounds: 1024, 1024
RevealsShroud:
Range: 5c0
MapEditorData:
Categories: Units
digger:
Inherits: ^Unit
Buildable:
Queue: Vehicle
BuildPaletteOrder: 20
Prerequisites: pressplant
Valued:
Cost: 1400
Tooltip:
Name: actor-digger.name
Health:
HP: 60000
Armor:
@ -30,10 +43,46 @@ digger:
Capacity: 20
Resources: Wax
DockClientManager:
RevealsShroud:
Range: 5c0
MapEditorData:
Categories: Units
popupvan:
Inherits: ^Unit
Buildable:
Queue: Vehicle
BuildPaletteOrder: 30
Prerequisites: garage
Valued:
Cost: 2500
Tooltip:
Name: actor-popupvan.name
Health:
HP: 60000
Armor:
Type: Heavy
Mobile:
Locomotor: wheeled
Speed: 60
Transforms:
IntoActor: popupshop
Offset: 0,0
Facing: 384
djgrunt:
Inherits: ^Unit
Buildable:
Queue: Infantry
BuildPaletteOrder: 10
Prerequisites: merchtable
Valued:
Cost: 100
Tooltip:
Name: actor-djgrunt.name
Health:
HP: 5000
Armor:
Type: None
Mobile:
Locomotor: foot
Speed: 56
^EconBuilding:
Inherits: ^EconSprite
@ -44,19 +93,63 @@ digger:
Type: Wood
RevealsShroud:
Range: 5c0
GivesBuildableArea:
AreaTypes: building
ProvidesPrerequisite@buildingname:
SequencePlaceBuildingPreview:
Sequence: idle
MapEditorData:
Categories: Buildings
pressplant:
Inherits: ^EconBuilding
Tooltip:
Name: actor-pressplant.name
^Buildable2x2:
Selectable:
Bounds: 2048, 2048
Building:
Footprint: xx ==
Footprint: xx xx
Dimensions: 2,2
TerrainTypes: Clear
RequiresBuildableArea:
AreaTypes: building
Adjacent: 4
^Buildable1x1:
Selectable:
Bounds: 1024, 1024
Building:
Footprint: x
Dimensions: 1,1
TerrainTypes: Clear
RequiresBuildableArea:
AreaTypes: building
Adjacent: 4
popupshop:
Inherits: ^EconBuilding
Inherits@shape: ^Buildable2x2
Tooltip:
Name: actor-popupshop.name
Health:
HP: 150000
BaseBuilding:
Production:
Produces: Building
Power:
Amount: 0
-RequiresBuildableArea:
pressplant:
Inherits: ^EconBuilding
Inherits@shape: ^Buildable2x2
Buildable:
Queue: Building
BuildPaletteOrder: 20
Prerequisites: ampstack
Valued:
Cost: 2000
Tooltip:
Name: actor-pressplant.name
Building:
Footprint: xx ==
Refinery:
DockHost:
Type: Unload
@ -71,30 +164,71 @@ pressplant:
ampstack:
Inherits: ^EconBuilding
Inherits@shape: ^Buildable1x1
Buildable:
Queue: Building
BuildPaletteOrder: 10
Valued:
Cost: 300
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
Inherits@shape: ^Buildable1x1
Buildable:
Queue: Building
BuildPaletteOrder: 40
Prerequisites: pressplant
Valued:
Cost: 150
Tooltip:
Name: actor-vault.name
Selectable:
Bounds: 1024, 1024
Health:
HP: 30000
Building:
Footprint: x
Dimensions: 1,1
TerrainTypes: Clear
StoresPlayerResources:
Capacity: 3000
merchtable:
Inherits: ^EconBuilding
Inherits@shape: ^Buildable2x2
Buildable:
Queue: Building
BuildPaletteOrder: 30
Prerequisites: pressplant
Valued:
Cost: 300
Tooltip:
Name: actor-merchtable.name
Health:
HP: 80000
Production:
Produces: Infantry
Exit@1:
ExitCell: 0, 2
Power:
Amount: -10
garage:
Inherits: ^EconBuilding
Inherits@shape: ^Buildable2x2
Buildable:
Queue: Building
BuildPaletteOrder: 50
Prerequisites: pressplant
Valued:
Cost: 2000
Tooltip:
Name: actor-garage.name
Health:
HP: 110000
Production:
Produces: Vehicle
Exit@1:
ExitCell: 0, 2
Power:
Amount: -20

View File

@ -3,6 +3,8 @@
Name: greyscale
PaletteFromGrayscale@terrain:
Name: terrain
PaletteFromGrayscale@chrome:
Name: chrome
PlayerColorPalette@player:
BasePalette: greyscale
PlayerColorShift:

View File

@ -10,6 +10,17 @@ player:
ResourceValues:
Wax: 25
PowerManager:
TechTree:
PlaceBuilding:
ClassicProductionQueue@Building:
Type: Building
Group: Building
ClassicProductionQueue@Vehicle:
Type: Vehicle
Group: Vehicle
ClassicProductionQueue@Infantry:
Type: Infantry
Group: Infantry
editorplayer:
Inherits: ^baseplayer

View File

@ -29,8 +29,8 @@ world:
SpawnMapActors:
SpawnStartingUnits:
StartingUnits@Vinylgod:
BaseActor: pressplant
SupportActors: ampstack
BaseActor: popupvan
SupportActors: digger
Factions: vinylgod
ClassName: options-starting-units.unlabeled
BuildingInfluence:
@ -40,6 +40,12 @@ world:
TerrainSpeeds:
Clear: 100
Wax: 80
Locomotor@FOOT:
Name: foot
SharesCell: true
TerrainSpeeds:
Clear: 100
Wax: 70
ResourceLayer:
RecalculateResourceDensity: true
ResourceTypes:

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 B

View File

@ -2,18 +2,60 @@ resources:
wax01:
Filename: sequences/assets/wax.png
clock:
idle:
Filename: sequences/assets/clock.png
digger:
idle:
Filename: sequences/assets/digger.png
icon:
Filename: sequences/assets/icon_digger.png
popupvan:
idle:
Filename: sequences/assets/popupvan.png
icon:
Filename: sequences/assets/icon_popupvan.png
djgrunt:
idle:
Filename: sequences/assets/djgrunt.png
icon:
Filename: sequences/assets/icon_djgrunt.png
popupshop:
idle:
Filename: sequences/assets/popupshop.png
icon:
Filename: sequences/assets/icon_popupshop.png
pressplant:
idle:
Filename: sequences/assets/pressplant.png
icon:
Filename: sequences/assets/icon_pressplant.png
ampstack:
idle:
Filename: sequences/assets/ampstack.png
icon:
Filename: sequences/assets/icon_ampstack.png
vault:
idle:
Filename: sequences/assets/vault.png
icon:
Filename: sequences/assets/icon_vault.png
merchtable:
idle:
Filename: sequences/assets/merchtable.png
icon:
Filename: sequences/assets/icon_merchtable.png
garage:
idle:
Filename: sequences/assets/garage.png
icon:
Filename: sequences/assets/icon_garage.png

View File

@ -75,3 +75,52 @@ 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)
# Phase B: production actors
GREEN = (80, 200, 120, 255)
BLUE = (80, 140, 220, 255)
GOLD = (230, 190, 60, 255)
box_sprite(os.path.join(OUT, 'popupvan.png'), 24, GOLD, DARK)
box_sprite(os.path.join(OUT, 'popupshop.png'), 64, GOLD, PINK)
box_sprite(os.path.join(OUT, 'merchtable.png'), 32, GREEN, DARK)
box_sprite(os.path.join(OUT, 'garage.png'), 64, BLUE, DARK)
box_sprite(os.path.join(OUT, 'djgrunt.png'), 16, PINK, DARK)
def icon(path, body):
w, h = 64, 48
px = canvas(w, h)
rect(px, w, 2, 2, w - 2, h - 2, DARK)
rect(px, w, 4, 4, w - 4, h - 4, body)
disc(px, w, w / 2, h / 2, 10, DARK)
disc(px, w, w / 2, h / 2, 3, body)
write_png(path, w, h, px)
for name, col in [('popupshop', GOLD), ('ampstack', GREY), ('pressplant', (255, 45, 150, 255)),
('vault', (70, 65, 75, 255)), ('merchtable', GREEN), ('garage', BLUE),
('digger', PINK), ('popupvan', GOLD), ('djgrunt', (255, 120, 180, 255))]:
icon(os.path.join(OUT, f'icon_{name}.png'), col)
# clock overlay for production progress (single frame, semi-transparent)
px = canvas(48, 48, (0, 0, 0, 110))
disc(px, 48, 24, 24, 10, (255, 45, 150, 180))
write_png(os.path.join(OUT, 'clock.png'), 48, 48, px)
# production type tab icons: rows building/infantry/vehicle x cols normal/disabled/alert
# ponytail: 64x64 because chrome textures must be power-of-two
w, h = 64, 64
px = canvas(w, h)
cols = [PINK, GREY, (255, 255, 255, 255)]
for r, shape in enumerate(('rect', 'dot', 'disc')):
for c, col in enumerate(cols):
ox, oy = c * 16, r * 16
if shape == 'rect':
rect(px, w, ox + 3, oy + 3, ox + 13, oy + 13, col)
elif shape == 'dot':
disc(px, w, ox + 8, oy + 8, 3, col)
else:
disc(px, w, ox + 8, oy + 8, 6, col)
disc(px, w, ox + 8, oy + 8, 2, DARK)
CHROME = os.path.join(os.path.dirname(__file__), '..', 'mods', 'vinylgod', 'chrome', 'assets')
write_png(os.path.join(CHROME, 'production-icons.png'), w, h, px)