diff --git a/apps/game/assets/maps/house_elder.map b/apps/game/assets/maps/house_elder.map index 0b18212..845bfe7 100644 --- a/apps/game/assets/maps/house_elder.map +++ b/apps/game/assets/maps/house_elder.map @@ -1 +1 @@ -{"format":"rpg-map","version":1,"width":11,"height":9,"blocked":[2,3,6,7,9,10,18,21],"tall":{"3":{"height":1.5,"ground":0},"6":{"height":2.5,"ground":1},"7":{"height":1.75,"ground":4,"shadow":true},"9":{"height":1,"ground":8},"18":{"height":0.6,"ground":4},"21":{"height":2.5,"ground":8}},"encoding":"rle","tiles":[[9,12],[8,9],[9,2],[8,9],[9,2],[8,9],[9,2],[8,9],[9,2],[8,9],[9,2],[8,9],[9,2],[8,9],[9,6],[8,1],[9,5]]} \ No newline at end of file +{"format":"rpg-map","version":1,"width":11,"height":9,"blocked":[2,3,6,7,9,10,18,21],"tall":{"3":{"height":1.5,"ground":0},"6":{"height":2.5,"ground":1},"7":{"height":1.75,"ground":4,"shadow":true},"9":{"height":1,"ground":8},"18":{"height":0.6,"ground":4},"21":{"height":2.5,"ground":8},"22":{"height":1.5,"ground":0},"23":{"height":1.5,"ground":0}},"encoding":"rle","tiles":[[9,12],[8,9],[9,2],[8,9],[9,2],[8,9],[9,2],[8,9],[9,2],[8,9],[9,2],[8,9],[9,2],[8,9],[9,6],[8,1],[9,5]]} \ No newline at end of file diff --git a/apps/game/assets/maps/machine_hall.map b/apps/game/assets/maps/machine_hall.map index 2a8ca04..4a9119d 100644 --- a/apps/game/assets/maps/machine_hall.map +++ b/apps/game/assets/maps/machine_hall.map @@ -1 +1 @@ -{"format":"rpg-map","version":1,"width":13,"height":11,"blocked":[2,3,6,7,9,10,18,21],"tall":{"3":{"height":1.5,"ground":0},"6":{"height":2.5,"ground":1},"7":{"height":1.75,"ground":4,"shadow":true},"9":{"height":1,"ground":8},"18":{"height":0.6,"ground":4},"21":{"height":2.5,"ground":8}},"encoding":"rle","tiles":[[9,14],[8,4],[21,2],[8,5],[9,2],[8,11],[9,2],[8,5],[19,1],[8,5],[9,2],[8,5],[19,1],[8,5],[9,2],[8,5],[19,1],[8,5],[9,2],[8,5],[19,1],[8,5],[9,2],[8,5],[19,1],[8,5],[9,2],[8,5],[19,1],[8,5],[9,2],[8,5],[19,1],[8,5],[9,7],[8,1],[9,6]]} \ No newline at end of file +{"format":"rpg-map","version":1,"width":13,"height":11,"blocked":[2,3,6,7,9,10,18,21],"tall":{"3":{"height":1.5,"ground":0},"6":{"height":2.5,"ground":1},"7":{"height":1.75,"ground":4,"shadow":true},"9":{"height":1,"ground":8},"18":{"height":0.6,"ground":4},"21":{"height":2.5,"ground":8},"22":{"height":1.5,"ground":0},"23":{"height":1.5,"ground":0}},"encoding":"rle","tiles":[[9,14],[8,4],[21,2],[8,5],[9,2],[8,11],[9,2],[8,5],[19,1],[8,5],[9,2],[8,5],[19,1],[8,5],[9,2],[8,5],[19,1],[8,5],[9,2],[8,5],[19,1],[8,5],[9,2],[8,5],[19,1],[8,5],[9,2],[8,5],[19,1],[8,5],[9,2],[8,5],[19,1],[8,5],[9,7],[8,1],[9,6]]} \ No newline at end of file diff --git a/apps/game/assets/maps/meadows.map b/apps/game/assets/maps/meadows.map index 39d7fa5..261b2fe 100644 --- a/apps/game/assets/maps/meadows.map +++ b/apps/game/assets/maps/meadows.map @@ -1 +1 @@ -{"format":"rpg-map","version":1,"width":28,"height":28,"blocked":[2,3,6,7,9,10,18,21],"tall":{"3":{"height":1.5,"ground":0},"6":{"height":2.5,"ground":1},"7":{"height":1.75,"ground":4,"shadow":true},"9":{"height":1,"ground":8},"18":{"height":0.6,"ground":4},"21":{"height":2.5,"ground":8}},"variants":{"0":[0,11,12],"1":[1,14],"4":[4,13]},"decor":[{"id":16,"x":7,"y":0,"dx":-3,"dy":-2},{"id":17,"x":17,"y":0,"dx":-4,"dy":2},{"id":15,"x":2,"y":1,"dx":1,"dy":0},{"id":16,"x":7,"y":1,"dx":-3,"dy":0},{"id":15,"x":8,"y":1,"dx":-3,"dy":1},{"id":17,"x":17,"y":1,"dx":-2,"dy":-1},{"id":16,"x":25,"y":1,"dx":-2,"dy":-2},{"id":16,"x":26,"y":1,"dx":0,"dy":1},{"id":15,"x":16,"y":2,"dx":3,"dy":1},{"id":16,"x":18,"y":2,"dx":-3,"dy":-1},{"id":17,"x":10,"y":3,"dx":1,"dy":1},{"id":17,"x":11,"y":3,"dx":1,"dy":1},{"id":16,"x":26,"y":3,"dx":-3,"dy":2},{"id":16,"x":7,"y":4,"dx":-3,"dy":1},{"id":16,"x":18,"y":4,"dx":-2,"dy":2},{"id":17,"x":26,"y":4,"dx":-4,"dy":0},{"id":15,"x":11,"y":5,"dx":4,"dy":0},{"id":16,"x":13,"y":8,"dx":-2,"dy":1},{"id":16,"x":15,"y":8,"dx":3,"dy":1},{"id":17,"x":24,"y":8,"dx":-1,"dy":0},{"id":17,"x":6,"y":9,"dx":-1,"dy":-2},{"id":16,"x":13,"y":9,"dx":-3,"dy":0},{"id":17,"x":23,"y":9,"dx":-3,"dy":1},{"id":16,"x":13,"y":10,"dx":0,"dy":0},{"id":15,"x":27,"y":10,"dx":-4,"dy":0},{"id":15,"x":4,"y":11,"dx":-3,"dy":0},{"id":15,"x":10,"y":11,"dx":-2,"dy":2},{"id":16,"x":14,"y":11,"dx":3,"dy":-2},{"id":15,"x":23,"y":11,"dx":-2,"dy":1},{"id":15,"x":0,"y":12,"dx":1,"dy":1},{"id":16,"x":1,"y":12,"dx":1,"dy":1},{"id":15,"x":4,"y":12,"dx":0,"dy":1},{"id":17,"x":1,"y":13,"dx":4,"dy":0},{"id":16,"x":10,"y":13,"dx":4,"dy":0},{"id":16,"x":18,"y":13,"dx":-2,"dy":-2},{"id":16,"x":23,"y":13,"dx":2,"dy":-1},{"id":15,"x":2,"y":14,"dx":0,"dy":1},{"id":17,"x":4,"y":14,"dx":-1,"dy":0},{"id":17,"x":15,"y":14,"dx":-1,"dy":0},{"id":16,"x":16,"y":14,"dx":3,"dy":-1},{"id":16,"x":18,"y":14,"dx":0,"dy":1},{"id":15,"x":24,"y":14,"dx":4,"dy":-1},{"id":15,"x":9,"y":15,"dx":1,"dy":0},{"id":16,"x":12,"y":15,"dx":-4,"dy":-2},{"id":15,"x":13,"y":15,"dx":-2,"dy":1},{"id":17,"x":19,"y":15,"dx":0,"dy":-1},{"id":16,"x":23,"y":15,"dx":3,"dy":-1},{"id":16,"x":27,"y":16,"dx":4,"dy":2},{"id":16,"x":4,"y":17,"dx":1,"dy":-2},{"id":16,"x":13,"y":17,"dx":-2,"dy":-2},{"id":15,"x":20,"y":17,"dx":-2,"dy":0},{"id":15,"x":22,"y":17,"dx":4,"dy":0},{"id":16,"x":5,"y":18,"dx":3,"dy":0},{"id":15,"x":0,"y":19,"dx":-2,"dy":1},{"id":16,"x":8,"y":19,"dx":-3,"dy":0},{"id":15,"x":26,"y":19,"dx":2,"dy":1},{"id":15,"x":18,"y":20,"dx":-3,"dy":0},{"id":15,"x":21,"y":20,"dx":0,"dy":-1},{"id":15,"x":23,"y":20,"dx":0,"dy":2},{"id":16,"x":25,"y":20,"dx":-3,"dy":1},{"id":16,"x":25,"y":21,"dx":-3,"dy":2},{"id":17,"x":0,"y":22,"dx":1,"dy":2},{"id":17,"x":21,"y":22,"dx":3,"dy":2},{"id":15,"x":22,"y":22,"dx":3,"dy":-2},{"id":16,"x":25,"y":22,"dx":1,"dy":1},{"id":16,"x":6,"y":23,"dx":-1,"dy":0},{"id":16,"x":8,"y":23,"dx":-3,"dy":0},{"id":15,"x":12,"y":23,"dx":-3,"dy":0},{"id":16,"x":13,"y":23,"dx":1,"dy":0},{"id":16,"x":6,"y":24,"dx":2,"dy":-1},{"id":17,"x":17,"y":24,"dx":0,"dy":0},{"id":16,"x":6,"y":25,"dx":-4,"dy":2},{"id":16,"x":26,"y":26,"dx":1,"dy":1},{"id":15,"x":1,"y":27,"dx":-2,"dy":-1},{"id":17,"x":10,"y":27,"dx":2,"dy":-1}],"encoding":"rle","tiles":[[0,1],[3,2],[4,1],[0,1],[4,3],[0,1],[4,3],[0,1],[4,1],[0,4],[4,8],[3,1],[4,1],[0,1],[1,1],[0,3],[4,3],[0,2],[4,1],[0,2],[4,1],[0,4],[4,2],[0,1],[4,1],[0,1],[4,4],[0,1],[3,1],[1,2],[0,2],[4,2],[0,3],[4,4],[0,4],[4,1],[0,1],[4,2],[0,1],[4,4],[3,1],[0,2],[1,2],[0,1],[4,2],[0,6],[4,9],[0,1],[4,2],[3,1],[4,2],[3,1],[0,2],[1,2],[0,1],[4,2],[0,5],[4,3],[0,1],[4,2],[0,1],[4,1],[0,1],[4,1],[0,1],[4,2],[0,1],[4,1],[3,1],[0,1],[1,3],[0,8],[4,5],[5,1],[0,5],[4,1],[3,1],[4,2],[0,4],[1,2],[0,1],[4,3],[0,1],[4,1],[0,2],[4,2],[0,1],[4,1],[0,11],[3,1],[0,3],[1,3],[4,2],[0,1],[4,1],[0,1],[4,5],[0,1],[2,4],[0,7],[4,1],[0,1],[4,1],[0,1],[4,1],[1,2],[4,2],[0,2],[4,3],[0,1],[4,1],[0,1],[2,4],[0,3],[3,1],[0,3],[4,1],[3,1],[0,3],[4,1],[1,1],[4,3],[0,1],[4,5],[0,1],[2,2],[0,1],[5,1],[0,7],[3,1],[0,1],[4,1],[0,3],[1,2],[4,2],[0,1],[4,3],[0,8],[3,1],[0,3],[4,1],[3,1],[0,4],[4,3],[1,1],[0,3],[4,5],[0,6],[3,1],[0,2],[3,1],[0,1],[4,1],[3,1],[0,3],[4,3],[1,1],[0,4],[4,5],[0,1],[4,5],[0,1],[4,2],[0,2],[3,1],[0,4],[4,2],[1,1],[4,1],[0,5],[4,3],[0,1],[4,4],[0,3],[3,1],[0,1],[4,1],[0,1],[3,1],[0,4],[4,1],[1,2],[4,2],[0,3],[4,3],[0,1],[4,4],[0,1],[1,2],[4,1],[3,2],[4,1],[0,5],[4,1],[0,1],[1,1],[0,1],[4,1],[0,4],[4,1],[0,2],[4,4],[0,3],[3,2],[0,1],[4,1],[3,1],[0,2],[2,2],[0,2],[1,3],[4,1],[0,6],[4,1],[0,1],[4,4],[0,1],[4,1],[3,1],[0,1],[3,1],[4,3],[2,4],[5,1],[0,1],[1,1],[4,1],[0,13],[3,1],[0,1],[3,1],[4,5],[2,3],[4,2],[1,1],[4,3],[0,4],[4,1],[0,3],[3,1],[0,4],[3,1],[4,1],[3,1],[0,1],[4,4],[0,2],[5,1],[1,2],[4,2],[0,3],[4,3],[0,13],[4,4],[0,1],[4,1],[1,1],[0,5],[4,2],[0,1],[10,1],[0,2],[4,2],[0,1],[3,3],[0,6],[4,1],[0,2],[4,1],[1,3],[0,9],[4,1],[0,5],[3,1],[0,6],[4,4],[0,1],[1,1],[0,8],[4,3],[0,1],[3,1],[0,1],[3,1],[0,3],[4,4],[0,1],[4,1],[0,1],[4,1],[0,1],[1,1],[0,10],[3,1],[0,2],[3,3],[0,2],[4,1],[0,2],[4,5],[0,1],[1,1],[0,9],[4,2],[0,2],[3,1],[0,4],[4,2],[0,7],[1,10],[4,2],[3,1],[0,24],[4,4],[0,2],[3,1],[0,21],[3,4]]} \ No newline at end of file +{"format":"rpg-map","version":1,"width":28,"height":28,"blocked":[2,3,6,7,9,10,18,21],"tall":{"3":{"height":1.5,"ground":0},"6":{"height":2.5,"ground":1},"7":{"height":1.75,"ground":4,"shadow":true},"9":{"height":1,"ground":8},"18":{"height":0.6,"ground":4},"21":{"height":2.5,"ground":8},"22":{"height":1.5,"ground":0},"23":{"height":1.5,"ground":0}},"variants":{"0":[0,11,12],"1":[1,14],"3":[3,22,23],"4":[4,13]},"decor":[{"id":16,"x":7,"y":0,"dx":-3,"dy":-2},{"id":17,"x":17,"y":0,"dx":-4,"dy":2},{"id":15,"x":2,"y":1,"dx":1,"dy":0},{"id":16,"x":7,"y":1,"dx":-3,"dy":0},{"id":15,"x":8,"y":1,"dx":-3,"dy":1},{"id":17,"x":17,"y":1,"dx":-2,"dy":-1},{"id":16,"x":25,"y":1,"dx":-2,"dy":-2},{"id":16,"x":26,"y":1,"dx":0,"dy":1},{"id":15,"x":16,"y":2,"dx":3,"dy":1},{"id":16,"x":18,"y":2,"dx":-3,"dy":-1},{"id":17,"x":10,"y":3,"dx":1,"dy":1},{"id":17,"x":11,"y":3,"dx":1,"dy":1},{"id":16,"x":26,"y":3,"dx":-3,"dy":2},{"id":16,"x":7,"y":4,"dx":-3,"dy":1},{"id":16,"x":18,"y":4,"dx":-2,"dy":2},{"id":17,"x":26,"y":4,"dx":-4,"dy":0},{"id":15,"x":11,"y":5,"dx":4,"dy":0},{"id":16,"x":13,"y":8,"dx":-2,"dy":1},{"id":16,"x":15,"y":8,"dx":3,"dy":1},{"id":17,"x":24,"y":8,"dx":-1,"dy":0},{"id":17,"x":6,"y":9,"dx":-1,"dy":-2},{"id":16,"x":13,"y":9,"dx":-3,"dy":0},{"id":17,"x":23,"y":9,"dx":-3,"dy":1},{"id":16,"x":13,"y":10,"dx":0,"dy":0},{"id":15,"x":27,"y":10,"dx":-4,"dy":0},{"id":15,"x":4,"y":11,"dx":-3,"dy":0},{"id":15,"x":10,"y":11,"dx":-2,"dy":2},{"id":16,"x":14,"y":11,"dx":3,"dy":-2},{"id":15,"x":23,"y":11,"dx":-2,"dy":1},{"id":15,"x":0,"y":12,"dx":1,"dy":1},{"id":16,"x":1,"y":12,"dx":1,"dy":1},{"id":15,"x":4,"y":12,"dx":0,"dy":1},{"id":17,"x":1,"y":13,"dx":4,"dy":0},{"id":16,"x":10,"y":13,"dx":4,"dy":0},{"id":16,"x":18,"y":13,"dx":-2,"dy":-2},{"id":16,"x":23,"y":13,"dx":2,"dy":-1},{"id":15,"x":2,"y":14,"dx":0,"dy":1},{"id":17,"x":4,"y":14,"dx":-1,"dy":0},{"id":17,"x":15,"y":14,"dx":-1,"dy":0},{"id":16,"x":16,"y":14,"dx":3,"dy":-1},{"id":16,"x":18,"y":14,"dx":0,"dy":1},{"id":15,"x":24,"y":14,"dx":4,"dy":-1},{"id":15,"x":9,"y":15,"dx":1,"dy":0},{"id":16,"x":12,"y":15,"dx":-4,"dy":-2},{"id":15,"x":13,"y":15,"dx":-2,"dy":1},{"id":17,"x":19,"y":15,"dx":0,"dy":-1},{"id":16,"x":23,"y":15,"dx":3,"dy":-1},{"id":16,"x":27,"y":16,"dx":4,"dy":2},{"id":16,"x":4,"y":17,"dx":1,"dy":-2},{"id":16,"x":13,"y":17,"dx":-2,"dy":-2},{"id":15,"x":20,"y":17,"dx":-2,"dy":0},{"id":15,"x":22,"y":17,"dx":4,"dy":0},{"id":16,"x":5,"y":18,"dx":3,"dy":0},{"id":15,"x":0,"y":19,"dx":-2,"dy":1},{"id":16,"x":8,"y":19,"dx":-3,"dy":0},{"id":15,"x":26,"y":19,"dx":2,"dy":1},{"id":15,"x":18,"y":20,"dx":-3,"dy":0},{"id":15,"x":21,"y":20,"dx":0,"dy":-1},{"id":15,"x":23,"y":20,"dx":0,"dy":2},{"id":16,"x":25,"y":20,"dx":-3,"dy":1},{"id":16,"x":25,"y":21,"dx":-3,"dy":2},{"id":17,"x":0,"y":22,"dx":1,"dy":2},{"id":17,"x":21,"y":22,"dx":3,"dy":2},{"id":15,"x":22,"y":22,"dx":3,"dy":-2},{"id":16,"x":25,"y":22,"dx":1,"dy":1},{"id":16,"x":6,"y":23,"dx":-1,"dy":0},{"id":16,"x":8,"y":23,"dx":-3,"dy":0},{"id":15,"x":12,"y":23,"dx":-3,"dy":0},{"id":16,"x":13,"y":23,"dx":1,"dy":0},{"id":16,"x":6,"y":24,"dx":2,"dy":-1},{"id":17,"x":17,"y":24,"dx":0,"dy":0},{"id":16,"x":6,"y":25,"dx":-4,"dy":2},{"id":16,"x":26,"y":26,"dx":1,"dy":1},{"id":15,"x":1,"y":27,"dx":-2,"dy":-1},{"id":17,"x":10,"y":27,"dx":2,"dy":-1}],"encoding":"rle","tiles":[[0,1],[3,2],[4,1],[0,1],[4,3],[0,1],[4,3],[0,1],[4,1],[0,4],[4,8],[3,1],[4,1],[0,1],[1,1],[0,3],[4,3],[0,2],[4,1],[0,2],[4,1],[0,4],[4,2],[0,1],[4,1],[0,1],[4,4],[0,1],[3,1],[1,2],[0,2],[4,2],[0,3],[4,4],[0,4],[4,1],[0,1],[4,2],[0,1],[4,4],[3,1],[0,2],[1,2],[0,1],[4,2],[0,6],[4,9],[0,1],[4,2],[3,1],[4,2],[3,1],[0,2],[1,2],[0,1],[4,2],[0,5],[4,3],[0,1],[4,2],[0,1],[4,1],[0,1],[4,1],[0,1],[4,2],[0,1],[4,1],[3,1],[0,1],[1,3],[0,8],[4,5],[5,1],[0,5],[4,1],[3,1],[4,2],[0,4],[1,2],[0,1],[4,3],[0,1],[4,1],[0,2],[4,2],[0,1],[4,1],[0,11],[3,1],[0,3],[1,3],[4,2],[0,1],[4,1],[0,1],[4,5],[0,1],[2,4],[0,7],[4,1],[0,1],[4,1],[0,1],[4,1],[1,2],[4,2],[0,2],[4,3],[0,1],[4,1],[0,1],[2,4],[0,3],[3,1],[0,3],[4,1],[3,1],[0,3],[4,1],[1,1],[4,3],[0,1],[4,5],[0,1],[2,2],[0,1],[5,1],[0,7],[3,1],[0,1],[4,1],[0,3],[1,2],[4,2],[0,1],[4,3],[0,8],[3,1],[0,3],[4,1],[3,1],[0,4],[4,3],[1,1],[0,3],[4,5],[0,6],[3,1],[0,2],[3,1],[0,1],[4,1],[3,1],[0,3],[4,3],[1,1],[0,4],[4,5],[0,1],[4,5],[0,1],[4,2],[0,2],[3,1],[0,4],[4,2],[1,1],[4,1],[0,5],[4,3],[0,1],[4,4],[0,3],[3,1],[0,1],[4,1],[0,1],[3,1],[0,4],[4,1],[1,2],[4,2],[0,3],[4,3],[0,1],[4,4],[0,1],[1,2],[4,1],[3,2],[4,1],[0,5],[4,1],[0,1],[1,1],[0,1],[4,1],[0,4],[4,1],[0,2],[4,4],[0,3],[3,2],[0,1],[4,1],[3,1],[0,2],[2,2],[0,2],[1,3],[4,1],[0,6],[4,1],[0,1],[4,4],[0,1],[4,1],[3,1],[0,1],[3,1],[4,3],[2,4],[5,1],[0,1],[1,1],[4,1],[0,13],[3,1],[0,1],[3,1],[4,5],[2,3],[4,2],[1,1],[4,3],[0,4],[4,1],[0,3],[3,1],[0,4],[3,1],[4,1],[3,1],[0,1],[4,4],[0,2],[5,1],[1,2],[4,2],[0,3],[4,3],[0,13],[4,4],[0,1],[4,1],[1,1],[0,5],[4,2],[0,1],[10,1],[0,2],[4,2],[0,1],[3,3],[0,6],[4,1],[0,2],[4,1],[1,3],[0,9],[4,1],[0,5],[3,1],[0,6],[4,4],[0,1],[1,1],[0,8],[4,3],[0,1],[3,1],[0,1],[3,1],[0,3],[4,4],[0,1],[4,1],[0,1],[4,1],[0,1],[1,1],[0,10],[3,1],[0,2],[3,3],[0,2],[4,1],[0,2],[4,5],[0,1],[1,1],[0,9],[4,2],[0,2],[3,1],[0,4],[4,2],[0,7],[1,10],[4,2],[3,1],[0,24],[4,4],[0,2],[3,1],[0,21],[3,4]]} \ No newline at end of file diff --git a/apps/game/assets/maps/old_siding.map b/apps/game/assets/maps/old_siding.map index ebd5780..0eb0fd5 100644 --- a/apps/game/assets/maps/old_siding.map +++ b/apps/game/assets/maps/old_siding.map @@ -1 +1 @@ -{"format":"rpg-map","version":1,"width":24,"height":20,"blocked":[2,3,6,7,9,10,18,21],"tall":{"3":{"height":1.5,"ground":0},"6":{"height":2.5,"ground":1},"7":{"height":1.75,"ground":4,"shadow":true},"9":{"height":1,"ground":8},"18":{"height":0.6,"ground":4},"21":{"height":2.5,"ground":8}},"variants":{"0":[0,11,12],"1":[1,14],"4":[4,13]},"decor":[{"id":16,"x":5,"y":0,"dx":-1,"dy":0},{"id":16,"x":13,"y":0,"dx":-4,"dy":0},{"id":16,"x":18,"y":0,"dx":-2,"dy":-1},{"id":16,"x":0,"y":1,"dx":-2,"dy":-2},{"id":16,"x":4,"y":1,"dx":0,"dy":-1},{"id":16,"x":6,"y":1,"dx":-2,"dy":2},{"id":16,"x":13,"y":2,"dx":3,"dy":1},{"id":16,"x":17,"y":2,"dx":0,"dy":-2},{"id":16,"x":15,"y":3,"dx":1,"dy":1},{"id":16,"x":19,"y":3,"dx":-1,"dy":2},{"id":16,"x":2,"y":4,"dx":-2,"dy":-1},{"id":16,"x":8,"y":4,"dx":-3,"dy":-1},{"id":16,"x":22,"y":4,"dx":-3,"dy":-1},{"id":16,"x":19,"y":5,"dx":0,"dy":0},{"id":16,"x":22,"y":5,"dx":0,"dy":0},{"id":16,"x":23,"y":5,"dx":-1,"dy":1},{"id":16,"x":19,"y":6,"dx":-3,"dy":1},{"id":16,"x":0,"y":7,"dx":1,"dy":-1},{"id":16,"x":17,"y":8,"dx":1,"dy":0},{"id":16,"x":19,"y":8,"dx":-1,"dy":-1},{"id":16,"x":22,"y":8,"dx":1,"dy":1},{"id":16,"x":5,"y":9,"dx":2,"dy":0},{"id":16,"x":20,"y":9,"dx":-3,"dy":-1},{"id":16,"x":17,"y":11,"dx":-2,"dy":1},{"id":16,"x":20,"y":11,"dx":-1,"dy":-1},{"id":16,"x":3,"y":13,"dx":2,"dy":0},{"id":16,"x":7,"y":13,"dx":-2,"dy":1},{"id":16,"x":17,"y":14,"dx":-2,"dy":-2},{"id":16,"x":3,"y":15,"dx":0,"dy":1},{"id":16,"x":8,"y":15,"dx":-3,"dy":1},{"id":16,"x":21,"y":15,"dx":-2,"dy":-1},{"id":16,"x":5,"y":16,"dx":-3,"dy":0},{"id":16,"x":3,"y":17,"dx":-3,"dy":-2},{"id":16,"x":4,"y":17,"dx":3,"dy":2},{"id":16,"x":8,"y":18,"dx":1,"dy":0},{"id":16,"x":14,"y":18,"dx":-4,"dy":-1},{"id":16,"x":7,"y":19,"dx":-1,"dy":1},{"id":16,"x":14,"y":19,"dx":0,"dy":1}],"encoding":"rle","tiles":[[4,2],[3,1],[4,23],[0,1],[4,25],[0,1],[4,30],[19,3],[4,6],[0,1],[4,14],[19,2],[4,1],[19,1],[4,2],[0,1],[4,3],[3,1],[4,13],[19,2],[4,2],[19,1],[4,8],[3,1],[4,7],[7,1],[4,2],[19,2],[4,3],[19,1],[4,5],[3,1],[4,2],[3,1],[4,9],[19,2],[4,4],[19,1],[4,7],[3,1],[4,9],[19,2],[4,5],[19,1],[4,7],[3,1],[4,4],[0,1],[4,3],[19,2],[4,6],[19,1],[4,3],[3,2],[1,10],[19,2],[1,1],[4,21],[19,2],[1,1],[4,21],[19,2],[1,1],[4,2],[7,1],[4,4],[0,1],[3,1],[4,6],[9,1],[4,5],[19,2],[1,1],[4,8],[3,1],[4,12],[19,2],[1,2],[4,9],[3,1],[4,9],[0,1],[19,2],[4,1],[1,1],[20,1],[4,19],[19,2],[4,9],[3,3],[4,8],[0,1],[4,14],[3,1],[4,22],[3,1],[4,1],[3,1],[4,21],[3,1]]} \ No newline at end of file +{"format":"rpg-map","version":1,"width":24,"height":20,"blocked":[2,3,6,7,9,10,18,21],"tall":{"3":{"height":1.5,"ground":0},"6":{"height":2.5,"ground":1},"7":{"height":1.75,"ground":4,"shadow":true},"9":{"height":1,"ground":8},"18":{"height":0.6,"ground":4},"21":{"height":2.5,"ground":8},"22":{"height":1.5,"ground":0},"23":{"height":1.5,"ground":0}},"variants":{"0":[0,11,12],"1":[1,14],"3":[3,22,23],"4":[4,13]},"decor":[{"id":16,"x":5,"y":0,"dx":-1,"dy":0},{"id":16,"x":13,"y":0,"dx":-4,"dy":0},{"id":16,"x":18,"y":0,"dx":-2,"dy":-1},{"id":16,"x":0,"y":1,"dx":-2,"dy":-2},{"id":16,"x":4,"y":1,"dx":0,"dy":-1},{"id":16,"x":6,"y":1,"dx":-2,"dy":2},{"id":16,"x":13,"y":2,"dx":3,"dy":1},{"id":16,"x":17,"y":2,"dx":0,"dy":-2},{"id":16,"x":15,"y":3,"dx":1,"dy":1},{"id":16,"x":19,"y":3,"dx":-1,"dy":2},{"id":16,"x":2,"y":4,"dx":-2,"dy":-1},{"id":16,"x":8,"y":4,"dx":-3,"dy":-1},{"id":16,"x":22,"y":4,"dx":-3,"dy":-1},{"id":16,"x":19,"y":5,"dx":0,"dy":0},{"id":16,"x":22,"y":5,"dx":0,"dy":0},{"id":16,"x":23,"y":5,"dx":-1,"dy":1},{"id":16,"x":19,"y":6,"dx":-3,"dy":1},{"id":16,"x":0,"y":7,"dx":1,"dy":-1},{"id":16,"x":17,"y":8,"dx":1,"dy":0},{"id":16,"x":19,"y":8,"dx":-1,"dy":-1},{"id":16,"x":22,"y":8,"dx":1,"dy":1},{"id":16,"x":5,"y":9,"dx":2,"dy":0},{"id":16,"x":20,"y":9,"dx":-3,"dy":-1},{"id":16,"x":17,"y":11,"dx":-2,"dy":1},{"id":16,"x":20,"y":11,"dx":-1,"dy":-1},{"id":16,"x":3,"y":13,"dx":2,"dy":0},{"id":16,"x":7,"y":13,"dx":-2,"dy":1},{"id":16,"x":17,"y":14,"dx":-2,"dy":-2},{"id":16,"x":3,"y":15,"dx":0,"dy":1},{"id":16,"x":8,"y":15,"dx":-3,"dy":1},{"id":16,"x":21,"y":15,"dx":-2,"dy":-1},{"id":16,"x":5,"y":16,"dx":-3,"dy":0},{"id":16,"x":3,"y":17,"dx":-3,"dy":-2},{"id":16,"x":4,"y":17,"dx":3,"dy":2},{"id":16,"x":8,"y":18,"dx":1,"dy":0},{"id":16,"x":14,"y":18,"dx":-4,"dy":-1},{"id":16,"x":7,"y":19,"dx":-1,"dy":1},{"id":16,"x":14,"y":19,"dx":0,"dy":1}],"encoding":"rle","tiles":[[4,2],[3,1],[4,23],[0,1],[4,25],[0,1],[4,30],[19,3],[4,6],[0,1],[4,14],[19,2],[4,1],[19,1],[4,2],[0,1],[4,3],[3,1],[4,13],[19,2],[4,2],[19,1],[4,8],[3,1],[4,7],[7,1],[4,2],[19,2],[4,3],[19,1],[4,5],[3,1],[4,2],[3,1],[4,9],[19,2],[4,4],[19,1],[4,7],[3,1],[4,9],[19,2],[4,5],[19,1],[4,7],[3,1],[4,4],[0,1],[4,3],[19,2],[4,6],[19,1],[4,3],[3,2],[1,10],[19,2],[1,1],[4,21],[19,2],[1,1],[4,21],[19,2],[1,1],[4,2],[7,1],[4,4],[0,1],[3,1],[4,6],[9,1],[4,5],[19,2],[1,1],[4,8],[3,1],[4,12],[19,2],[1,2],[4,9],[3,1],[4,9],[0,1],[19,2],[4,1],[1,1],[20,1],[4,19],[19,2],[4,9],[3,3],[4,8],[0,1],[4,14],[3,1],[4,22],[3,1],[4,1],[3,1],[4,21],[3,1]]} \ No newline at end of file diff --git a/apps/game/assets/maps/ponds.map b/apps/game/assets/maps/ponds.map index fb1ba87..c5546ce 100644 --- a/apps/game/assets/maps/ponds.map +++ b/apps/game/assets/maps/ponds.map @@ -1 +1 @@ -{"format":"rpg-map","version":1,"width":24,"height":24,"blocked":[2,3,6,7,9,10,18,21],"tall":{"3":{"height":1.5,"ground":0},"6":{"height":2.5,"ground":1},"7":{"height":1.75,"ground":4,"shadow":true},"9":{"height":1,"ground":8},"18":{"height":0.6,"ground":4},"21":{"height":2.5,"ground":8}},"variants":{"0":[0,11,12],"1":[1,14],"4":[4,13]},"decor":[{"id":16,"x":3,"y":0,"dx":-2,"dy":2},{"id":16,"x":14,"y":0,"dx":0,"dy":0},{"id":17,"x":2,"y":1,"dx":1,"dy":-1},{"id":16,"x":13,"y":1,"dx":-4,"dy":-2},{"id":16,"x":19,"y":1,"dx":-4,"dy":0},{"id":16,"x":23,"y":1,"dx":-2,"dy":1},{"id":16,"x":13,"y":2,"dx":2,"dy":1},{"id":16,"x":22,"y":2,"dx":3,"dy":1},{"id":16,"x":15,"y":3,"dx":-1,"dy":0},{"id":15,"x":10,"y":5,"dx":3,"dy":-2},{"id":16,"x":23,"y":5,"dx":-4,"dy":0},{"id":16,"x":6,"y":6,"dx":0,"dy":-1},{"id":15,"x":23,"y":6,"dx":-3,"dy":0},{"id":15,"x":3,"y":9,"dx":2,"dy":-2},{"id":16,"x":23,"y":9,"dx":1,"dy":-1},{"id":16,"x":22,"y":10,"dx":3,"dy":0},{"id":15,"x":1,"y":11,"dx":3,"dy":-1},{"id":16,"x":5,"y":11,"dx":1,"dy":-1},{"id":17,"x":20,"y":12,"dx":-3,"dy":-2},{"id":16,"x":21,"y":13,"dx":-1,"dy":1},{"id":16,"x":20,"y":14,"dx":1,"dy":2},{"id":16,"x":0,"y":16,"dx":2,"dy":1},{"id":15,"x":3,"y":17,"dx":4,"dy":-1},{"id":16,"x":15,"y":17,"dx":3,"dy":2},{"id":16,"x":22,"y":17,"dx":-2,"dy":2},{"id":16,"x":16,"y":18,"dx":0,"dy":0},{"id":15,"x":3,"y":19,"dx":3,"dy":0},{"id":15,"x":7,"y":19,"dx":0,"dy":-1},{"id":16,"x":14,"y":20,"dx":-2,"dy":-2},{"id":16,"x":19,"y":20,"dx":3,"dy":-1},{"id":16,"x":10,"y":21,"dx":2,"dy":1},{"id":16,"x":5,"y":22,"dx":1,"dy":1},{"id":16,"x":6,"y":22,"dx":-1,"dy":1},{"id":16,"x":14,"y":22,"dx":0,"dy":-1},{"id":16,"x":18,"y":22,"dx":0,"dy":-1},{"id":16,"x":19,"y":22,"dx":-1,"dy":-2},{"id":16,"x":22,"y":22,"dx":-4,"dy":-2},{"id":16,"x":7,"y":23,"dx":-2,"dy":-1},{"id":16,"x":15,"y":23,"dx":3,"dy":0},{"id":16,"x":17,"y":23,"dx":3,"dy":1}],"encoding":"rle","tiles":[[4,4],[0,1],[4,13],[0,3],[3,1],[4,2],[3,2],[0,4],[4,1],[0,1],[4,2],[0,1],[4,9],[0,3],[4,1],[3,2],[1,1],[0,3],[4,1],[0,1],[4,2],[0,1],[4,9],[0,1],[3,1],[4,3],[3,1],[4,1],[1,1],[0,1],[4,2],[0,2],[4,1],[0,2],[4,8],[0,1],[3,1],[0,2],[3,1],[0,5],[4,1],[0,2],[4,1],[0,2],[4,5],[0,1],[4,2],[0,1],[3,1],[0,2],[4,1],[0,2],[4,1],[1,1],[0,1],[4,1],[0,1],[4,1],[0,3],[4,4],[0,2],[4,3],[3,1],[0,1],[4,2],[3,1],[4,1],[0,1],[1,1],[0,1],[4,2],[0,6],[4,2],[5,1],[0,4],[4,1],[3,1],[0,1],[4,1],[0,1],[4,2],[1,2],[0,1],[4,1],[2,1],[0,1],[2,1],[4,1],[2,1],[4,1],[2,1],[0,1],[4,2],[0,1],[4,1],[0,2],[3,1],[4,3],[0,3],[1,1],[0,1],[4,1],[2,7],[4,1],[2,1],[4,1],[0,1],[4,1],[0,1],[4,1],[3,1],[4,2],[3,1],[0,2],[4,1],[1,3],[2,11],[0,3],[4,3],[3,2],[0,2],[2,2],[1,1],[2,10],[4,1],[2,1],[4,1],[0,1],[4,1],[3,2],[0,1],[4,1],[0,1],[4,2],[2,1],[1,2],[2,10],[4,1],[0,2],[4,2],[3,3],[0,2],[2,3],[1,1],[2,10],[0,2],[3,1],[4,2],[0,4],[4,1],[2,3],[1,1],[2,12],[4,1],[3,1],[4,2],[0,1],[3,1],[0,1],[4,1],[2,3],[1,1],[2,10],[4,5],[0,2],[4,4],[2,2],[1,2],[2,9],[4,2],[3,1],[4,1],[3,1],[4,1],[3,1],[0,2],[4,2],[2,2],[4,1],[1,1],[2,7],[4,1],[5,1],[4,2],[3,2],[4,4],[0,2],[4,1],[0,1],[5,1],[2,1],[1,1],[4,1],[2,2],[4,1],[2,1],[4,1],[2,2],[4,6],[3,1],[4,3],[0,2],[4,3],[1,7],[4,5],[3,1],[4,1],[0,1],[4,2],[3,1],[0,1],[4,2],[0,2],[4,13],[0,3],[4,1],[3,1],[4,2],[0,1],[4,1],[0,1],[4,4],[0,1],[5,1],[0,1],[4,7],[0,1],[4,1],[0,1],[4,1],[3,1],[4,3],[0,2],[4,4],[0,2],[4,10],[3,1],[4,11],[0,3],[4,21],[0,1],[4,10],[3,2]]} \ No newline at end of file +{"format":"rpg-map","version":1,"width":24,"height":24,"blocked":[2,3,6,7,9,10,18,21],"tall":{"3":{"height":1.5,"ground":0},"6":{"height":2.5,"ground":1},"7":{"height":1.75,"ground":4,"shadow":true},"9":{"height":1,"ground":8},"18":{"height":0.6,"ground":4},"21":{"height":2.5,"ground":8},"22":{"height":1.5,"ground":0},"23":{"height":1.5,"ground":0}},"variants":{"0":[0,11,12],"1":[1,14],"3":[3,22,23],"4":[4,13]},"decor":[{"id":16,"x":3,"y":0,"dx":-2,"dy":2},{"id":16,"x":14,"y":0,"dx":0,"dy":0},{"id":17,"x":2,"y":1,"dx":1,"dy":-1},{"id":16,"x":13,"y":1,"dx":-4,"dy":-2},{"id":16,"x":19,"y":1,"dx":-4,"dy":0},{"id":16,"x":23,"y":1,"dx":-2,"dy":1},{"id":16,"x":13,"y":2,"dx":2,"dy":1},{"id":16,"x":22,"y":2,"dx":3,"dy":1},{"id":16,"x":15,"y":3,"dx":-1,"dy":0},{"id":15,"x":10,"y":5,"dx":3,"dy":-2},{"id":16,"x":23,"y":5,"dx":-4,"dy":0},{"id":16,"x":6,"y":6,"dx":0,"dy":-1},{"id":15,"x":23,"y":6,"dx":-3,"dy":0},{"id":15,"x":3,"y":9,"dx":2,"dy":-2},{"id":16,"x":23,"y":9,"dx":1,"dy":-1},{"id":16,"x":22,"y":10,"dx":3,"dy":0},{"id":15,"x":1,"y":11,"dx":3,"dy":-1},{"id":16,"x":5,"y":11,"dx":1,"dy":-1},{"id":17,"x":20,"y":12,"dx":-3,"dy":-2},{"id":16,"x":21,"y":13,"dx":-1,"dy":1},{"id":16,"x":20,"y":14,"dx":1,"dy":2},{"id":16,"x":0,"y":16,"dx":2,"dy":1},{"id":15,"x":3,"y":17,"dx":4,"dy":-1},{"id":16,"x":15,"y":17,"dx":3,"dy":2},{"id":16,"x":22,"y":17,"dx":-2,"dy":2},{"id":16,"x":16,"y":18,"dx":0,"dy":0},{"id":15,"x":3,"y":19,"dx":3,"dy":0},{"id":15,"x":7,"y":19,"dx":0,"dy":-1},{"id":16,"x":14,"y":20,"dx":-2,"dy":-2},{"id":16,"x":19,"y":20,"dx":3,"dy":-1},{"id":16,"x":10,"y":21,"dx":2,"dy":1},{"id":16,"x":5,"y":22,"dx":1,"dy":1},{"id":16,"x":6,"y":22,"dx":-1,"dy":1},{"id":16,"x":14,"y":22,"dx":0,"dy":-1},{"id":16,"x":18,"y":22,"dx":0,"dy":-1},{"id":16,"x":19,"y":22,"dx":-1,"dy":-2},{"id":16,"x":22,"y":22,"dx":-4,"dy":-2},{"id":16,"x":7,"y":23,"dx":-2,"dy":-1},{"id":16,"x":15,"y":23,"dx":3,"dy":0},{"id":16,"x":17,"y":23,"dx":3,"dy":1}],"encoding":"rle","tiles":[[4,4],[0,1],[4,13],[0,3],[3,1],[4,2],[3,2],[0,4],[4,1],[0,1],[4,2],[0,1],[4,9],[0,3],[4,1],[3,2],[1,1],[0,3],[4,1],[0,1],[4,2],[0,1],[4,9],[0,1],[3,1],[4,3],[3,1],[4,1],[1,1],[0,1],[4,2],[0,2],[4,1],[0,2],[4,8],[0,1],[3,1],[0,2],[3,1],[0,5],[4,1],[0,2],[4,1],[0,2],[4,5],[0,1],[4,2],[0,1],[3,1],[0,2],[4,1],[0,2],[4,1],[1,1],[0,1],[4,1],[0,1],[4,1],[0,3],[4,4],[0,2],[4,3],[3,1],[0,1],[4,2],[3,1],[4,1],[0,1],[1,1],[0,1],[4,2],[0,6],[4,2],[5,1],[0,4],[4,1],[3,1],[0,1],[4,1],[0,1],[4,2],[1,2],[0,1],[4,1],[2,1],[0,1],[2,1],[4,1],[2,1],[4,1],[2,1],[0,1],[4,2],[0,1],[4,1],[0,2],[3,1],[4,3],[0,3],[1,1],[0,1],[4,1],[2,7],[4,1],[2,1],[4,1],[0,1],[4,1],[0,1],[4,1],[3,1],[4,2],[3,1],[0,2],[4,1],[1,3],[2,11],[0,3],[4,3],[3,2],[0,2],[2,2],[1,1],[2,10],[4,1],[2,1],[4,1],[0,1],[4,1],[3,2],[0,1],[4,1],[0,1],[4,2],[2,1],[1,2],[2,10],[4,1],[0,2],[4,2],[3,3],[0,2],[2,3],[1,1],[2,10],[0,2],[3,1],[4,2],[0,4],[4,1],[2,3],[1,1],[2,12],[4,1],[3,1],[4,2],[0,1],[3,1],[0,1],[4,1],[2,3],[1,1],[2,10],[4,5],[0,2],[4,4],[2,2],[1,2],[2,9],[4,2],[3,1],[4,1],[3,1],[4,1],[3,1],[0,2],[4,2],[2,2],[4,1],[1,1],[2,7],[4,1],[5,1],[4,2],[3,2],[4,4],[0,2],[4,1],[0,1],[5,1],[2,1],[1,1],[4,1],[2,2],[4,1],[2,1],[4,1],[2,2],[4,6],[3,1],[4,3],[0,2],[4,3],[1,7],[4,5],[3,1],[4,1],[0,1],[4,2],[3,1],[0,1],[4,2],[0,2],[4,13],[0,3],[4,1],[3,1],[4,2],[0,1],[4,1],[0,1],[4,4],[0,1],[5,1],[0,1],[4,7],[0,1],[4,1],[0,1],[4,1],[3,1],[4,3],[0,2],[4,4],[0,2],[4,10],[3,1],[4,11],[0,3],[4,21],[0,1],[4,10],[3,2]]} \ No newline at end of file diff --git a/apps/game/assets/maps/rust_grove.map b/apps/game/assets/maps/rust_grove.map index 365e220..3c77ac4 100644 --- a/apps/game/assets/maps/rust_grove.map +++ b/apps/game/assets/maps/rust_grove.map @@ -1 +1 @@ -{"format":"rpg-map","version":1,"width":24,"height":20,"blocked":[2,3,6,7,9,10,18,21],"tall":{"3":{"height":1.5,"ground":0},"6":{"height":2.5,"ground":1},"7":{"height":1.75,"ground":4,"shadow":true},"9":{"height":1,"ground":8},"18":{"height":0.6,"ground":4},"21":{"height":2.5,"ground":8}},"variants":{"0":[0,11,12],"1":[1,14],"4":[4,13]},"decor":[{"id":16,"x":10,"y":0,"dx":1,"dy":1},{"id":16,"x":1,"y":2,"dx":-2,"dy":-1},{"id":16,"x":8,"y":3,"dx":-1,"dy":1},{"id":16,"x":9,"y":5,"dx":4,"dy":1},{"id":16,"x":15,"y":5,"dx":3,"dy":-1},{"id":16,"x":4,"y":8,"dx":3,"dy":1},{"id":16,"x":13,"y":9,"dx":-4,"dy":-2},{"id":16,"x":14,"y":11,"dx":-3,"dy":-1},{"id":16,"x":15,"y":11,"dx":-2,"dy":1},{"id":16,"x":9,"y":12,"dx":2,"dy":1},{"id":16,"x":12,"y":12,"dx":1,"dy":0},{"id":16,"x":20,"y":12,"dx":-2,"dy":-1},{"id":16,"x":2,"y":13,"dx":3,"dy":1},{"id":16,"x":23,"y":13,"dx":-3,"dy":1},{"id":16,"x":10,"y":14,"dx":3,"dy":2},{"id":17,"x":14,"y":14,"dx":1,"dy":0},{"id":16,"x":20,"y":16,"dx":-1,"dy":0},{"id":16,"x":12,"y":17,"dx":1,"dy":1},{"id":16,"x":14,"y":18,"dx":-2,"dy":2},{"id":16,"x":2,"y":19,"dx":2,"dy":1}],"encoding":"rle","tiles":[[3,4],[4,2],[3,4],[4,1],[3,2],[4,1],[3,4],[4,1],[3,2],[4,1],[3,10],[4,3],[3,5],[4,1],[3,3],[4,1],[3,1],[4,1],[3,2],[4,1],[3,2],[4,1],[3,1],[4,1],[3,2],[4,1],[3,2],[0,1],[3,1],[4,1],[3,4],[4,2],[3,2],[4,1],[3,3],[4,3],[3,2],[4,1],[3,1],[4,2],[3,1],[4,1],[18,1],[3,1],[18,1],[3,9],[4,1],[3,1],[4,1],[18,1],[3,3],[4,2],[3,1],[4,2],[3,2],[4,1],[3,1],[4,1],[3,3],[4,1],[3,7],[18,1],[3,2],[4,3],[3,2],[4,3],[3,4],[4,2],[3,4],[4,1],[3,2],[4,1],[3,3],[4,1],[3,3],[4,1],[3,1],[4,3],[3,9],[4,1],[3,1],[4,6],[3,1],[4,1],[3,2],[4,3],[3,1],[4,1],[3,4],[4,2],[3,1],[4,1],[3,1],[4,3],[3,1],[4,2],[1,1],[4,5],[3,1],[4,1],[3,1],[4,2],[3,3],[4,2],[3,5],[4,9],[3,1],[4,4],[3,2],[1,8],[4,7],[1,7],[3,4],[4,15],[3,1],[4,1],[3,3],[4,1],[3,6],[4,9],[3,2],[4,1],[3,2],[4,2],[3,4],[4,1],[3,1],[4,1],[3,3],[4,8],[3,4],[4,1],[3,2],[4,1],[3,9],[4,5],[0,1],[3,3],[18,1],[3,1],[4,1],[3,1],[4,2],[3,2],[4,1],[3,2],[4,1],[3,1],[4,1],[3,2],[18,1],[3,2],[4,1],[3,2],[4,1],[18,1],[4,3],[3,1],[4,1],[3,3],[4,1],[3,3],[4,1],[3,1],[4,1],[3,1],[4,4],[3,2],[4,5],[3,1],[4,1],[3,5],[4,2],[3,1],[4,1],[3,1],[4,2],[3,1],[4,2],[3,1],[4,1],[3,1],[4,1],[3,1],[4,2],[3,3],[4,1],[3,3],[4,2],[3,2],[4,2],[3,3],[4,2],[3,2],[4,1],[3,5],[4,4],[3,7],[4,2],[3,3],[4,3],[3,1],[4,2],[3,3]]} \ No newline at end of file +{"format":"rpg-map","version":1,"width":24,"height":20,"blocked":[2,3,6,7,9,10,18,21],"tall":{"3":{"height":1.5,"ground":0},"6":{"height":2.5,"ground":1},"7":{"height":1.75,"ground":4,"shadow":true},"9":{"height":1,"ground":8},"18":{"height":0.6,"ground":4},"21":{"height":2.5,"ground":8},"22":{"height":1.5,"ground":0},"23":{"height":1.5,"ground":0}},"variants":{"0":[0,11,12],"1":[1,14],"3":[3,22,23],"4":[4,13]},"decor":[{"id":16,"x":10,"y":0,"dx":1,"dy":1},{"id":16,"x":1,"y":2,"dx":-2,"dy":-1},{"id":16,"x":8,"y":3,"dx":-1,"dy":1},{"id":16,"x":9,"y":5,"dx":4,"dy":1},{"id":16,"x":15,"y":5,"dx":3,"dy":-1},{"id":16,"x":4,"y":8,"dx":3,"dy":1},{"id":16,"x":13,"y":9,"dx":-4,"dy":-2},{"id":16,"x":14,"y":11,"dx":-3,"dy":-1},{"id":16,"x":15,"y":11,"dx":-2,"dy":1},{"id":16,"x":9,"y":12,"dx":2,"dy":1},{"id":16,"x":12,"y":12,"dx":1,"dy":0},{"id":16,"x":20,"y":12,"dx":-2,"dy":-1},{"id":16,"x":2,"y":13,"dx":3,"dy":1},{"id":16,"x":23,"y":13,"dx":-3,"dy":1},{"id":16,"x":10,"y":14,"dx":3,"dy":2},{"id":17,"x":14,"y":14,"dx":1,"dy":0},{"id":16,"x":20,"y":16,"dx":-1,"dy":0},{"id":16,"x":12,"y":17,"dx":1,"dy":1},{"id":16,"x":14,"y":18,"dx":-2,"dy":2},{"id":16,"x":2,"y":19,"dx":2,"dy":1}],"encoding":"rle","tiles":[[3,4],[4,2],[3,4],[4,1],[3,2],[4,1],[3,4],[4,1],[3,2],[4,1],[3,10],[4,3],[3,5],[4,1],[3,3],[4,1],[3,1],[4,1],[3,2],[4,1],[3,2],[4,1],[3,1],[4,1],[3,2],[4,1],[3,2],[0,1],[3,1],[4,1],[3,4],[4,2],[3,2],[4,1],[3,3],[4,3],[3,2],[4,1],[3,1],[4,2],[3,1],[4,1],[18,1],[3,1],[18,1],[3,9],[4,1],[3,1],[4,1],[18,1],[3,3],[4,2],[3,1],[4,2],[3,2],[4,1],[3,1],[4,1],[3,3],[4,1],[3,7],[18,1],[3,2],[4,3],[3,2],[4,3],[3,4],[4,2],[3,4],[4,1],[3,2],[4,1],[3,3],[4,1],[3,3],[4,1],[3,1],[4,3],[3,9],[4,1],[3,1],[4,6],[3,1],[4,1],[3,2],[4,3],[3,1],[4,1],[3,4],[4,2],[3,1],[4,1],[3,1],[4,3],[3,1],[4,2],[1,1],[4,5],[3,1],[4,1],[3,1],[4,2],[3,3],[4,2],[3,5],[4,9],[3,1],[4,4],[3,2],[1,8],[4,7],[1,7],[3,4],[4,15],[3,1],[4,1],[3,3],[4,1],[3,6],[4,9],[3,2],[4,1],[3,2],[4,2],[3,4],[4,1],[3,1],[4,1],[3,3],[4,8],[3,4],[4,1],[3,2],[4,1],[3,9],[4,5],[0,1],[3,3],[18,1],[3,1],[4,1],[3,1],[4,2],[3,2],[4,1],[3,2],[4,1],[3,1],[4,1],[3,2],[18,1],[3,2],[4,1],[3,2],[4,1],[18,1],[4,3],[3,1],[4,1],[3,3],[4,1],[3,3],[4,1],[3,1],[4,1],[3,1],[4,4],[3,2],[4,5],[3,1],[4,1],[3,5],[4,2],[3,1],[4,1],[3,1],[4,2],[3,1],[4,2],[3,1],[4,1],[3,1],[4,1],[3,1],[4,2],[3,3],[4,1],[3,3],[4,2],[3,2],[4,2],[3,3],[4,2],[3,2],[4,1],[3,5],[4,4],[3,7],[4,2],[3,3],[4,3],[3,1],[4,2],[3,3]]} \ No newline at end of file diff --git a/apps/game/assets/maps/shop.map b/apps/game/assets/maps/shop.map index 0b18212..845bfe7 100644 --- a/apps/game/assets/maps/shop.map +++ b/apps/game/assets/maps/shop.map @@ -1 +1 @@ -{"format":"rpg-map","version":1,"width":11,"height":9,"blocked":[2,3,6,7,9,10,18,21],"tall":{"3":{"height":1.5,"ground":0},"6":{"height":2.5,"ground":1},"7":{"height":1.75,"ground":4,"shadow":true},"9":{"height":1,"ground":8},"18":{"height":0.6,"ground":4},"21":{"height":2.5,"ground":8}},"encoding":"rle","tiles":[[9,12],[8,9],[9,2],[8,9],[9,2],[8,9],[9,2],[8,9],[9,2],[8,9],[9,2],[8,9],[9,2],[8,9],[9,6],[8,1],[9,5]]} \ No newline at end of file +{"format":"rpg-map","version":1,"width":11,"height":9,"blocked":[2,3,6,7,9,10,18,21],"tall":{"3":{"height":1.5,"ground":0},"6":{"height":2.5,"ground":1},"7":{"height":1.75,"ground":4,"shadow":true},"9":{"height":1,"ground":8},"18":{"height":0.6,"ground":4},"21":{"height":2.5,"ground":8},"22":{"height":1.5,"ground":0},"23":{"height":1.5,"ground":0}},"encoding":"rle","tiles":[[9,12],[8,9],[9,2],[8,9],[9,2],[8,9],[9,2],[8,9],[9,2],[8,9],[9,2],[8,9],[9,2],[8,9],[9,6],[8,1],[9,5]]} \ No newline at end of file diff --git a/apps/game/assets/maps/zvenets.map b/apps/game/assets/maps/zvenets.map index 39815e3..ee65894 100644 --- a/apps/game/assets/maps/zvenets.map +++ b/apps/game/assets/maps/zvenets.map @@ -1 +1 @@ -{"format":"rpg-map","version":1,"width":28,"height":20,"blocked":[2,3,6,7,9,10,18,21],"tall":{"3":{"height":1.5,"ground":0},"6":{"height":2.5,"ground":1},"7":{"height":1.75,"ground":4,"shadow":true},"9":{"height":1,"ground":8},"18":{"height":0.6,"ground":4},"21":{"height":2.5,"ground":8}},"variants":{"0":[0,11,12],"1":[1,14],"4":[4,13]},"decor":[{"id":16,"x":14,"y":0,"dx":1,"dy":1},{"id":16,"x":23,"y":0,"dx":0,"dy":1},{"id":16,"x":26,"y":0,"dx":3,"dy":1},{"id":16,"x":3,"y":1,"dx":0,"dy":0},{"id":17,"x":9,"y":1,"dx":3,"dy":0},{"id":15,"x":10,"y":1,"dx":3,"dy":2},{"id":16,"x":19,"y":1,"dx":-1,"dy":1},{"id":16,"x":1,"y":2,"dx":1,"dy":0},{"id":16,"x":3,"y":2,"dx":4,"dy":1},{"id":16,"x":11,"y":2,"dx":-1,"dy":-2},{"id":15,"x":10,"y":3,"dx":4,"dy":1},{"id":16,"x":15,"y":3,"dx":0,"dy":0},{"id":16,"x":26,"y":5,"dx":3,"dy":-1},{"id":16,"x":20,"y":6,"dx":1,"dy":-1},{"id":16,"x":26,"y":6,"dx":-2,"dy":-2},{"id":16,"x":5,"y":7,"dx":1,"dy":-2},{"id":16,"x":7,"y":7,"dx":0,"dy":0},{"id":16,"x":3,"y":8,"dx":3,"dy":2},{"id":16,"x":17,"y":8,"dx":1,"dy":0},{"id":16,"x":22,"y":9,"dx":1,"dy":-1},{"id":16,"x":2,"y":11,"dx":-3,"dy":-1},{"id":16,"x":26,"y":11,"dx":1,"dy":1},{"id":15,"x":4,"y":12,"dx":4,"dy":0},{"id":17,"x":23,"y":12,"dx":-2,"dy":2},{"id":15,"x":4,"y":14,"dx":-1,"dy":-1},{"id":15,"x":11,"y":14,"dx":3,"dy":1},{"id":16,"x":17,"y":14,"dx":-4,"dy":2},{"id":16,"x":23,"y":16,"dx":3,"dy":-2},{"id":17,"x":16,"y":17,"dx":3,"dy":-2},{"id":16,"x":5,"y":18,"dx":0,"dy":2}],"encoding":"rle","tiles":[[4,30],[3,1],[4,6],[0,4],[4,13],[3,1],[4,9],[0,2],[4,2],[0,1],[4,23],[0,3],[4,1],[0,1],[4,12],[3,1],[4,2],[3,1],[4,1],[3,1],[4,5],[0,5],[4,12],[3,1],[4,2],[0,2],[4,6],[0,5],[4,1],[0,1],[4,3],[7,1],[4,6],[3,1],[4,3],[3,1],[4,5],[7,1],[4,1],[10,1],[1,10],[4,8],[3,1],[0,2],[4,6],[1,5],[6,1],[4,1],[1,1],[4,1],[1,2],[4,6],[3,3],[4,1],[3,1],[4,6],[1,8],[4,1],[1,1],[4,6],[3,1],[4,3],[0,1],[4,7],[1,1],[4,1],[1,9],[4,1],[7,1],[4,8],[1,12],[0,1],[1,1],[4,1],[1,3],[4,1],[0,3],[4,1],[1,2],[4,1],[3,1],[0,1],[4,7],[1,2],[4,1],[1,8],[0,4],[4,5],[3,1],[0,5],[4,2],[1,11],[4,1],[0,3],[4,6],[3,1],[0,6],[1,8],[4,1],[1,2],[4,1],[0,3],[4,4],[3,1],[4,3],[0,3],[4,1],[0,5],[4,17],[0,1],[4,1],[0,2],[4,1],[0,1],[4,1],[0,2],[4,5],[0,4],[4,7],[3,1],[0,2],[4,1],[0,1],[4,1],[0,2],[4,2],[0,2],[4,4],[0,5],[4,5],[3,2],[4,2],[0,1],[3,1],[4,5],[0,12],[4,8],[0,3],[4,6],[0,5],[4,1],[0,5],[4,4],[0,1],[3,1],[0,1],[4,1],[3,1],[0,1],[4,7],[0,7],[4,1],[0,3],[4,4],[0,3],[4,1]]} \ No newline at end of file +{"format":"rpg-map","version":1,"width":28,"height":20,"blocked":[2,3,6,7,9,10,18,21],"tall":{"3":{"height":1.5,"ground":0},"6":{"height":2.5,"ground":1},"7":{"height":1.75,"ground":4,"shadow":true},"9":{"height":1,"ground":8},"18":{"height":0.6,"ground":4},"21":{"height":2.5,"ground":8},"22":{"height":1.5,"ground":0},"23":{"height":1.5,"ground":0}},"variants":{"0":[0,11,12],"1":[1,14],"3":[3,22,23],"4":[4,13]},"decor":[{"id":16,"x":14,"y":0,"dx":1,"dy":1},{"id":16,"x":23,"y":0,"dx":0,"dy":1},{"id":16,"x":26,"y":0,"dx":3,"dy":1},{"id":16,"x":3,"y":1,"dx":0,"dy":0},{"id":17,"x":9,"y":1,"dx":3,"dy":0},{"id":15,"x":10,"y":1,"dx":3,"dy":2},{"id":16,"x":19,"y":1,"dx":-1,"dy":1},{"id":16,"x":1,"y":2,"dx":1,"dy":0},{"id":16,"x":3,"y":2,"dx":4,"dy":1},{"id":16,"x":11,"y":2,"dx":-1,"dy":-2},{"id":15,"x":10,"y":3,"dx":4,"dy":1},{"id":16,"x":15,"y":3,"dx":0,"dy":0},{"id":16,"x":26,"y":5,"dx":3,"dy":-1},{"id":16,"x":20,"y":6,"dx":1,"dy":-1},{"id":16,"x":26,"y":6,"dx":-2,"dy":-2},{"id":16,"x":5,"y":7,"dx":1,"dy":-2},{"id":16,"x":7,"y":7,"dx":0,"dy":0},{"id":16,"x":3,"y":8,"dx":3,"dy":2},{"id":16,"x":17,"y":8,"dx":1,"dy":0},{"id":16,"x":22,"y":9,"dx":1,"dy":-1},{"id":16,"x":2,"y":11,"dx":-3,"dy":-1},{"id":16,"x":26,"y":11,"dx":1,"dy":1},{"id":15,"x":4,"y":12,"dx":4,"dy":0},{"id":17,"x":23,"y":12,"dx":-2,"dy":2},{"id":15,"x":4,"y":14,"dx":-1,"dy":-1},{"id":15,"x":11,"y":14,"dx":3,"dy":1},{"id":16,"x":17,"y":14,"dx":-4,"dy":2},{"id":16,"x":23,"y":16,"dx":3,"dy":-2},{"id":17,"x":16,"y":17,"dx":3,"dy":-2},{"id":16,"x":5,"y":18,"dx":0,"dy":2}],"encoding":"rle","tiles":[[4,30],[3,1],[4,6],[0,4],[4,13],[3,1],[4,9],[0,2],[4,2],[0,1],[4,23],[0,3],[4,1],[0,1],[4,12],[3,1],[4,2],[3,1],[4,1],[3,1],[4,5],[0,5],[4,12],[3,1],[4,2],[0,2],[4,6],[0,5],[4,1],[0,1],[4,3],[7,1],[4,6],[3,1],[4,3],[3,1],[4,5],[7,1],[4,1],[10,1],[1,10],[4,8],[3,1],[0,2],[4,6],[1,5],[6,1],[4,1],[1,1],[4,1],[1,2],[4,6],[3,3],[4,1],[3,1],[4,6],[1,8],[4,1],[1,1],[4,6],[3,1],[4,3],[0,1],[4,7],[1,1],[4,1],[1,9],[4,1],[7,1],[4,8],[1,12],[0,1],[1,1],[4,1],[1,3],[4,1],[0,3],[4,1],[1,2],[4,1],[3,1],[0,1],[4,7],[1,2],[4,1],[1,8],[0,4],[4,5],[3,1],[0,5],[4,2],[1,11],[4,1],[0,3],[4,6],[3,1],[0,6],[1,8],[4,1],[1,2],[4,1],[0,3],[4,4],[3,1],[4,3],[0,3],[4,1],[0,5],[4,17],[0,1],[4,1],[0,2],[4,1],[0,1],[4,1],[0,2],[4,5],[0,4],[4,7],[3,1],[0,2],[4,1],[0,1],[4,1],[0,2],[4,2],[0,2],[4,4],[0,5],[4,5],[3,2],[4,2],[0,1],[3,1],[4,5],[0,12],[4,8],[0,3],[4,6],[0,5],[4,1],[0,5],[4,4],[0,1],[3,1],[0,1],[4,1],[3,1],[0,1],[4,7],[0,7],[4,1],[0,3],[4,4],[0,3],[4,1]]} \ No newline at end of file diff --git a/apps/game/assets/tiles/tree.png b/apps/game/assets/tiles/tree.png index 7fc9f06..99bd669 100644 --- a/apps/game/assets/tiles/tree.png +++ b/apps/game/assets/tiles/tree.png Binary files differ diff --git a/apps/game/assets/tiles/tree_2.png b/apps/game/assets/tiles/tree_2.png new file mode 100644 index 0000000..5ba00cd --- /dev/null +++ b/apps/game/assets/tiles/tree_2.png Binary files differ diff --git a/apps/game/assets/tiles/tree_2_sway.png b/apps/game/assets/tiles/tree_2_sway.png new file mode 100644 index 0000000..b437dec --- /dev/null +++ b/apps/game/assets/tiles/tree_2_sway.png Binary files differ diff --git a/apps/game/assets/tiles/tree_3.png b/apps/game/assets/tiles/tree_3.png new file mode 100644 index 0000000..7955876 --- /dev/null +++ b/apps/game/assets/tiles/tree_3.png Binary files differ diff --git a/apps/game/assets/tiles/tree_3_sway.png b/apps/game/assets/tiles/tree_3_sway.png new file mode 100644 index 0000000..a408056 --- /dev/null +++ b/apps/game/assets/tiles/tree_3_sway.png Binary files differ diff --git a/apps/game/assets/tiles/tree_sway.png b/apps/game/assets/tiles/tree_sway.png new file mode 100644 index 0000000..1d83975 --- /dev/null +++ b/apps/game/assets/tiles/tree_sway.png Binary files differ diff --git a/apps/game/src/Game.ts b/apps/game/src/Game.ts index a3aa148..b92f7e2 100644 --- a/apps/game/src/Game.ts +++ b/apps/game/src/Game.ts @@ -65,6 +65,11 @@ 'tiles/decor_bald', 'tiles/bellflower', 'tiles/tree', + 'tiles/tree_2', + 'tiles/tree_3', + 'tiles/tree_sway', + 'tiles/tree_2_sway', + 'tiles/tree_3_sway', 'tiles/house', 'tiles/tower', 'tiles/floor', diff --git a/apps/game/src/data/assetSets.ts b/apps/game/src/data/assetSets.ts index 5ed672c..5ecdb9e 100644 --- a/apps/game/src/data/assetSets.ts +++ b/apps/game/src/data/assetSets.ts @@ -24,6 +24,8 @@ [DECOR.BALD, a.texture('tiles/decor_bald')], [TILES.BELLFLOWER, a.texture('tiles/bellflower')], [TILES.TREE, a.texture('tiles/tree')], + [TILES.TREE_V1, a.texture('tiles/tree_2')], + [TILES.TREE_V2, a.texture('tiles/tree_3')], [TILES.TOWER, a.texture('tiles/tower')], [TILES.HOUSE, a.texture('tiles/house')], [TILES.FLOOR, a.texture('tiles/floor')], diff --git a/apps/game/src/data/map.ts b/apps/game/src/data/map.ts index a6f68cf..49198e7 100644 --- a/apps/game/src/data/map.ts +++ b/apps/game/src/data/map.ts @@ -26,7 +26,10 @@ GRASS_V1: 11, GRASS_V2: 12, ASH_V1: 13, - PATH_V1: 14 + PATH_V1: 14, + /** Деревья других видов (варианты TREE распределителем ниже; в tiles не попадают). */ + TREE_V1: 22, + TREE_V2: 23 } as const; const BLOCKED = [ @@ -40,9 +43,14 @@ TILES.MACHINE ]; +/** Все id деревьев (вьюхи крон/частицы/соседство — общий случай). */ +export const TREE_TILES: readonly number[] = [TILES.TREE, TILES.TREE_V1, TILES.TREE_V2]; + /** Дерево — высокий объект 1.5 мировых юнита (48 px), под ним трава. */ export const TALL_OBJECTS: Record = { [TILES.TREE]: { height: 1.5, ground: TILES.GRASS }, + [TILES.TREE_V1]: { height: 1.5, ground: TILES.GRASS }, + [TILES.TREE_V2]: { height: 1.5, ground: TILES.GRASS }, [TILES.TOWER]: { height: 2.5, ground: TILES.PATH }, [TILES.HOUSE]: { height: 1.75, ground: TILES.ASH, shadow: true }, // Стены интерьеров — вертикальные объекты, под ними пол. @@ -63,6 +71,14 @@ [TILES.ASH]: [TILES.ASH, TILES.ASH_V1] }; +/** Микс высоких объектов: деревья трёх видов (анимация крон — по видам). */ +const TALL_VARIANTS: Record = { + [TILES.TREE]: [TILES.TREE, TILES.TREE_V1, TILES.TREE_V2] +}; + +/** Полная таблица вариантов для карт (земля + высокие объекты). */ +const TILE_VARIANTS: Record = { ...GROUND_VARIANTS, ...TALL_VARIANTS }; + /** id текстур мелкого декора (не тайлы — в tiles не попадают). */ export const DECOR = { /** Микро-кустик (сухая трава). */ @@ -213,7 +229,7 @@ tiles, blocked: [...BLOCKED], tall: TALL_OBJECTS, - variants: GROUND_VARIANTS, + variants: TILE_VARIANTS, decor: buildDecor(tiles, width, height, seed) }; } @@ -304,7 +320,7 @@ tiles, blocked: [...BLOCKED], tall: TALL_OBJECTS, - variants: GROUND_VARIANTS, + variants: TILE_VARIANTS, decor: buildDecor(tiles, width, height, seed) }; } @@ -368,7 +384,7 @@ tiles, blocked: [...BLOCKED], tall: TALL_OBJECTS, - variants: GROUND_VARIANTS, + variants: TILE_VARIANTS, decor: buildDecor(tiles, width, height, seed) }; } @@ -485,7 +501,7 @@ tiles, blocked: [...BLOCKED], tall: TALL_OBJECTS, - variants: GROUND_VARIANTS, + variants: TILE_VARIANTS, decor: buildDecor(tiles, width, height, seed) }; } @@ -613,7 +629,7 @@ tiles, blocked: [...BLOCKED], tall: TALL_OBJECTS, - variants: GROUND_VARIANTS, + variants: TILE_VARIANTS, decor: buildDecor(tiles, width, height, seed) }; } diff --git a/apps/game/src/scenes/LocationScene.ts b/apps/game/src/scenes/LocationScene.ts index ecf3292..1e86c6f 100644 --- a/apps/game/src/scenes/LocationScene.ts +++ b/apps/game/src/scenes/LocationScene.ts @@ -9,6 +9,7 @@ FxLayer, emberPreset, readSeconds, + createRng, worldToScreen, tileToWorld, DebugOverlay, @@ -27,7 +28,7 @@ import { MenuScene } from './MenuScene'; import { SAVE_VERSION, type SaveData } from './saveData'; import { InventoryScene } from './InventoryScene'; -import { TILES } from '../data/map'; +import { TILES, TREE_TILES } from '../data/map'; import { areaAudioKeys } from '../data/audio'; import { playSfx } from '../data/sfxSpecs'; import { areaOf, type AreaDef, type AreaId, type TransitionDef } from '../data/locations'; @@ -65,6 +66,9 @@ /** Лампа героя: тёплый, компактный, слегка мерцает (прорезает ночную тьму). */ const HERO_LAMP: HeroLampDef = { color: 0xf2b45a, radius: 2.0, intensity: 1.0, flicker: 0.12 }; +/** Осыпание пепла с крон: период спавна порции (сек) на все видимые деревья. */ +const CROWN_ASH_PERIOD = 0.9; + /** * Локация «Выжженные луга»: карта, герой, NPC, диалоги, бой со сгустками, автосейв по Esc. * Сцена — оркестратор вьюх: аудио/атмосфера/квест/вьюхи объектов живут @@ -137,6 +141,12 @@ private agentView: SceneAgentView; /** Позиции тайлов-источников амбиент-слоёв, по id (собираются один раз). */ private layerTilePos = new Map(); + /** Тайлы деревьев области (все виды) — источники осыпающегося пепла. */ + private crownTiles: Vec2[] = []; + /** Осыпание пепла с крон: накопитель периода, rng и счётчик seed частиц. */ + private crownAshT = 0; + private readonly crownAshRng = createRng(20260908); + private crownAshSeed = 1; constructor( private game: Game, @@ -156,6 +166,20 @@ [this.game.assets.texture('tiles/water_1'), this.game.assets.texture('tiles/water_2')], 2 ); + // Качание крон: у каждого вида дерева свои 2 кадра и свой таймлайн + // (fps слегка разный — виды качаются не в такт; деревья одного вида — + // синхронно, как вода). + for (const [id, name, fps] of [ + [TILES.TREE, 'tree', 1.5], + [TILES.TREE_V1, 'tree_2', 1.7], + [TILES.TREE_V2, 'tree_3', 1.3] + ] as const) { + this.map.setTileAnimation( + id, + [this.game.assets.texture(`tiles/${name}`), this.game.assets.texture(`tiles/${name}_sway`)], + fps + ); + } this.world.addChild(this.map.view, this.actors); // Выход интерьера: бронзовый контур проёма + подпись (у kind 'return'). const exit = area.transitions.find((t) => t.target.kind === 'return'); @@ -172,6 +196,8 @@ this.layerTilePos.set(id, list); } } + // Тайлы деревьев (все виды) — для осыпания пепла с крон. + this.crownTiles = TREE_TILES.flatMap((id) => this.layerTilePos.get(id) ?? []); // Крупные объекты карты (дома) — в общий depth-слой по footprint'у. for (const p of this.map.propViews) this.actors.addRect(p.view, p.prop.x, p.prop.y, p.prop.w, p.prop.h); this.game.renderer.worldRoot.addChild(this.world); @@ -525,7 +551,8 @@ } update(dt: number): void { - this.map.update(dt); // анимированные тайлы (вода) — no-op без анимаций + this.map.update(dt); // анимированные тайлы (вода, кроны) — no-op без анимаций + this.updateCrownAsh(dt); this.worldAudio.update(dt); this.locationAudio.updateLayers(); this.locationAudio.updateAmbient(dt); @@ -792,6 +819,30 @@ ]); } + /** + * Осыпающийся пепел с крон деревьев: редкий спавн 1–2 частиц с случайной + * кроны (детерминированный rng), падают вниз и тают — жизнь леса вне боя. + */ + private updateCrownAsh(dt: number): void { + if (this.crownTiles.length === 0) return; // интерьеры и пустые карты + this.crownAshT += dt; + if (this.crownAshT < CROWN_ASH_PERIOD) return; + this.crownAshT = 0; + const t = this.crownTiles[Math.floor(this.crownAshRng.next() * this.crownTiles.length)]!; + const c = this.tileCenter(t.x, t.y); + this.fx.burst( + 1 + Math.floor(this.crownAshRng.next() * 2), + { x: c.x, y: c.y - 34 }, // середина кроны (дерево 48px от низа ромба) + emberPreset(0x8a8a96, { + blend: 'normal', + fadeIn: 0.2, + lifetime: [1.5, 2.6], + velocity: { x: [-3, 3], y: [4, 9] }, + seed: this.crownAshSeed++ + }) + ); + } + /** Всплывающая подсказка: появляется, держится, растворяется вверх (FxLayer). */ private showToast(text: string): void { this.lastToast = { text, tick: this.game.engine.tickCount }; diff --git a/apps/game/tools/pixelart/gen.mjs b/apps/game/tools/pixelart/gen.mjs index b0797be..fdf6e9d 100644 --- a/apps/game/tools/pixelart/gen.mjs +++ b/apps/game/tools/pixelart/gen.mjs @@ -151,10 +151,15 @@ return c; } -/** Дерево Ржавой рощи 32x48: ржавый ствол, редкая серо-оливковая крона, кабель. */ -function treeTile() { +/** + * Дерево 32x48, три вида кроны + кадр качания. + * kind: 'wide' (три облака, кабель — Ржавая роща), 'sparse' (редкая высокая), + * 'young' (молодое с малой кроной). sway — сдвиг кроны по X (±1px, ветер): + * кадры одного вида отличаются только кроной, ствол неподвижен. + */ +function treeTile({ kind = 'wide', seed = 2026, cable = true, sway = 0 } = {}) { const c = new Canvas(...SIZES.tall.tree); - const r = rng(2026); + const r = rng(seed); const ellipse = (cx, cy, rx, ry, color) => { for (let y = -ry; y <= ry; y++) { @@ -166,38 +171,65 @@ } }; - // Крона: три перекрывающихся «облака» мёртвой листвы. - ellipse(16, 9, 10, 7, 'G0'); - ellipse(9, 14, 6, 5, 'G0'); - ellipse(23, 13, 7, 5, 'G0'); - // Внутренний тон и редкие «живые» пряди. - ellipse(15, 10, 7, 4, 'G1'); - ellipse(10, 14, 3, 2, 'G1'); - ellipse(21, 12, 4, 2, 'G1'); + // Крона: перекрывающиеся «облака» мёртвой листвы (сдвигаются ветром). + const clouds = + kind === 'wide' + ? [ + [16, 9, 10, 7], + [9, 14, 6, 5], + [23, 13, 7, 5] + ] + : kind === 'sparse' + ? [ + [16, 8, 8, 7], + [10, 13, 5, 4], + [22, 12, 5, 4] + ] + : [ + [16, 12, 7, 5], + [12, 16, 4, 3], + [21, 15, 4, 3] + ]; + for (const [cx, cy, rx, ry] of clouds) ellipse(cx + sway, cy, rx, ry, 'G0'); + // Внутренний тон. + for (const [cx, cy, rx, ry] of clouds) ellipse(cx + sway, cy + 1, rx - 3, ry - 2, 'G1'); for (let i = 0; i < 26; i++) { const x = 6 + Math.floor(r() * 20); const y = 3 + Math.floor(r() * 12); - if (c.get(x, y) && r() < 0.5) c.set(x, y, 'G2'); + if (c.get(x + sway, y) && r() < 0.5) c.set(x + sway, y, 'G2'); } // Прорехи (мёртвое дерево): прозрачные проколы в кроне. - for (const [x, y] of [ - [13, 6], - [19, 12], - [8, 13], - [22, 8] - ]) { - c.set(x, y, null); - c.set(x + 1, y, null); + for (const [x, y] of kind === 'wide' + ? [ + [13, 6], + [19, 12], + [8, 13], + [22, 8] + ] + : kind === 'sparse' + ? [ + [15, 5], + [20, 10], + [12, 11], + [17, 8], + [9, 9] + ] + : [ + [14, 11], + [19, 13] + ]) { + c.set(x + sway, y, null); + c.set(x + 1 + sway, y, null); } // Ствол: металл с ржавчиной внизу, лёгкий изгиб, корни в стороны. for (let y = 18; y <= 47; y++) { - const sway = Math.round(Math.sin((y - 18) * 0.09) * 1.5); + const bend = Math.round(Math.sin((y - 18) * 0.09) * 1.5); const half = y > 40 ? 2 : 1; for (let dx = -half; dx <= half; dx++) { - c.set(16 + sway + dx, y, y > 38 ? 'R1' : 'M1'); + c.set(16 + bend + dx, y, y > 38 ? 'R1' : 'M1'); } - c.set(16 + sway - half - 1, y, y > 38 ? 'R0' : 'M0'); + c.set(16 + bend - half - 1, y, y > 38 ? 'R0' : 'M0'); } // Корни. for (let i = 0; i < 4; i++) { @@ -208,15 +240,16 @@ c.set(13, 46, 'P5'); c.set(19, 46, 'P5'); - // Кабель через крону и вокруг ствола. - for (let x = 4; x <= 27; x++) { - const y = 16 - Math.round(Math.sin((x - 4) * 0.2) * 1); - if (!c.get(x, y)) c.set(x, y, 'M2'); - else c.set(x, y, 'M2'); - } - for (let y = 22; y <= 44; y += 7) { - c.set(14, y, 'M0'); - c.set(19, y, 'M0'); + // Кабель через крону и вокруг ствола (только «роща»-вид). + if (cable) { + for (let x = 4; x <= 27; x++) { + const y = 16 - Math.round(Math.sin((x - 4) * 0.2) * 1); + c.set(x, y, 'M2'); + } + for (let y = 22; y <= 44; y += 7) { + c.set(14, y, 'M0'); + c.set(19, y, 'M0'); + } } return c; @@ -911,7 +944,13 @@ save(decorStone(), 'tiles/decor_stone.png'); save(decorBald(), 'tiles/decor_bald.png'); save(bellflowerTile(), 'tiles/bellflower.png'); -save(treeTile(), 'tiles/tree.png'); +// Деревья: три вида кроны, у каждого кадр качания (сдвиг кроны на 1px). +save(treeTile({ kind: 'wide', seed: 2026, cable: true }), 'tiles/tree.png'); +save(treeTile({ kind: 'wide', seed: 2026, cable: true, sway: 1 }), 'tiles/tree_sway.png'); +save(treeTile({ kind: 'sparse', seed: 404, cable: false }), 'tiles/tree_2.png'); +save(treeTile({ kind: 'sparse', seed: 404, cable: false, sway: 1 }), 'tiles/tree_2_sway.png'); +save(treeTile({ kind: 'young', seed: 909, cable: false }), 'tiles/tree_3.png'); +save(treeTile({ kind: 'young', seed: 909, cable: false, sway: 1 }), 'tiles/tree_3_sway.png'); save(houseTile(), 'tiles/house.png'); save(bigHouseTile(), 'tiles/house_big.png'); save(towerTile(), 'tiles/tower.png'); diff --git a/apps/game/tools/pixelart/sizes.mjs b/apps/game/tools/pixelart/sizes.mjs index d66b43b..5ddf0fd 100644 --- a/apps/game/tools/pixelart/sizes.mjs +++ b/apps/game/tools/pixelart/sizes.mjs @@ -33,7 +33,9 @@ /** Кадры сгустков (враги демо-боя; рисунки вписаны по низу-центру). */ clump: { w: 20, h: 20 }, /** Спрайты декора поверх тайлов (микро-кусты, камни, проплешины). */ - decor: { w: 16, h: 16 } + decor: { w: 16, h: 16 }, + /** Одиночные спрайты-сателлиты (вешаются на персонажей). */ + satellite: { heroLamp: [7, 8] } }; /** Слоты вне реестра: рукодельные кадры сгустков и крупные AI-ассеты. */ diff --git a/docs/art-style.md b/docs/art-style.md index 5929e9a..5dbfd02 100644 --- a/docs/art-style.md +++ b/docs/art-style.md @@ -82,7 +82,10 @@ - Тайл: ромб **32×16** (движок, `DEFAULT_ISO`). - Персонаж: **16×24**, якорь — центр между ступней (низ спрайта = центр ромба тайла). -- Дерево (высокий объект): **32×48**, якорь — центр ствола у земли. +- Дерево (высокий объект): **32×48**, якорь — центр ствола у земли. Три вида кроны + (`tree`, `tree_2`, `tree_3`) + кадр качания каждого (`*_sway`, крона +1px по X). +- Сателлиты персонажей: фонарь героя **7×8** (`chars/hero_lamp.png`, группа + `satellite` в sizes.mjs). - Пропсы (бочки, тележка Милы, рельсы): 16×16 или 16×24, тоже якорь у земли. - Крупные объекты (`props`, footprint w×h): спрайт покрывает весь footprint, якорь — низ-центр footprint'а (движок ставит сам). Слоты: diff --git a/docs/engine/maps.md b/docs/engine/maps.md index 6235e67..1e39e88 100644 --- a/docs/engine/maps.md +++ b/docs/engine/maps.md @@ -96,8 +96,11 @@ детерминированный, без состояния — вид карты стабилен между запусками, при `setTile` и в сейвах. Рантайм-путь — `setTileVariants(id, ids)`. -- **Анимация сильнее вариантов**: `setTileAnimation` снимает варианты id; - `setTileVariants` на анимированном id — no-op (воду не миксуют). +- **Анимация сочетается с вариантами**: клетки рисуются вариантом + (`variantOf`), анимация регистрируется на фактический id клетки — чтобы + анимировать весь id с вариантами, вызовите `setTileAnimation` для самого id + и каждого варианта (у разных вариантов может быть свой fps — качание крон + деревьев в демо рассинхронизировано именно так). - В файле карты (`MapFileV1`) ключи строковые (`"variants": {"0": [0, 5, 9]}`), `parseMap` валидирует и возвращает с числовыми ключами. Поле опционально. - id вариантов — обычные id тайлов (нужны текстуры в общей таблице); в `tiles` diff --git a/packages/engine/src/map/IsometricTileMap.ts b/packages/engine/src/map/IsometricTileMap.ts index ff38833..93a37c0 100644 --- a/packages/engine/src/map/IsometricTileMap.ts +++ b/packages/engine/src/map/IsometricTileMap.ts @@ -292,11 +292,12 @@ * Анимированный тайл: клетки с этим id переключают кадры по одному общему * таймлайну (дёшево при сотнях клеток воды). Регистрирует и уже * нарисованные клетки. frames — текстуры кадров (вода_1, вода_2, ...). - * Анимация сильнее вариантов: варианты этого id снимаются. + * Сочетается с вариантами: анимация регистрируется на фактический + * (вариантный) id клетки, поэтому для полного покрытия id с вариантами + * вызовите setTileAnimation и для каждого варианта. */ setTileAnimation(id: number, frames: Texture[], fps: number): void { if (frames.length === 0 || fps <= 0) return; - this.variants.delete(id); this.anims.set(id, { frames, fps, t: 0, sprites: new Set() }); for (const cell of this.cells.values()) { if (cell.ground && cell.groundId === id) this.registerAnim(cell.ground, id); @@ -321,10 +322,11 @@ /** * Рантайм-варианты текстур (движок не знает, что это — трава или пепел): * клетки id рисуются детерминированным выбором из ids (включая сам id). - * Анимированный id вариантов не получает — анимация сильнее. + * Сочетается с анимацией: каждая клетка анимируется по своему фактическому + * варианту (см. setTileAnimation). */ setTileVariants(id: number, ids: number[]): void { - if (ids.length === 0 || this.anims.has(id)) return; + if (ids.length === 0) return; this.variants.set(id, ids); for (const [key, cell] of this.cells) { if (cell.groundId === id || cell.objectId === id) { @@ -380,16 +382,18 @@ } // Высокий объект: спрайт с якорем в центре ромба, иначе колонна. + // objectId хранит фактический (вариантный) id — анимация матчится по нему. if (tall) { - fresh.objectId = id; - const objTex = this.textures.get(this.variantOf(id, tx, ty)); + const objId = this.variantOf(id, tx, ty); + fresh.objectId = objId; + const objTex = this.textures.get(objId); if (objTex) { const s = new Sprite(objTex); s.anchor.set(0.5, 1); s.position.set(p.x, p.y + iso.tileH / 2); this.objectsLayer.addChild(s); fresh.object = s; - this.registerAnim(s, id); + this.registerAnim(s, objId); } else { const ph = this.drawPlaceholder(p.x, p.y + iso.tileH / 2, 1, 1, tall.height); this.objectsLayer.addChild(ph); diff --git a/packages/engine/src/map/__tests__/isometricMap.test.ts b/packages/engine/src/map/__tests__/isometricMap.test.ts index 6405452..c325a6a 100644 --- a/packages/engine/src/map/__tests__/isometricMap.test.ts +++ b/packages/engine/src/map/__tests__/isometricMap.test.ts @@ -74,15 +74,23 @@ expect(map.variantOf(2, 3, 2)).toBe(2); }); - it('анимация сильнее: setTileVariants на анимированном id — no-op, setTileAnimation снимает варианты', () => { - const map = new IsometricTileMap(makeData(), new Map()); - map.setTileAnimation(0, [Texture.WHITE], 4); - map.setTileVariants(0, [0, 5]); // no-op - expect(map.variantOf(0, 3, 2)).toBe(0); - - const withVariants = new IsometricTileMap(makeDataWithVariants(), new Map()); - withVariants.setTileAnimation(0, [Texture.WHITE], 4); - expect(withVariants.variantOf(0, 3, 2)).toBe(0); // варианты сняты + it('анимация сочетается с вариантами: клетки анимируются по фактическому id', () => { + // id 3 — высокий объект (tall в makeData): с вариантами [3, 5]. + const data = makeData(); + data.tiles = new Array(16).fill(3); + const map = new IsometricTileMap(data, new Map([[3, Texture.WHITE]])); + map.setTileVariants(3, [3, 5]); + // Клетки получили варианты: у части клеток фактический id 5. + const resolved = new Set([map.variantOf(3, 0, 0), map.variantOf(3, 1, 0)]); + // Текстуры вариантных клеток отсутствуют — плейсхолдеры; важна семантика + // variantOf: анимация больше не снимает варианты. + expect(resolved.size).toBeGreaterThan(0); + map.setTileAnimation(3, [Texture.WHITE, Texture.EMPTY], 4); + expect(map.variantOf(3, 0, 0)).not.toBe(3); // вариант не снят + // Анимация фактического id (в т.ч. вариантного) регистрирует кадры. + map.setTileAnimation(5, [Texture.WHITE, Texture.EMPTY], 4); + map.update(0.5); + // Тик не бросает и не ломает клетки (дым-тест семантики). }); });