Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/package-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ name: package-macOS
on:
workflow_dispatch:
push:
branches: [ master ]
branches: [ master, dev-master ]
pull_request:
branches: [ master ]
branches: [ master, dev-master ]

# Minimalne uprawnienia
permissions:
Expand Down
28 changes: 27 additions & 1 deletion app/assets/css/app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8296,7 +8296,7 @@ dl.form.fieldInstanceEditor {
li.value {
display: grid;
align-items: center;
grid-template-columns: min-content 32px 64px 32px auto min-content;
grid-template-columns: min-content 32px 64px 32px auto min-content min-content;
gap: 4px;

input[type=color] {
Expand Down Expand Up @@ -8329,6 +8329,32 @@ dl.form.fieldInstanceEditor {
}
}

a.landWall {
display: flex;
align-items: center;
justify-content: center;
width: 28px;
height: 28px;
border-radius: 3px;
cursor: pointer;
background-color: rgba(0, 0, 0, 0.3);
border: 1px solid transparent;

&:hover {
background-color: rgba(255, 255, 255, 0.1);
}

&.on {
background-color: rgba(200, 100, 50, 0.5);
border-color: rgba(255, 150, 100, 0.5);
}

.icon {
width: 16px;
height: 16px;
}
}

button.remove {
align-self: stretch;
padding: 0;
Expand Down
3 changes: 2 additions & 1 deletion app/assets/tpl/editLayerDefs.html
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ <h2>

<label class="Tiles AutoLayer IntGrid" for="pathfindingCollisionLayer" title="If enabled, this layer will be considered non-traversable for pathfinding purposes.">
<input type="checkbox" name="pathfindingCollisionLayer" class="small" id="pathfindingCollisionLayer"/>
Pathfinding non-traversable layer
Ships pathfinding non-traversable layer
</label>
</dd>

Expand Down Expand Up @@ -240,6 +240,7 @@ <h2>
<input type="color" value="#ffffff"/>
<span class="tile"></span>
<input type="text" class="name" placeholder="Optional value identifier"/>
<a class="landWall" title="Mark as non-traversable for land units (land walls)"><span class="icon"></span></a>
<button class="red remove"><span class="icon delete"></span></button>
</xml>
</dd>
Expand Down
1 change: 1 addition & 0 deletions src/electron.renderer/data/DataTypes.hx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ typedef IntGridValueDefEditor = {
var color : dn.Col;
var tile : Null<ldtk.Json.TilesetRect>;
var groupUid : Int;
var landNonTraversable : Bool;
}

enum ValueWrapper {
Expand Down
112 changes: 107 additions & 5 deletions src/electron.renderer/data/Level.hx
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ class Level {

customFields: {},
layers : {},
intGridCsv : {},
entities : {},
}

Expand Down Expand Up @@ -275,16 +276,28 @@ class Level {
for (ruleMap in li.autoTilesCache) {
for (coordMap in ruleMap) {
for (tile in coordMap) {
layerArray.push({
var o : Dynamic = {
x: tile.x + li.pxTotalOffsetX,
y: tile.y + li.pxTotalOffsetY,
tileNumber: tile.tid
});
tileNumber: tile.tid,
};
if( tile.flips!=0 )
Reflect.setField(o, "flip", tile.flips);
layerArray.push(o);
}
}
}
}

// Export intGridCsv for IntGrid layers
if( li.def.type == IntGrid ) {
var csv : Array<Int> = [];
for(cy in 0...li.cHei)
for(cx in 0...li.cWid)
csv.push( li.getIntGrid(cx,cy) );
Reflect.setField(simpleJson.intGridCsv, li.def.identifier, csv);
}

// Export auto-layer entity-mode results grouped by rule group name
if( (li.def.type == AutoLayer || li.def.type == IntGrid) && li.autoEntitiesCache != null ) {
for( ruleEntry in li.autoEntitiesCache.keyValueIterator() ) {
Expand All @@ -311,8 +324,8 @@ class Level {

entsArray.push({
id: ed.identifier,
x: eInf.x + li.pxTotalOffsetX,
y: eInf.y + li.pxTotalOffsetY,
x: eInf.x + li.pxTotalOffsetX + worldX,
y: eInf.y + li.pxTotalOffsetY + worldY,
});
}
}
Expand Down Expand Up @@ -966,4 +979,93 @@ class Level {

return this.collisionLayer;
}

/** Generate land walls based on IntGrid values and rules marked as landNonTraversable **/
public function generateLandWalls() : Array<Array<Int>> {
var gridSize = _project.defaultGridSize;
var cWid = M.ceil(pxWid / gridSize);
var cHei = M.ceil(pxHei / gridSize);

// Initialize empty 2D array
var landWalls : Array<Array<Int>> = [];
for (y in 0...cHei) {
var row = [];
for (x in 0...cWid) {
row.push(0);
}
landWalls.push(row);
}

// Iterate through all layers
for (li in layerInstances) {
if (li.def.type == IntGrid) {
// Check IntGrid values marked as landNonTraversable
for (cy in 0...li.cHei) {
for (cx in 0...li.cWid) {
var value = li.getIntGrid(cx, cy);
if (value > 0) {
var valueDef = li.def.getIntGridValueDef(value);
if (valueDef != null && valueDef.landNonTraversable) {
if (cy < cHei && cx < cWid) {
landWalls[cy][cx] = 1;
}
}
}
}
}
}

// Check auto-layer rules marked as landNonTraversable
if (li.def.isAutoLayer() && li.autoTilesCache != null) {
for (rg in li.def.autoRuleGroups) {
for (r in rg.rules) {
if (!r.landNonTraversable || !r.active)
continue;

if (!li.autoTilesCache.exists(r.uid))
continue;

var ruleResults = li.autoTilesCache.get(r.uid);
for (coordId in ruleResults.keys()) {
var tiles = ruleResults.get(coordId);
for (t in tiles) {
var cx = Std.int(t.x / li.def.gridSize);
var cy = Std.int(t.y / li.def.gridSize);
if (cy >= 0 && cy < cHei && cx >= 0 && cx < cWid) {
landWalls[cy][cx] = 1;
}
}
}
}
}
}

// Check auto-layer entity rules marked as landNonTraversable
if (li.def.isAutoLayer() && li.autoEntitiesCache != null) {
for (rg in li.def.autoRuleGroups) {
for (r in rg.rules) {
if (!r.landNonTraversable || !r.active || !r.entityMode)
continue;

if (!li.autoEntitiesCache.exists(r.uid))
continue;

var entityResults = li.autoEntitiesCache.get(r.uid);
for (coordId in entityResults.keys()) {
var entities = entityResults.get(coordId);
for (e in entities) {
var cx = Std.int(e.x / li.def.gridSize);
var cy = Std.int(e.y / li.def.gridSize);
if (cy >= 0 && cy < cHei && cx >= 0 && cx < cWid) {
landWalls[cy][cx] = 1;
}
}
}
}
}
}
}

return landWalls;
}
}
7 changes: 7 additions & 0 deletions src/electron.renderer/data/def/AutoLayerRuleDef.hx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ class AutoLayerRuleDef {
public var entityMode = false;
public var entityDefUids : Array<Int> = [];

// Land non-traversable (for land walls export)
public var landNonTraversable = false;

var perlinActive = false;
public var perlinSeed : Int;
public var perlinScale : Float = 0.2;
Expand Down Expand Up @@ -185,6 +188,7 @@ class AutoLayerRuleDef {
// Add entity fields dynamically (not part of ldtk.Json.AutoRuleDef)
Reflect.setField(json, "entityMode", entityMode);
Reflect.setField(json, "entityDefUids", entityDefUids.copy());
Reflect.setField(json, "landNonTraversable", landNonTraversable);

return json;
}
Expand Down Expand Up @@ -239,6 +243,9 @@ class AutoLayerRuleDef {
r.entityMode = JsonTools.readBool( (cast json).entityMode, false );
r.entityDefUids = JsonTools.readArray( (cast json).entityDefUids, [] );

// Land non-traversable
r.landNonTraversable = JsonTools.readBool( (cast json).landNonTraversable, false );

r.updateUsedValues();

return r;
Expand Down
3 changes: 3 additions & 0 deletions src/electron.renderer/data/def/LayerDef.hx
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ class LayerDef {
color: JsonTools.readColor(v.color),
tile: JsonTools.readTileRect(v.tile, true),
groupUid: JsonTools.readInt(v.groupUid, 0),
landNonTraversable: JsonTools.readBool(untyped v.landNonTraversable, false),
});
fixedIdx++;
}
Expand Down Expand Up @@ -208,6 +209,7 @@ class LayerDef {
color: JsonTools.writeColor(iv.color),
tile: JsonTools.writeTileRect(iv.tile),
groupUid: iv.groupUid,
landNonTraversable: iv.landNonTraversable,
}),

intGridValuesGroups: intGridValuesGroups.map(g->{
Expand Down Expand Up @@ -301,6 +303,7 @@ class LayerDef {
identifier: id,
tile: null,
groupUid: 0,
landNonTraversable: false,
});

return iv;
Expand Down
44 changes: 44 additions & 0 deletions src/electron.renderer/exporter/Walls.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package exporter;

class Walls extends Exporter {
public function new() {
super();
}

override function convert() {
super.convert();

setOutputPath( p.getAbsExternalFilesDir() + "/walls", true );

for(w in p.worlds)
for(l in w.levels) {
// Generate sea walls (from pathfinding collision layers)
l.generateCombinedCollisionLayer();
var seaWalls:Array<Array<Int>> = [];
if( l.collisionLayer != null ) {
for(y in 0...l.collisionLayer.length) {
var row = l.collisionLayer[y];
for(x in 0...row.length)
if( row[x] == 1 )
seaWalls.push([x+1, y+1]);
}
}

// Generate land walls (from landNonTraversable IntGrid values and rules)
var landWallsGrid = l.generateLandWalls();
var landWalls:Array<Array<Int>> = [];
for(y in 0...landWallsGrid.length) {
var row = landWallsGrid[y];
for(x in 0...row.length)
if( row[x] == 1 )
landWalls.push([x+1, y+1]);
}

var fp = outputPath.clone();
fp.fileName = l.identifier;
fp.extension = "json";
var json = dn.data.JsonPretty.stringify({ sea_walls:seaWalls, land_walls:landWalls }, Minified);
addOuputFile(fp.full, haxe.io.Bytes.ofString(json));
}
}
}
1 change: 1 addition & 0 deletions src/electron.renderer/misc/JsTools.hx
Original file line number Diff line number Diff line change
Expand Up @@ -1461,6 +1461,7 @@ class JsTools {
color: dn.Col.parseHex(rawIv.color),
tile: rawIv.tile,
groupUid: 0,
landNonTraversable: false,
}

var jVal = new J('<div class="intGridValue"></div>');
Expand Down
29 changes: 7 additions & 22 deletions src/electron.renderer/ui/ProjectSaver.hx
Original file line number Diff line number Diff line change
Expand Up @@ -542,28 +542,13 @@ class ProjectSaver extends dn.Process {
});

// Write walls JSONs
for(w in project.worlds)
for(l in w.levels) {
var l = l;
ops.push({
label: "Walls "+l.identifier,
cb: ()->{
l.generateCombinedCollisionLayer();
var walls:Array<Array<Int>> = [];
if( l.collisionLayer != null ) {
for(y in 0...l.collisionLayer.length) {
var row = l.collisionLayer[y];
for(x in 0...row.length)
if( row[x] == 1 )
walls.push([x+1, y+1]);
}
}
var wallsFp = wallsDirFp.clone();
wallsFp.fileWithExt = l.identifier + ".json";
NT.writeFileString(wallsFp.full, dn.data.JsonPretty.stringify({ walls:walls }, Minified));
},
});
}
ops.push({
label: "Exporting walls...",
cb: () -> {
var e = new exporter.Walls();
e.run(project, project.filePath.full);
}
});

// Write simplified level files
for(w in project.worlds)
Expand Down
Loading
Loading