Skip to content

Commit

Permalink
(station) west square objects & bus stops, part III (#73)
Browse files Browse the repository at this point in the history
  • Loading branch information
ahyangyi authored Dec 13, 2024
1 parent 59b8ce7 commit cab7d34
Show file tree
Hide file tree
Showing 31 changed files with 647 additions and 332 deletions.
14 changes: 14 additions & 0 deletions agrf/gorender/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,3 +148,17 @@ def discard_layers(discards, vox_path, new_path):
+ [x for discard in discards for x in ["--discard", discard]],
check=True,
)


def keep_layers(keeps, vox_path, new_path):
try:
if os.path.getmtime(vox_path) < os.path.getmtime(new_path):
return
except:
pass
os.makedirs(os.path.dirname(new_path), exist_ok=True)
subprocess.run(
["layer-filter", "--source", vox_path, "--destination", new_path]
+ [x for keep in keeps for x in ["--keep", keep]],
check=True,
)
13 changes: 13 additions & 0 deletions agrf/graphics/voxel.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
self_compose,
produce_empty,
discard_layers,
keep_layers,
)
from agrf.graphics.rotator import unnatural_dimens
from agrf.graphics.spritesheet import spritesheet_template
Expand Down Expand Up @@ -185,6 +186,18 @@ def voxel_getter():
self.name, prefix=os.path.join(self.prefix, suffix), voxel_getter=voxel_getter, config=deepcopy(self.config)
)

@functools.cache
def keep_layers(self, keeps, suffix):
def voxel_getter():
old_path = self.voxel_getter()
new_path = os.path.join(self.prefix, suffix, f"{self.name}.vox")
keep_layers(keeps, old_path, new_path)
return new_path

return LazyVoxel(
self.name, prefix=os.path.join(self.prefix, suffix), voxel_getter=voxel_getter, config=deepcopy(self.config)
)

@functools.cache
def squash(self, ratio, suffix):
new_config = deepcopy(self.config)
Expand Down
19 changes: 13 additions & 6 deletions agrf/lib/building/demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,22 @@ class Demo:
subclimate: str = "default"
merge_bbox: bool = False

def to_layout(self):
sprites = []
rows = len(self.tiles)
columns = len(self.tiles[0])
for r, row in enumerate(self.tiles):
for c, sprite in enumerate(row[::-1]):
if sprite is not None:
sprites.extend(
sprite.demo_translate(c * 16 - (columns - 1) * 8, r * 16 - (rows - 1) * 8).parent_sprites
)
return ALayout(None, sprites, False)

def graphics(self, scale, bpp, remap=None):
remap = remap or self.remap
if self.merge_bbox:
sprites = []
for r, row in enumerate(self.tiles):
for c, sprite in enumerate(row[::-1]):
if sprite is not None:
sprites.extend(sprite.demo_translate(c, r).parent_sprites)
return ALayout(None, sprites, False).graphics(scale, bpp, remap)
return self.to_layout().graphics(scale, bpp, remap, climate=self.climate, subclimate=self.subclimate)
yofs = 32 * scale
img = LayeredImage.canvas(
-16 * scale * (len(self.tiles) + len(self.tiles[0])),
Expand Down
8 changes: 8 additions & 0 deletions agrf/lib/building/image_sprite.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import grf
from agrf.graphics import SCALE_TO_ZOOM


def image_sprite(path):
return grf.AlternativeSprites(
grf.FileSprite(grf.ImageFile(path), 0, 0, 256, 127, xofs=-124, yofs=0, bpp=32, zoom=SCALE_TO_ZOOM[4])
)
19 changes: 13 additions & 6 deletions agrf/lib/building/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,21 @@ def __init__(self, sprite, *args, **kwargs):
for climate in ["temperate", "arctic", "tropical", "toyland"]
for k in [1011, 1012, 1037, 1038, 3981, 4550]
}
climate_independent_tiles = {k: load_third_party_image(f"third_party/opengfx2/{k}.png") for k in [1313, 1314, 1420]}
climate_independent_tiles = {
k: load_third_party_image(f"third_party/opengfx2/{k}.png") for k in [1313, 1314, 1320, 1321, 1420]
}

def graphics(self, scale, bpp, climate="temperate", subclimate="default"):
# FIXME handle flags correctly
if self.sprite in self.climate_independent_tiles:
img = np.asarray(self.climate_independent_tiles[self.sprite])
else:
img = np.asarray(
self.climate_dependent_tiles[(climate, self.sprite + (26 if subclimate != "default" else 0))]
)
if self.sprite == 3981:
img = np.asarray(self.climate_dependent_tiles[(climate, 4550 if subclimate != "default" else 3981)])
else:
img = np.asarray(
self.climate_dependent_tiles[(climate, self.sprite + (26 if subclimate != "default" else 0))]
)
ret = LayeredImage(-124, 0, 256, 127, img[:, :, :3], img[:, :, 3], None)
if scale == 4:
ret = ret.copy()
Expand Down Expand Up @@ -254,7 +259,7 @@ def demo_translate(self, xofs, yofs, zofs):
return ADefaultParentSprite(
self.sprite,
self.extent,
(self.offset[0] + xofs * 16, self.offset[1] + yofs * 16, self.offset[2] + zofs * 8),
(self.offset[0] + xofs, self.offset[1] + yofs, self.offset[2] + zofs * 8),
self.child_sprites,
self.flags,
)
Expand Down Expand Up @@ -379,7 +384,7 @@ def demo_translate(self, xofs, yofs, zofs):
return AParentSprite(
self.sprite,
self.extent,
(self.offset[0] + xofs * 16, self.offset[1] + yofs * 16, self.offset[2] + zofs * 8),
(self.offset[0] + xofs, self.offset[1] + yofs, self.offset[2] + zofs * 8),
self.child_sprites,
self.flags,
)
Expand Down Expand Up @@ -501,6 +506,8 @@ def graphics(self, scale, bpp, climate="temperate", subclimate="default"):

if self.flags.get("dodraw") == Registers.SNOW and subclimate != "snow":
return LayeredImage.empty()
if self.flags.get("dodraw") == Registers.NOSNOW and subclimate == "snow":
return LayeredImage.empty()
return LayeredImage.from_sprite(self.sprite.get_sprite(zoom=SCALE_TO_ZOOM[scale], bpp=bpp))

@functools.cache
Expand Down
19 changes: 2 additions & 17 deletions agrf/lib/building/layout_test.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import grf
from agrf.lib.building.layout import AGroundSprite, ADefaultGroundSprite, ALayout
from agrf.lib.building.symmetry import BuildingSymmetrical
from agrf.pkg import load_third_party_image
from agrf.lib.building.image_sprite import image_sprite
from agrf.graphics.misc import SCALE_TO_ZOOM


Expand All @@ -26,22 +26,7 @@ def test_default_groundsprite():


def test_groundsprite():
gs1012 = AGroundSprite(
grf.AlternativeSprites(
grf.FileSprite(
grf.ImageFile("agrf/third_party/opengfx2/temperate/1012.png"),
0,
0,
256,
127,
xofs=124,
yofs=0,
bpp=32,
zoom=SCALE_TO_ZOOM[4],
)
)
)

gs1012 = AGroundSprite(image_sprite("agrf/third_party/opengfx2/temperate/1012.png"))
graphics = gs1012.graphics(4, 32).to_image()
assert graphics.shape == (127, 256, 4)
assert graphics[64, 128, 1] == 67
Expand Down
6 changes: 6 additions & 0 deletions agrf/magic/switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ def fmap(self, f):
subroutines=self.subroutines,
)

def lookup(self, x):
for r in self._ranges:
if r.low <= x <= r.high:
return r.ref
return self.default

# FIXME: should probably be refactored into something more general
# and not rely on everything else implementing `get_default_graphics`
def get_default_graphics(self):
Expand Down
Binary file added agrf/third_party/opengfx2/1320.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added agrf/third_party/opengfx2/1321.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion grfobject/lib/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
from .object import AObject
from .switch import GraphicalSwitch
from .switch import GraphicalSwitch, PositionSwitch
1 change: 1 addition & 0 deletions grfobject/lib/object.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ def get_sprites(self, g, sprites=None):
default=layouts[0],
code="""
TEMP[0x03] = (terrain_type & 0x4) == 0x4
TEMP[0x04] = (terrain_type & 0x4) != 0x4
view
""",
)
Expand Down
95 changes: 95 additions & 0 deletions grfobject/lib/switch.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import grf
from agrf.magic import Switch
from agrf.utils import unique_tuple

Expand All @@ -11,3 +12,97 @@ def __init__(self, code, ranges, default, *, feature=None, ref_id=None, related_
@property
def sprites(self):
return unique_tuple([s for sw in [self.default] + [r.ref for r in self._ranges] for s in sw.sprites])


class PositionSwitch(GraphicalSwitch):
def __init__(
self,
code,
ranges,
default,
*,
feature=None,
ref_id=None,
related_scope=False,
subroutines=None,
rows=1,
columns=1
):
super().__init__(
code, ranges, default, feature=feature, ref_id=ref_id, related_scope=related_scope, subroutines=subroutines
)
self.rows = rows
self.columns = columns

def fmap(self, f):
return type(self)(
self.code,
{(r.low, r.high): f(r.ref) for r in self._ranges},
f(self.default),
feature=self.feature,
ref_id=self.ref_id,
related_scope=self.related_scope,
subroutines=self.subroutines,
rows=self.rows,
columns=self.columns,
)

def to_lists(self):
return [[self.lookup(r * 256 + self.columns - 1 - c) for c in range(self.columns)] for r in range(self.rows)]

@staticmethod
def __index_M(p):
x, y = p // 256, p % 256
return y * 256 + x

@property
def M(self):
return type(self)(
self.code,
{self.__index_M(p): r.ref.M for r in self._ranges for p in range(r.low, r.high + 1)},
self.default.M,
feature=self.feature,
ref_id=self.ref_id,
related_scope=self.related_scope,
subroutines=self.subroutines,
rows=self.columns,
columns=self.rows,
)

@staticmethod
def __index_R(p, c):
x, y = p // 256, p % 256
return x * 256 + (c - 1 - y)

@property
def R(self):
return type(self)(
self.code,
{self.__index_R(p, self.columns): r.ref.R for r in self._ranges for p in range(r.low, r.high + 1)},
self.default.R,
feature=self.feature,
ref_id=self.ref_id,
related_scope=self.related_scope,
subroutines=self.subroutines,
rows=self.rows,
columns=self.columns,
)

@staticmethod
def __index_T(p, r):
x, y = p // 256, p % 256
return (r - x - 1) * 256 + y

@property
def T(self):
return type(self)(
self.code,
{self.__index_T(p, self.rows): r.ref.T for r in self._ranges for p in range(r.low, r.high + 1)},
self.default.T,
feature=self.feature,
ref_id=self.ref_id,
related_scope=self.related_scope,
subroutines=self.subroutines,
rows=self.rows,
columns=self.columns,
)
2 changes: 1 addition & 1 deletion install-go-dependencies.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ go install github.com/ahyangyi/gorender/cmd@cdca513
mv gopath/bin/cmd gopath/bin/gorender
go install github.com/ahyangyi/cargopositor/cmd@f9051fa
mv gopath/bin/cmd gopath/bin/positor
go install github.com/ahyangyi/gandalf/cmd@d0c1c3d
go install github.com/ahyangyi/gandalf/cmd@c363ea1
mv gopath/bin/cmd gopath/bin/layer-filter
6 changes: 4 additions & 2 deletions station/files/cns-palette-hard.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,14 @@
{
"_comment": "forest greens",
"start": 88,
"end": 95
"end": 95,
"smoothness": -2
},
{
"_comment": "mint greens",
"start": 96,
"end": 103
"end": 103,
"smoothness": -2
},
{
"_comment": "forest browns",
Expand Down
8 changes: 6 additions & 2 deletions station/lang/chinese.lng
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,12 @@ STR_STATION_CLASS_E7B981W :{PUSH_COLOUR}{WHITE}CNS:{POP_COLOUR}繁昌西

STR_STATION_CLASS_E88A9CP :{PUSH_COLOUR}{WHITE}CNS:{POP_COLOUR}芜湖包 - 站台

STR_OBJECT_CLASS_E88A9CZ :{PUSH_COLOUR}{WHITE}CNS:{POP_COLOUR}芜湖站 - 广场
STR_ROADSTOP_CLASS_E88A9CR :{PUSH_COLOUR}{WHITE}CNS:{POP_COLOUR}芜湖站
STR_OBJECT_CLASS_E88A9CG :{PUSH_COLOUR}{WHITE}|>{POP_COLOUR} 芜湖站 - 西广场 - 地面
STR_OBJECT_CLASS_E88A9CF :{PUSH_COLOUR}{WHITE}|>{POP_COLOUR} 芜湖站 - 西广场 - 绿雕
STR_OBJECT_CLASS_E88A9Cl :{PUSH_COLOUR}{WHITE}|>{POP_COLOUR} 芜湖站 - 西广场 - 草坪
STR_OBJECT_CLASS_E88A9CL :{PUSH_COLOUR}{WHITE}|>{POP_COLOUR} 芜湖站 - 西广场 - 路灯
STR_OBJECT_CLASS_E88A9CM :{PUSH_COLOUR}{WHITE}|>{POP_COLOUR} 芜湖站 - 西广场 - 综合
STR_ROADSTOP_CLASS_E88A9CR :{PUSH_COLOUR}{WHITE}|>{POP_COLOUR} 芜湖站

STR_METASTATION_CLASS_E88A9CA :芜湖站 (2015)
STR_METASTATION_CLASS_E88A9Ca :芜湖站 (1992)
Expand Down
6 changes: 5 additions & 1 deletion station/lang/english-uk.lng
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,11 @@ STR_STATION_CLASS_E7B981W :{PUSH_COLOUR}{WHITE}CNS:{POP_COLOUR} Fanchang W

STR_STATION_CLASS_E88A9CP :{PUSH_COLOUR}{WHITE}CNS:{POP_COLOUR} Wuhu - Extra Platforms

STR_OBJECT_CLASS_E88A9CZ :{PUSH_COLOUR}{WHITE}CNS:{POP_COLOUR} Wuhu - Plaza
STR_OBJECT_CLASS_E88A9CG :{PUSH_COLOUR}{WHITE}|>{POP_COLOUR} West Square - Ground
STR_OBJECT_CLASS_E88A9CF :{PUSH_COLOUR}{WHITE}|>{POP_COLOUR} West Square - Topiary
STR_OBJECT_CLASS_E88A9Cl :{PUSH_COLOUR}{WHITE}|>{POP_COLOUR} West Square - Lawn
STR_OBJECT_CLASS_E88A9CL :{PUSH_COLOUR}{WHITE}|>{POP_COLOUR} West Square - Light Post
STR_OBJECT_CLASS_E88A9CM :{PUSH_COLOUR}{WHITE}|>{POP_COLOUR} West Square - Mixed
STR_ROADSTOP_CLASS_E88A9CR :{PUSH_COLOUR}{WHITE}CNS:{POP_COLOUR} Wuhu

STR_METASTATION_CLASS_E88A9CA :Wuhu Station (2015)
Expand Down
2 changes: 2 additions & 0 deletions station/lib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
BuildingSymmetricalX,
BuildingSymmetricalY,
BuildingRotational,
BuildingRotational4,
BuildingDiagonal,
BuildingDiagonalAlt,
BuildingDiamond,
BuildingCylindrical,
)
Expand Down
2 changes: 2 additions & 0 deletions station/lib/registers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ class Registers:
CLIMATE_RAIL_OFFSET = grf.Temp(1)
CLIMATE_OFFSET = grf.Temp(2)
SNOW = grf.Temp(3)
NOSNOW = grf.Temp(4)


code = """
TEMP[0x00] = 0
TEMP[0x01] = (26 * ((terrain_type & 0x5) > 0) + 82 * (max(track_type, 1) - 1)) * (track_type <= 3)
TEMP[0x02] = 569 * ((terrain_type & 0x5) > 0)
TEMP[0x03] = (terrain_type & 0x4) == 0x4
TEMP[0x04] = (terrain_type & 0x4) != 0x4
"""
3 changes: 1 addition & 2 deletions station/stations/dovemere_2018_lib/demos/west_plaza.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@

# Objects
center_ground = west_plaza_center.lower_tile()
west_square = [[center_ground] * 7, [center_ground] * 7]

west_square = [[center_ground] * 7] * 2

west_plaza = Demo(
station + roadstops + west_square, "West plaza", remap=get_1cc_remap(CompanyColour.WHITE), merge_bbox=True
Expand Down
Loading

0 comments on commit cab7d34

Please sign in to comment.