├── .gitignore
├── .vscode
├── commandbar.json
├── launch.json
├── settings.json
└── tasks.json
├── LICENSE
├── README.md
├── art
├── fontStyle.psd
├── logo.png
├── logo.psd
├── tiles.psd
└── tiles.tps
├── base.hxml
├── hl.debug.hxml
├── hl.dx.hxml
├── hl.hxml
├── hl.sdl.hxml
├── js.debug.hxml
├── js.html
├── js.hxml
├── langParser.hxml
├── led
├── editor
│ ├── app.html
│ ├── css
│ │ ├── app.css
│ │ ├── app.min.css
│ │ └── app.scss
│ ├── fonts
│ │ ├── LICENSE.txt
│ │ ├── RobotoCondensed-Bold.ttf
│ │ ├── RobotoCondensed-BoldItalic.ttf
│ │ ├── RobotoCondensed-Italic.ttf
│ │ ├── RobotoCondensed-Light.ttf
│ │ ├── RobotoCondensed-LightItalic.ttf
│ │ └── RobotoCondensed-Regular.ttf
│ ├── img
│ │ ├── grid.png
│ │ ├── icons
│ │ │ ├── drag.png
│ │ │ ├── entity.png
│ │ │ ├── intGrid.png
│ │ │ ├── layer.png
│ │ │ ├── level.png
│ │ │ ├── list.png
│ │ │ ├── mouseLeft.png
│ │ │ ├── mouseMiddle.png
│ │ │ ├── mouseRight.png
│ │ │ ├── mouseWheel.png
│ │ │ ├── projectSettings.png
│ │ │ └── tile.png
│ │ ├── key.png
│ │ └── stripes.png
│ ├── js
│ │ ├── app.js
│ │ ├── app.js.map
│ │ ├── html5sortable.min.js
│ │ └── jquery-3.5.1.js
│ ├── package.json
│ ├── tpl
│ │ ├── editEntityDefs.html
│ │ ├── editLayerDefs.html
│ │ ├── editTilesetDefs.html
│ │ ├── help.html
│ │ ├── levelList.html
│ │ └── projectSettings.html
│ └── userFiles
│ │ ├── atlas
│ │ ├── SystemShock.png
│ │ ├── cavesofgallet_tiles.png
│ │ ├── gif87a.gif
│ │ └── s4m_ur4i_huge-assetpack-tilemap.png
│ │ ├── gridLab.json
│ │ ├── map1.json
│ │ ├── map2.json
│ │ ├── map3.json
│ │ ├── map4.json
│ │ ├── resize.json
│ │ ├── test.json
│ │ ├── testImages
│ │ ├── gif87a.gif
│ │ ├── gif89.8colors.gif
│ │ ├── gif89a.gif
│ │ ├── jpeg.35colors.jpg
│ │ ├── jpeg.bw.jpg
│ │ ├── jpeg.color.jpg
│ │ ├── jpeg.fullcolor.jpg
│ │ ├── jpeg.gray.jpg
│ │ ├── jpeg2.color.jpg
│ │ └── png.png
│ │ └── undo.json
├── runEditor.nwjs.cmd
└── src.api
│ └── led
│ ├── Definitions.hx
│ ├── JsonTools.hx
│ ├── LedTypes.hx
│ ├── Level.hx
│ ├── Project.hx
│ ├── def
│ ├── EntityDef.hx
│ ├── EnumDef.hx
│ ├── FieldDef.hx
│ ├── LayerDef.hx
│ └── TilesetDef.hx
│ └── inst
│ ├── EntityInstance.hx
│ ├── FieldInstance.hx
│ └── LayerInstance.hx
├── redist
├── directx.zip
├── directx
│ └── DumberDwarves
│ │ ├── DumberDwarves.exe
│ │ ├── OpenAL32.dll
│ │ ├── d3dcompiler_47.dll
│ │ ├── directx.hdll
│ │ ├── fmt.hdll
│ │ ├── hlboot.dat
│ │ ├── libhl.dll
│ │ ├── msvcr120.dll
│ │ ├── openal.hdll
│ │ ├── ssl.hdll
│ │ ├── ui.hdll
│ │ └── uv.hdll
├── js.zip
├── js
│ ├── client.js
│ └── index.html
├── sdl_mac.zip
├── sdl_mac
│ └── DumberDwarves
│ │ ├── DumberDwarves
│ │ ├── hlboot.dat
│ │ ├── libSDL2-2.0.0.dylib
│ │ ├── libhl.dylib
│ │ ├── libmbedtls.10.dylib
│ │ ├── libopenal.1.dylib
│ │ ├── libpng16.16.dylib
│ │ ├── libuv.1.dylib
│ │ ├── libvorbis.0.dylib
│ │ └── libvorbisfile.3.dylib
├── sdl_win.zip
└── sdl_win
│ └── DumberDwarves
│ ├── DumberDwarves.exe
│ ├── OpenAL32.dll
│ ├── SDL2.dll
│ ├── fmt.hdll
│ ├── hlboot.dat
│ ├── libhl.dll
│ ├── msvcr120.dll
│ ├── openal.hdll
│ ├── sdl.hdll
│ ├── ssl.hdll
│ ├── ui.hdll
│ └── uv.hdll
├── res
├── atlas
│ ├── tiles.atlas
│ └── tiles.png
├── data.cdb
├── fonts
│ ├── barlow_condensed_medium_regular_11.fnt
│ ├── barlow_condensed_medium_regular_11.png
│ ├── barlow_condensed_medium_regular_17.fnt
│ ├── barlow_condensed_medium_regular_17.png
│ ├── barlow_condensed_medium_regular_32.fnt
│ ├── barlow_condensed_medium_regular_32.png
│ ├── barlow_condensed_medium_regular_9.fnt
│ ├── barlow_condensed_medium_regular_9.png
│ ├── minecraftiaOutline.fnt
│ └── minecraftiaOutline.png
├── lang
│ ├── en.mo
│ ├── en.po
│ └── sourceTexts.pot
├── ld
│ ├── tileset.png
│ └── world.json
└── props.json
├── screenshots
├── dumberDwarves-cover.png
├── god0.png
├── s0.png
├── s1.png
├── s2.png
├── s3.png
├── s4.gif
├── s5.avi
├── s6.avi
├── s7.avi
├── s8.mp4
└── s9.png
├── src.langParser
└── LangParser.hx
├── src
├── Assets.hx
├── Boot.hx
├── Camera.hx
├── Const.hx
├── Entity.hx
├── Fx.hx
├── Game.hx
├── Lang.hx
├── Level.hx
├── Main.hx
├── Types.hx
├── en
│ ├── Ai.hx
│ ├── BossDoor.hx
│ ├── Breakable.hx
│ ├── Cart.hx
│ ├── Item.hx
│ ├── Label.hx
│ ├── MobGen.hx
│ ├── Pointer.hx
│ └── ai
│ │ ├── Dwarf.hx
│ │ ├── Mob.hx
│ │ └── mob
│ │ ├── Boss.hx
│ │ └── Goblin.hx
├── import.hx
├── tools
│ ├── CPoint.hx
│ └── MouseCoords.hx
└── ui
│ ├── Bar.hx
│ ├── Console.hx
│ ├── Hud.hx
│ ├── Modal.hx
│ └── Window.hx
└── swf.hxml
/.gitignore:
--------------------------------------------------------------------------------
1 | res/.tmp
2 | redist.*
3 | bin/*.*
4 | art/export_*
--------------------------------------------------------------------------------
/.vscode/commandbar.json:
--------------------------------------------------------------------------------
1 | {
2 | "skipTerminateQuickPick": true,
3 | "skipSwitchToOutput": false,
4 | "skipErrorMessage": true,
5 | "commands": [
6 | {
7 | "text": "🍊 Build HL",
8 | "color": "orange",
9 | "commandType":"palette",
10 | "command": "workbench.action.tasks.runTask|HL release",
11 | "alignment": "right",
12 | "skipTerminateQuickPick": false,
13 | "priority": -10
14 | },
15 | {
16 | "text": "Run HL",
17 | "color": "orange",
18 | "command": "hl bin/client.hl",
19 | "alignment": "right",
20 | "skipTerminateQuickPick": false,
21 | "priority": -11
22 | },
23 | {
24 | "text": "☕ Build JS",
25 | "color": "yellow",
26 | "commandType":"palette",
27 | "command": "workbench.action.tasks.runTask|JS release",
28 | "alignment": "right",
29 | "skipTerminateQuickPick": false,
30 | "priority": -20
31 | },
32 | {
33 | "text": "Run JS",
34 | "color": "yellow",
35 | "command": "start js.html",
36 | "alignment": "right",
37 | "skipTerminateQuickPick": false,
38 | "priority": -21
39 | },
40 | {
41 | "text": "🅰️ Build POT",
42 | "color": "white",
43 | "commandType":"palette",
44 | "command": "workbench.action.tasks.runTask|Lang",
45 | "alignment": "right",
46 | "skipTerminateQuickPick": false,
47 | "priority": -40
48 | },
49 | {
50 | "text": "📦 Redist",
51 | "color": "lightgreen",
52 | "command": "haxelib run redistHelper hl.dx.hxml hl.sdl.hxml js.hxml -p DumberDwarves -zip",
53 | "alignment": "right",
54 | "skipTerminateQuickPick": false,
55 | "priority": -50
56 | }
57 | ]
58 | }
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "name": "HL debug",
9 | "request": "launch",
10 | "type": "hl",
11 | "hxml": "hl.debug.hxml",
12 | "cwd": "${workspaceRoot}",
13 | "preLaunchTask": "HL debug"
14 | },
15 | {
16 | "name": "Chrome JS debug",
17 | "request": "launch",
18 | "type": "chrome",
19 | "file": "${workspaceFolder}/js.html",
20 | "preLaunchTask": "JS debug"
21 | },
22 | {
23 | "name": "Firefox JS debug",
24 | "request": "launch",
25 | "type": "firefox",
26 | "file": "${workspaceFolder}/js.html",
27 | "preLaunchTask": "JS debug"
28 | }
29 | ]
30 | }
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "workbench.colorCustomizations": {
3 | "titleBar.inactiveBackground": "#494949",
4 | "titleBar.activeBackground": "#6d6d6d",
5 | "titleBar.activeForeground": "#ffffff"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | // See https://go.microsoft.com/fwlink/?LinkId=733558
3 | // for the documentation about the tasks.json format
4 | "version": "2.0.0",
5 | "tasks": [
6 | {
7 | "label": "HL debug",
8 | "type": "hxml",
9 | "file": "hl.debug.hxml",
10 | "presentation": {
11 | "reveal": "never",
12 | "panel": "dedicated",
13 | "clear": true
14 | },
15 | "problemMatcher": [ "$haxe-absolute", "$haxe", "$haxe-error", "$haxe-trace" ],
16 | "group": {
17 | "kind": "build",
18 | "isDefault": true
19 | }
20 | },
21 |
22 | {
23 | "label": "HL release",
24 | "type": "hxml",
25 | "file": "hl.dx.hxml",
26 | "presentation": {
27 | "reveal": "never",
28 | "panel": "dedicated",
29 | "clear": true
30 | },
31 | "problemMatcher": [ "$haxe-absolute", "$haxe", "$haxe-error", "$haxe-trace" ],
32 | },
33 |
34 | {
35 | "label": "JS release",
36 | "type": "hxml",
37 | "file": "js.hxml",
38 | "presentation": {
39 | "reveal": "never",
40 | "panel": "dedicated",
41 | "clear": true
42 | },
43 | "problemMatcher": [ "$haxe-absolute", "$haxe", "$haxe-error", "$haxe-trace" ],
44 | },
45 |
46 | {
47 | "label": "Flash release",
48 | "type": "hxml",
49 | "file": "swf.hxml",
50 | "presentation": {
51 | "reveal": "never",
52 | "panel": "dedicated",
53 | "clear": true
54 | },
55 | "problemMatcher": [ "$haxe-absolute", "$haxe", "$haxe-error", "$haxe-trace" ],
56 | },
57 |
58 | {
59 | "label": "Lang",
60 | "type": "hxml",
61 | "file": "langParser.hxml",
62 | "presentation": {
63 | "reveal": "always",
64 | "panel": "shared",
65 | "clear": true
66 | },
67 | "problemMatcher": [ "$haxe-absolute", "$haxe", "$haxe-error", "$haxe-trace" ],
68 | },
69 |
70 | {
71 | "label": "JS debug",
72 | "type": "hxml",
73 | "file": "js.debug.hxml",
74 | "presentation": {
75 | "reveal": "never",
76 | "panel": "dedicated",
77 | "clear": true
78 | },
79 | "problemMatcher": ["$haxe"],
80 | }
81 | ]
82 | }
83 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Attribution-NonCommercial-ShareAlike 4.0 International
2 | (BY-NC-SA 4.0)
3 |
4 | You are free to:
5 |
6 | Share — copy and redistribute the material in any medium or format
7 | Adapt — remix, transform, and build upon the material
8 |
9 | The licensor cannot revoke these freedoms as long as you follow the license terms.
10 |
11 |
12 | Under the following terms:
13 |
14 | Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
15 |
16 | NonCommercial — You may not use the material for commercial purposes.
17 |
18 | ShareAlike — If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original.
19 |
20 | No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits.
21 |
22 |
23 | Notices:
24 |
25 | You do not have to comply with the license for elements of the material in the public domain or where your use is permitted by an applicable exception or limitation.
26 | No warranties are given. The license may not give you all of the permissions necessary for your intended use. For example, other rights such as publicity, privacy, or moral rights may limit how you use the material.
27 |
28 | Full license here:
29 | https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## About
2 |
3 | Dumber Dwarves is a dungeon crawler where you can’t control the adventurers directly and they are not the sharpest tool in the shed. Slap them or throw some meat on the battlefield to give your “instructions”.
4 |
5 | The game was created in 48h (well, more like 35h) for the GMTK 2020 game jam. The theme was “Out of Control“.
6 |
7 | Play it here: https://deepnight.net/games/dumber-dwarves/
8 |
9 | ## Compiling
10 |
11 | You'll need:
12 |
13 | * **Haxe** compiler
14 | * **HeapsIO** framework
15 | * my libs: run ``haxelib install deepnightLibs``
16 |
17 | It is based on my GameBase repository:
18 |
19 | * GitHub: https://github.com/deepnight/gameBase
20 | * Doc: https://deepnight.net/tutorial/using-my-gamebase-to-create-a-heaps-game/
21 |
22 |
--------------------------------------------------------------------------------
/art/fontStyle.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/art/fontStyle.psd
--------------------------------------------------------------------------------
/art/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/art/logo.png
--------------------------------------------------------------------------------
/art/logo.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/art/logo.psd
--------------------------------------------------------------------------------
/art/tiles.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/art/tiles.psd
--------------------------------------------------------------------------------
/base.hxml:
--------------------------------------------------------------------------------
1 | -cp led/src.api
2 | -cp src
3 | -lib heaps
4 | -lib deepnightLibs
5 | -main Boot
6 | -dce full
--------------------------------------------------------------------------------
/hl.debug.hxml:
--------------------------------------------------------------------------------
1 | hl.dx.hxml
2 | -debug
--------------------------------------------------------------------------------
/hl.dx.hxml:
--------------------------------------------------------------------------------
1 | hl.hxml
2 | -lib hldx
--------------------------------------------------------------------------------
/hl.hxml:
--------------------------------------------------------------------------------
1 | base.hxml
2 | -D windowSize=2000x1400
3 | -hl bin/client.hl
4 |
--------------------------------------------------------------------------------
/hl.sdl.hxml:
--------------------------------------------------------------------------------
1 | hl.hxml
2 | -lib hlsdl
--------------------------------------------------------------------------------
/js.debug.hxml:
--------------------------------------------------------------------------------
1 | js.hxml
2 | -debug
--------------------------------------------------------------------------------
/js.html:
--------------------------------------------------------------------------------
1 |
2 |
base2D
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/js.hxml:
--------------------------------------------------------------------------------
1 | base.hxml
2 | -js bin/client.js
3 |
--------------------------------------------------------------------------------
/langParser.hxml:
--------------------------------------------------------------------------------
1 | -cp src.langParser
2 | -main LangParser
3 | -lib castle
4 | -lib deepnightLibs
5 | -D potools
6 | -hl bin/langParser.hl
7 |
8 | --next
9 | -cmd hl bin/langParser.hl
--------------------------------------------------------------------------------
/led/editor/app.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
28 |
29 |
30 |
31 |
some useful tips
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | 👁️
48 | ❌
49 |
50 |
51 |
52 |
53 |
59 |
60 |
61 |
62 |
63 |
66 |
67 |
68 |
69 |
70 |
73 |
74 |
75 |
76 |
77 |
82 |
83 |
84 |
85 |
86 |
100 |
101 |
102 |
103 |
104 |
117 |
118 |
119 |
120 |
121 |
122 |
--------------------------------------------------------------------------------
/led/editor/fonts/LICENSE.txt:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright [yyyy] [name of copyright owner]
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
203 |
--------------------------------------------------------------------------------
/led/editor/fonts/RobotoCondensed-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/led/editor/fonts/RobotoCondensed-Bold.ttf
--------------------------------------------------------------------------------
/led/editor/fonts/RobotoCondensed-BoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/led/editor/fonts/RobotoCondensed-BoldItalic.ttf
--------------------------------------------------------------------------------
/led/editor/fonts/RobotoCondensed-Italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/led/editor/fonts/RobotoCondensed-Italic.ttf
--------------------------------------------------------------------------------
/led/editor/fonts/RobotoCondensed-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/led/editor/fonts/RobotoCondensed-Light.ttf
--------------------------------------------------------------------------------
/led/editor/fonts/RobotoCondensed-LightItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/led/editor/fonts/RobotoCondensed-LightItalic.ttf
--------------------------------------------------------------------------------
/led/editor/fonts/RobotoCondensed-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/led/editor/fonts/RobotoCondensed-Regular.ttf
--------------------------------------------------------------------------------
/led/editor/img/grid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/led/editor/img/grid.png
--------------------------------------------------------------------------------
/led/editor/img/icons/drag.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/led/editor/img/icons/drag.png
--------------------------------------------------------------------------------
/led/editor/img/icons/entity.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/led/editor/img/icons/entity.png
--------------------------------------------------------------------------------
/led/editor/img/icons/intGrid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/led/editor/img/icons/intGrid.png
--------------------------------------------------------------------------------
/led/editor/img/icons/layer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/led/editor/img/icons/layer.png
--------------------------------------------------------------------------------
/led/editor/img/icons/level.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/led/editor/img/icons/level.png
--------------------------------------------------------------------------------
/led/editor/img/icons/list.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/led/editor/img/icons/list.png
--------------------------------------------------------------------------------
/led/editor/img/icons/mouseLeft.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/led/editor/img/icons/mouseLeft.png
--------------------------------------------------------------------------------
/led/editor/img/icons/mouseMiddle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/led/editor/img/icons/mouseMiddle.png
--------------------------------------------------------------------------------
/led/editor/img/icons/mouseRight.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/led/editor/img/icons/mouseRight.png
--------------------------------------------------------------------------------
/led/editor/img/icons/mouseWheel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/led/editor/img/icons/mouseWheel.png
--------------------------------------------------------------------------------
/led/editor/img/icons/projectSettings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/led/editor/img/icons/projectSettings.png
--------------------------------------------------------------------------------
/led/editor/img/icons/tile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/led/editor/img/icons/tile.png
--------------------------------------------------------------------------------
/led/editor/img/key.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/led/editor/img/key.png
--------------------------------------------------------------------------------
/led/editor/img/stripes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/led/editor/img/stripes.png
--------------------------------------------------------------------------------
/led/editor/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name" : "led",
3 | "version": "0.0.1",
4 | "description": "L-Ed, a lightweight & efficient 2D level editor",
5 |
6 | "window" : {
7 | "title" : "LEd",
8 | "width" : 800,
9 | "height" : 600,
10 | "show" : true
11 | },
12 | "main" : "app.html",
13 | "chromium-args":"--enable-spell-checking",
14 | "js-flags": "--expose-gc",
15 |
16 | "build": {
17 | "nwVersion": "0.46.4"
18 | }
19 | }
--------------------------------------------------------------------------------
/led/editor/tpl/editEntityDefs.html:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
14 |
15 | Create entity
16 | 🗑️
17 |
18 |
19 |
20 |
64 |
65 |
66 |
67 |
68 | Create field
69 | 🗑️
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/led/editor/tpl/editLayerDefs.html:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 | Create layer
15 | 🗑️
16 |
17 |
18 |
19 |
20 |
72 |
--------------------------------------------------------------------------------
/led/editor/tpl/editTilesetDefs.html:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
14 |
15 | Create tileset
16 | 🗑️
17 |
18 |
19 |
20 |
53 |
--------------------------------------------------------------------------------
/led/editor/tpl/help.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Draw
4 |
5 |
6 | Erase
7 |
8 | SPACE +
9 | Move the current level view
10 |
11 |
12 | Zoom
13 |
14 |
15 |
16 | H
17 | Show this help
18 |
19 | TAB
20 | Toggle compact mode
21 |
22 | CTRL S
23 | Save
24 |
25 |
--------------------------------------------------------------------------------
/led/editor/tpl/levelList.html:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 | Create level
12 | 🗑️
13 |
14 |
15 |
16 |
17 |
23 |
24 |
--------------------------------------------------------------------------------
/led/editor/tpl/projectSettings.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Project settings
4 |
5 |
6 |
7 | New project
8 | Load
9 | Save as
10 |
11 |
12 |
34 |
35 |
36 | Enumerations (Enums) are special value types of Entities.
37 |
38 |
39 |
40 |
41 |
42 | Create enum
43 | 🗑️
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/led/editor/userFiles/atlas/SystemShock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/led/editor/userFiles/atlas/SystemShock.png
--------------------------------------------------------------------------------
/led/editor/userFiles/atlas/cavesofgallet_tiles.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/led/editor/userFiles/atlas/cavesofgallet_tiles.png
--------------------------------------------------------------------------------
/led/editor/userFiles/atlas/gif87a.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/led/editor/userFiles/atlas/gif87a.gif
--------------------------------------------------------------------------------
/led/editor/userFiles/atlas/s4m_ur4i_huge-assetpack-tilemap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/led/editor/userFiles/atlas/s4m_ur4i_huge-assetpack-tilemap.png
--------------------------------------------------------------------------------
/led/editor/userFiles/map2.json:
--------------------------------------------------------------------------------
1 | {
2 | "dataVersion":1,
3 | "nextUniqId":2,
4 | "defs":{
5 | "layers":[
6 | {
7 | "uid":1,
8 | "type":{
9 | "id":0,
10 | "p":[
11 |
12 | ]
13 | },
14 | "name":"test",
15 | "gridSize":16,
16 | "displaydisplayOpacity":1,
17 | "intGridValues":[
18 | {
19 | "color":8234606
20 | }
21 | ]
22 | }
23 | ],
24 | "entities":[
25 |
26 | ],
27 | "tilesets":[
28 |
29 | ]
30 | },
31 | "levels":[
32 | {
33 | "uid":0,
34 | "pxWid":512,
35 | "pxHei":256,
36 | "layerInstances":[
37 | {
38 | "levelId":0,
39 | "layerDefId":1,
40 | "intGrid":[
41 | {
42 | "coordId":144,
43 | "v":0
44 | },
45 | {
46 | "coordId":145,
47 | "v":0
48 | },
49 | {
50 | "coordId":146,
51 | "v":0
52 | },
53 | {
54 | "coordId":147,
55 | "v":0
56 | },
57 | {
58 | "coordId":148,
59 | "v":0
60 | },
61 | {
62 | "coordId":149,
63 | "v":0
64 | },
65 | {
66 | "coordId":182,
67 | "v":0
68 | },
69 | {
70 | "coordId":183,
71 | "v":0
72 | },
73 | {
74 | "coordId":184,
75 | "v":0
76 | },
77 | {
78 | "coordId":217,
79 | "v":0
80 | },
81 | {
82 | "coordId":248,
83 | "v":0
84 | },
85 | {
86 | "coordId":279,
87 | "v":0
88 | },
89 | {
90 | "coordId":294,
91 | "v":0
92 | },
93 | {
94 | "coordId":295,
95 | "v":0
96 | },
97 | {
98 | "coordId":296,
99 | "v":0
100 | },
101 | {
102 | "coordId":297,
103 | "v":0
104 | },
105 | {
106 | "coordId":311,
107 | "v":0
108 | },
109 | {
110 | "coordId":325,
111 | "v":0
112 | },
113 | {
114 | "coordId":356,
115 | "v":0
116 | },
117 | {
118 | "coordId":388,
119 | "v":0
120 | },
121 | {
122 | "coordId":421,
123 | "v":0
124 | },
125 | {
126 | "coordId":430,
127 | "v":0
128 | },
129 | {
130 | "coordId":454,
131 | "v":0
132 | },
133 | {
134 | "coordId":455,
135 | "v":0
136 | },
137 | {
138 | "coordId":461,
139 | "v":0
140 | },
141 | {
142 | "coordId":462,
143 | "v":0
144 | },
145 | {
146 | "coordId":488,
147 | "v":0
148 | },
149 | {
150 | "coordId":489,
151 | "v":0
152 | },
153 | {
154 | "coordId":490,
155 | "v":0
156 | },
157 | {
158 | "coordId":491,
159 | "v":0
160 | },
161 | {
162 | "coordId":492,
163 | "v":0
164 | }
165 | ],
166 | "gridTiles":[
167 |
168 | ],
169 | "entityInstances":[
170 |
171 | ]
172 | }
173 | ]
174 | }
175 | ],
176 | "name":"New project",
177 | "defaultPivotX":0,
178 | "defaultPivotY":0,
179 | "defaultGridSize":16,
180 | "bgColor":16777215
181 | }
--------------------------------------------------------------------------------
/led/editor/userFiles/testImages/gif87a.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/led/editor/userFiles/testImages/gif87a.gif
--------------------------------------------------------------------------------
/led/editor/userFiles/testImages/gif89.8colors.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/led/editor/userFiles/testImages/gif89.8colors.gif
--------------------------------------------------------------------------------
/led/editor/userFiles/testImages/gif89a.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/led/editor/userFiles/testImages/gif89a.gif
--------------------------------------------------------------------------------
/led/editor/userFiles/testImages/jpeg.35colors.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/led/editor/userFiles/testImages/jpeg.35colors.jpg
--------------------------------------------------------------------------------
/led/editor/userFiles/testImages/jpeg.bw.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/led/editor/userFiles/testImages/jpeg.bw.jpg
--------------------------------------------------------------------------------
/led/editor/userFiles/testImages/jpeg.color.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/led/editor/userFiles/testImages/jpeg.color.jpg
--------------------------------------------------------------------------------
/led/editor/userFiles/testImages/jpeg.fullcolor.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/led/editor/userFiles/testImages/jpeg.fullcolor.jpg
--------------------------------------------------------------------------------
/led/editor/userFiles/testImages/jpeg.gray.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/led/editor/userFiles/testImages/jpeg.gray.jpg
--------------------------------------------------------------------------------
/led/editor/userFiles/testImages/jpeg2.color.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/led/editor/userFiles/testImages/jpeg2.color.jpg
--------------------------------------------------------------------------------
/led/editor/userFiles/testImages/png.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/led/editor/userFiles/testImages/png.png
--------------------------------------------------------------------------------
/led/runEditor.nwjs.cmd:
--------------------------------------------------------------------------------
1 | @start nw editor/
--------------------------------------------------------------------------------
/led/src.api/led/Definitions.hx:
--------------------------------------------------------------------------------
1 | package led;
2 |
3 | import led.LedTypes;
4 |
5 | class Definitions {
6 | var _project : Project;
7 |
8 | public var layers: Array = [];
9 | public var entities: Array = [];
10 | public var tilesets: Array = [];
11 | public var enums: Array = [];
12 |
13 |
14 | public function new(project:Project) {
15 | this._project = project;
16 | }
17 |
18 | public function toJson() : Dynamic {
19 | return {
20 | layers: layers.map( function(ld) return ld.toJson() ),
21 | entities: entities.map( function(ed) return ed.toJson() ),
22 | tilesets: tilesets.map( function(td) return td.toJson() ),
23 | enums: enums.map( function(ed) return ed.toJson() ),
24 | }
25 | }
26 |
27 | public static function fromJson(p:Project, json:Dynamic) {
28 | var d = new Definitions(p);
29 |
30 | for( layerJson in JsonTools.readArray(json.layers) )
31 | d.layers.push( led.def.LayerDef.fromJson(p.dataVersion, layerJson) );
32 |
33 | for( entityJson in JsonTools.readArray(json.entities) )
34 | d.entities.push( led.def.EntityDef.fromJson(p.dataVersion, entityJson) );
35 |
36 | for( tilesetJson in JsonTools.readArray(json.tilesets) )
37 | d.tilesets.push( led.def.TilesetDef.fromJson(p.dataVersion, tilesetJson) );
38 |
39 | for( enumJson in JsonTools.readArray(json.enums) )
40 | d.enums.push( led.def.EnumDef.fromJson(p.dataVersion, enumJson) );
41 |
42 | return d;
43 | }
44 |
45 | public function tidy(p:Project) {
46 | _project = p;
47 | }
48 |
49 | /** LAYER DEFS *****************************************/
50 |
51 | public function hasLayerType(t:LayerType) {
52 | for(ld in layers)
53 | if( ld.type==t )
54 | return true;
55 | return false;
56 | }
57 |
58 | public function getLayerDef(uid:Int) : Null {
59 | for(ld in layers)
60 | if( ld.uid==uid )
61 | return ld;
62 | return null;
63 | }
64 |
65 | public function createLayerDef(type:LayerType, ?name:String) : led.def.LayerDef {
66 | var l = new led.def.LayerDef(_project.makeUniqId(), type);
67 |
68 | #if editor
69 | if( name==null && isLayerNameValid( Lang.getLayerType(type).toString() ) ) // dirty fix for string comparison issue
70 | l.name = Lang.getLayerType(type);
71 | else if( name!=null && isLayerNameValid(name) )
72 | l.name = name;
73 | #end
74 |
75 | l.gridSize = _project.defaultGridSize;
76 | layers.push(l);
77 | _project.tidy();
78 | return l;
79 | }
80 |
81 | public function isLayerNameValid(name:String) {
82 | if( name==null || StringTools.trim(name).length==0 )
83 | return false;
84 |
85 | for(ld in layers)
86 | if( ld.name==name )
87 | return false;
88 | return true;
89 | }
90 |
91 | public function removeLayerDef(ld:led.def.LayerDef) {
92 | if( !layers.remove(ld) )
93 | throw "Unknown layerDef";
94 |
95 | _project.tidy();
96 | }
97 |
98 | public function sortLayerDef(from:Int, to:Int) : Null {
99 | if( from<0 || from>=layers.length || from==to )
100 | return null;
101 |
102 | if( to<0 || to>=layers.length )
103 | return null;
104 |
105 | _project.tidy();
106 |
107 | var moved = layers.splice(from,1)[0];
108 | layers.insert(to, moved);
109 | return moved;
110 | }
111 |
112 |
113 |
114 | /** ENTITY DEFS *****************************************/
115 |
116 | public function getEntityDef(uid:Int) : Null {
117 | for(ed in entities)
118 | if( ed.uid==uid )
119 | return ed;
120 | return null;
121 | }
122 |
123 | public function createEntityDef(?name:String) : led.def.EntityDef {
124 | var ed = new led.def.EntityDef(_project.makeUniqId());
125 | entities.push(ed);
126 |
127 | ed.setPivot( _project.defaultPivotX, _project.defaultPivotY );
128 |
129 | if( isEntityNameValid(name) )
130 | ed.name = name;
131 |
132 | return ed;
133 | }
134 |
135 | public function removeEntityDef(ed:led.def.EntityDef) {
136 | entities.remove(ed);
137 | _project.tidy();
138 | }
139 |
140 | public function isEntityNameValid(name:String) {
141 | if( name==null || name.length==0 )
142 | return false;
143 |
144 | for(ed in entities)
145 | if( ed.name==name )
146 | return false;
147 | return true;
148 | }
149 |
150 | public function sortEntityDef(from:Int, to:Int) : Null {
151 | if( from<0 || from>=entities.length || from==to )
152 | return null;
153 |
154 | if( to<0 || to>=entities.length )
155 | return null;
156 |
157 | _project.tidy();
158 |
159 | var moved = entities.splice(from,1)[0];
160 | entities.insert(to, moved);
161 |
162 | return moved;
163 | }
164 |
165 |
166 |
167 | /** FIELD DEFS *****************************************/
168 |
169 | public function getFieldDef(id:Int) : Null {
170 | for(ed in entities)
171 | for(fd in ed.fieldDefs)
172 | if( fd.uid==id )
173 | return fd;
174 |
175 | return null;
176 | }
177 |
178 |
179 | /** TILESET DEFS *****************************************/
180 |
181 | public function createTilesetDef() : led.def.TilesetDef {
182 | var td = new led.def.TilesetDef(_project.makeUniqId() );
183 | tilesets.push(td);
184 | _project.tidy();
185 | return td;
186 | }
187 |
188 | public function getTilesetDef(uid:Int) : Null {
189 | for(td in tilesets)
190 | if( td.uid==uid )
191 | return td;
192 | return null;
193 | }
194 |
195 |
196 | /** ENUM DEFS *****************************************/
197 |
198 | public function createEnumDef() : led.def.EnumDef {
199 | var uid = _project.makeUniqId();
200 | var ed = new led.def.EnumDef(uid, "LedEnum"+uid);
201 | enums.push(ed);
202 | _project.tidy();
203 | return ed;
204 | }
205 |
206 | public function removeEnumDef(ed:led.def.EnumDef) {
207 | if( !enums.remove(ed) )
208 | throw "EnumDef not found";
209 | _project.tidy();
210 | }
211 |
212 | function isEnumNameValid(name:String) {
213 | name = led.def.EnumDef.cleanUpString(name);
214 | for(ed in enums)
215 | if( ed.name==name )
216 | return false;
217 | return true;
218 | }
219 |
220 | public function getEnumDef(uid:Int) : Null {
221 | for(ed in enums)
222 | if( ed.uid==uid )
223 | return ed;
224 | return null;
225 | }
226 |
227 | }
--------------------------------------------------------------------------------
/led/src.api/led/JsonTools.hx:
--------------------------------------------------------------------------------
1 | package led;
2 |
3 | class JsonTools {
4 |
5 | public static function writeEnum(e:EnumValue, canBeNull:Bool) {
6 | if( e==null )
7 | if( canBeNull )
8 | return null;
9 | else
10 | throw "Enum is null";
11 |
12 | return { id:e.getIndex(), p:e.getParameters() }
13 | }
14 |
15 | public static function readEnum(e:Enum, o:{ id:Int, p:Array}, allowNull:Bool, ?def:T) : T {
16 | if( o==null ) {
17 | if( def==null && !allowNull )
18 | throw "Couldn't create "+e+", object is null";
19 | else
20 | return def;
21 | }
22 |
23 | try {
24 | return cast Type.createEnumIndex(e, o.id, o.p);
25 | }
26 | catch( err:Dynamic ) {
27 | if( def!=null )
28 | return def;
29 |
30 | if( !Reflect.hasField(o,"id") || Math.isNaN(o.id) )
31 | throw "Missing enum ID in "+o;
32 | else
33 | throw "Couldn't create "+e+" from "+o;
34 | }
35 | }
36 |
37 | public static function readString(v:Dynamic, allowNull=false) : Null {
38 | if( v==null && !allowNull )
39 | throw "Couldn't read String "+v;
40 |
41 | return v==null ? null : Std.string(v);
42 | }
43 |
44 | public static function readInt(v:Dynamic, ?defaultIfMissing:Int) : Int {
45 | if( v==null && defaultIfMissing!=null )
46 | return defaultIfMissing;
47 |
48 | if( v==null || Type.typeof(v)!=TInt )
49 | throw "Couldn't read Int "+v;
50 |
51 | return Std.int(v);
52 | }
53 |
54 | public static function readNullableInt(v:Dynamic) : Null {
55 | if( v==null )
56 | return null;
57 |
58 | if( Type.typeof(v)!=TInt )
59 | throw "Couldn't read Nullable Int "+v;
60 |
61 | return Std.int(v);
62 | }
63 |
64 | public static function readFloat(v:Dynamic, ?defaultIfMissing:Float) : Float {
65 | if( v==null && defaultIfMissing!=null )
66 | return defaultIfMissing;
67 |
68 | if( v==null || Type.typeof(v)!=TInt && Type.typeof(v)!=TFloat )
69 | throw "Couldn't read Float "+v;
70 |
71 | return v*1.0;
72 | }
73 |
74 | public static function readNullableFloat(v:Dynamic) : Null {
75 | if( v==null )
76 | return null;
77 |
78 | if( Type.typeof(v)!=TInt && Type.typeof(v)!=TFloat )
79 | throw "Couldn't read Float "+v;
80 |
81 | return v*1.0;
82 | }
83 |
84 | public static function clampFloatPrecision(v:Float, precision=3) {
85 | var p = Math.pow(10, precision);
86 | return dn.M.round(v*p)/p;
87 | }
88 |
89 | public static function readBool(v:Dynamic, ?defaultIfMissing:Bool) : Bool {
90 | if( v==null && defaultIfMissing!=null )
91 | return defaultIfMissing;
92 |
93 | if( v==null || Type.typeof(v)!=TBool )
94 | throw "Couldn't read Bool "+v;
95 |
96 | return v==true;
97 | }
98 |
99 | public static function readArray(arr:Dynamic) : Array {
100 | switch Type.typeof(arr) {
101 | case TClass(Array):
102 | case _: throw "Not an array ("+Type.typeof(arr)+")";
103 | }
104 | return arr;
105 | }
106 |
107 | }
108 |
--------------------------------------------------------------------------------
/led/src.api/led/LedTypes.hx:
--------------------------------------------------------------------------------
1 | package led;
2 |
3 | /*
4 | WARNING: all the follow types are serialized when saving a Project:
5 | - do not remove Enum values,
6 | - always add new Enum values at the end of the Enum,
7 | - Enum values can be renamed (they are stored as enum indexes)
8 | - do not rename Typedef fields or change their type
9 | */
10 |
11 | enum LayerType {
12 | IntGrid;
13 | Entities;
14 | Tiles;
15 | }
16 |
17 |
18 | typedef IntGridValueDef = {
19 | var name : Null;
20 | var color : UInt;
21 | }
22 |
23 | enum FieldType {
24 | F_Int;
25 | F_Float;
26 | F_String;
27 | F_Bool;
28 | F_Color;
29 | }
30 |
31 | enum ValueWrapper {
32 | V_Int(v:Int);
33 | V_Float(v:Float);
34 | V_Bool(v:Bool);
35 | V_String(v:String);
36 | }
37 |
38 | enum FieldDisplayMode {
39 | Hidden;
40 | ValueOnly;
41 | NameAndValue;
42 | }
43 |
44 | enum FieldDisplayPosition {
45 | Above;
46 | Beneath;
47 | }
48 |
49 | typedef TilesetSelection = {
50 | var ids : Array;
51 | var mode : TileEditMode;
52 | }
53 |
54 | enum TileEditMode {
55 | Stamp;
56 | Random;
57 | }
--------------------------------------------------------------------------------
/led/src.api/led/Level.hx:
--------------------------------------------------------------------------------
1 | package led;
2 |
3 | class Level {
4 | var _project : Project;
5 |
6 | public var uid(default,null) : Int;
7 | public var customName: Null; // TODO save
8 | public var pxWid : Int;
9 | public var pxHei : Int;
10 | public var layerInstances : Map = new Map();
11 |
12 |
13 | @:allow(led.Project)
14 | private function new(project:Project, uid:Int) {
15 | this.uid = uid;
16 | pxWid = Project.DEFAULT_LEVEL_WIDTH;
17 | pxHei = Project.DEFAULT_LEVEL_HEIGHT;
18 | this._project = project;
19 |
20 | for(ld in _project.defs.layers)
21 | layerInstances.set( ld.uid, new led.inst.LayerInstance(_project, uid, ld.uid) );
22 | }
23 |
24 | public inline function getName() return customName!=null ? customName : getDefaultName();
25 |
26 | public function getDefaultName() return "Level#"+uid;
27 |
28 | @:keep public function toString() {
29 | return Type.getClassName(Type.getClass(this));
30 | }
31 |
32 | public function toJson() {
33 | var layersJson = [];
34 | for(li in layerInstances)
35 | layersJson.push( li.toJson() );
36 |
37 | return {
38 | uid: uid,
39 | pxWid: pxWid,
40 | pxHei: pxHei,
41 | layerInstances : layersJson,
42 | customName: customName,
43 | }
44 | }
45 |
46 | public static function fromJson(p:Project, json:Dynamic) {
47 | var l = new Level( p, JsonTools.readInt(json.uid) );
48 | l.pxWid = JsonTools.readInt( json.pxWid, Project.DEFAULT_LEVEL_WIDTH );
49 | l.pxHei = JsonTools.readInt( json.pxHei, Project.DEFAULT_LEVEL_HEIGHT );
50 | l.customName = json.customName;
51 |
52 | for( layerJson in JsonTools.readArray(json.layerInstances) ) {
53 | var li = led.inst.LayerInstance.fromJson(p, layerJson);
54 | l.layerInstances.set(li.layerDefId, li);
55 | }
56 |
57 | return l;
58 | }
59 |
60 | public inline function inBounds(x:Int, y:Int) {
61 | return x>=0 && x=0 && yVoid ) {
111 | var i = _project.defs.layers.length-1;
112 | while( i>=0 ) {
113 | eachLayer( getLayerInstance(_project.defs.layers[i]) );
114 | i--;
115 | }
116 | }
117 |
118 | #if heaps
119 |
120 | public function renderAllLayers(target:h2d.Object) {
121 | iterateLayerInstancesInRenderOrder( function(li) {
122 | li.render(target);
123 | });
124 | }
125 |
126 | #else
127 |
128 | @:deprecated("Not implemented on this platform")
129 | public function renderAllLayers(target:Dynamic) {}
130 |
131 | #end
132 | }
133 |
--------------------------------------------------------------------------------
/led/src.api/led/Project.hx:
--------------------------------------------------------------------------------
1 | package led;
2 |
3 | class Project {
4 | public static var DEFAULT_LEVEL_WIDTH = 256; // px
5 | public static var DEFAULT_LEVEL_HEIGHT = 256; // px
6 | public static var DEFAULT_GRID_SIZE = 16; // px
7 |
8 | public static var DATA_VERSION = 1;
9 | /* DATA VERSION CHANGELOG:
10 | 1. initial release
11 | */
12 |
13 |
14 | var nextUniqId = 0;
15 | public var defs : Definitions;
16 | public var levels : Array = [];
17 |
18 | public var dataVersion : Int;
19 | public var name : String;
20 | public var defaultPivotX : Float;
21 | public var defaultPivotY : Float;
22 | public var defaultGridSize : Int;
23 | public var bgColor : UInt;
24 |
25 | private function new() {
26 | name = "New project";
27 | dataVersion = Project.DATA_VERSION;
28 | defaultGridSize = Project.DEFAULT_GRID_SIZE;
29 | bgColor = 0x7f8093;
30 | defaultPivotX = defaultPivotY = 0;
31 |
32 | defs = new Definitions(this);
33 | }
34 |
35 | public static function createEmpty() {
36 | var p = new Project();
37 | p.createLevel();
38 |
39 | return p;
40 | }
41 |
42 | public function makeUniqId() return nextUniqId++;
43 |
44 | @:keep public function toString() {
45 | return '$name(levels=${levels.length}, layerDefs=${defs.layers.length}, entDefs=${defs.entities.length})';
46 | }
47 |
48 | public static function fromJson(json:Dynamic) {
49 | var p = new Project();
50 | p.dataVersion = JsonTools.readInt(json.dataVersion, 0);
51 | p.nextUniqId = JsonTools.readInt( json.nextUniqId, 0 );
52 | p.name = JsonTools.readString( json.name );
53 | p.defaultPivotX = JsonTools.readFloat( json.defaultPivotX, 0 );
54 | p.defaultPivotY = JsonTools.readFloat( json.defaultPivotY, 0 );
55 | p.defaultGridSize = JsonTools.readInt( json.defaultGridSize, Project.DEFAULT_GRID_SIZE );
56 | p.bgColor = JsonTools.readInt( json.bgColor, 0xffffff );
57 |
58 | p.defs = Definitions.fromJson(p, json.defs);
59 |
60 | for( lvlJson in JsonTools.readArray(json.levels) )
61 | p.levels.push( Level.fromJson(p, lvlJson) );
62 |
63 | p.dataVersion = Project.DATA_VERSION; // always uses latest version
64 | return p;
65 | }
66 |
67 | public function toJson(excludeLevels=false) {
68 | return {
69 | dataVersion: dataVersion,
70 | nextUniqId: nextUniqId,
71 | defs: defs.toJson(),
72 | levels: excludeLevels ? [] : levels.map( function(l) return l.toJson() ),
73 |
74 | name: name,
75 | defaultPivotX: JsonTools.clampFloatPrecision( defaultPivotX ),
76 | defaultPivotY: JsonTools.clampFloatPrecision( defaultPivotY ),
77 | defaultGridSize: defaultGridSize,
78 | bgColor: bgColor,
79 | }
80 | }
81 |
82 | public function tidy() {
83 | for(level in levels)
84 | level.tidy(this);
85 |
86 | defs.tidy(this);
87 | }
88 |
89 |
90 | /** LEVELS *****************************************/
91 |
92 | public function createLevel() {
93 | var l = new Level(this, makeUniqId());
94 | levels.push(l);
95 | tidy(); // will create layer instances
96 | return l;
97 | }
98 |
99 | public function removeLevel(l:Level) {
100 | if( !levels.remove(l) )
101 | throw "Level not found in this Project";
102 |
103 | tidy();
104 | }
105 |
106 | public function getLevel(?name:String, ?uid:Int) : Null {
107 | for(l in levels)
108 | if( l.uid==uid || l.getName()==name )
109 | return l;
110 | return null;
111 | }
112 |
113 | public function sortLevel(from:Int, to:Int) : Null {
114 | if( from<0 || from>=levels.length || from==to )
115 | return null;
116 |
117 | if( to<0 || to>=levels.length )
118 | return null;
119 |
120 | tidy();
121 |
122 | var moved = levels.splice(from,1)[0];
123 | levels.insert(to, moved);
124 | return moved;
125 | }
126 |
127 |
128 |
129 |
130 |
131 | #if debug
132 | public static function createTest() : Project {
133 | var p = new Project();
134 |
135 | // Hero
136 | var ed = p.defs.createEntityDef("Hero");
137 | ed.color = 0x00ff00;
138 | ed.width = 24;
139 | ed.height = 32;
140 | ed.maxPerLevel = 1;
141 | ed.setPivot(0.5,1);
142 |
143 | // // Hero.life
144 | var fd = ed.createField(p, F_Int);
145 | fd.name = "life";
146 | fd.setDefault(Std.string(3));
147 | fd.setMin("1");
148 | fd.setMax("10");
149 |
150 | // Collision layer
151 | var ld = p.defs.layers[0];
152 | ld.name = "Collisions";
153 | ld.getIntGridValueDef(0).name = "walls";
154 | ld.addIntGridValue(0x00ff00, "grass");
155 | ld.addIntGridValue(0x0000ff, "water");
156 |
157 | // Entity layer
158 | var ld = p.defs.createLayerDef(Entities,"Entities");
159 |
160 | // Decoration layer
161 | var ld = p.defs.createLayerDef(IntGrid,"Decorations");
162 | ld.gridSize = 8;
163 | ld.displayOpacity = 0.7;
164 | ld.getIntGridValueDef(0).color = 0x00ff00;
165 |
166 | p.tidy();
167 |
168 | return p;
169 | }
170 | #end
171 | }
172 |
--------------------------------------------------------------------------------
/led/src.api/led/def/EntityDef.hx:
--------------------------------------------------------------------------------
1 | package led.def;
2 |
3 | import led.LedTypes;
4 |
5 | class EntityDef {
6 | public var uid(default,null) : Int;
7 | public var name : String;
8 | public var width : Int;
9 | public var height : Int;
10 | public var color : UInt;
11 | public var maxPerLevel : Int;
12 | public var discardExcess : Bool; // what to do when maxPerLevel is reached
13 | public var pivotX(default,set) : Float;
14 | public var pivotY(default,set) : Float;
15 |
16 | public var fieldDefs : Array = [];
17 |
18 |
19 | public function new(uid:Int) {
20 | this.uid = uid;
21 | color = 0xff0000;
22 | width = height = 16;
23 | maxPerLevel = 0;
24 | discardExcess = true;
25 | name = "New entity "+uid;
26 | setPivot(0.5,1);
27 | }
28 |
29 | @:keep public function toString() {
30 | return '$name($width x $height)['
31 | + fieldDefs.map( function(fd) return fd.name+":"+fd.type ).join(",")
32 | + "]";
33 | }
34 |
35 | public static function fromJson(dataVersion:Int, json:Dynamic) {
36 | var o = new EntityDef( JsonTools.readInt(json.uid) );
37 | o.name = JsonTools.readString( json.name );
38 | o.width = JsonTools.readInt( json.width, 16 );
39 | o.height = JsonTools.readInt( json.height, 16 );
40 | o.color = JsonTools.readInt( json.color, 0x0 );
41 | o.maxPerLevel = JsonTools.readInt( json.maxPerLevel, 0 );
42 | o.pivotX = JsonTools.readFloat( json.pivotX, 0 );
43 | o.pivotY = JsonTools.readFloat( json.pivotY, 0 );
44 | o.discardExcess = JsonTools.readBool( json.discardExcess, true );
45 |
46 | for(defJson in JsonTools.readArray(json.fieldDefs) )
47 | o.fieldDefs.push( FieldDef.fromJson(dataVersion, defJson) );
48 |
49 | return o;
50 | }
51 |
52 | public function toJson() {
53 | return {
54 | uid: uid,
55 | name: name,
56 | width: width,
57 | height: height,
58 | color: color,
59 | maxPerLevel: maxPerLevel,
60 | discardExcess: discardExcess,
61 | pivotX: JsonTools.clampFloatPrecision( pivotX ),
62 | pivotY: JsonTools.clampFloatPrecision( pivotY ),
63 |
64 | fieldDefs: fieldDefs.map( function(fd) return fd.toJson() ),
65 | }
66 | }
67 |
68 |
69 | public inline function setPivot(x,y) {
70 | pivotX = x;
71 | pivotY = y;
72 | }
73 |
74 | inline function set_pivotX(v) return pivotX = dn.M.fclamp(v, 0, 1);
75 | inline function set_pivotY(v) return pivotY = dn.M.fclamp(v, 0, 1);
76 |
77 |
78 | public function createField(project:Project, type:FieldType) : FieldDef {
79 | var f = new FieldDef(project.makeUniqId(), type);
80 | fieldDefs.push(f);
81 | return f;
82 | }
83 |
84 | public function removeField(project:Project, fd:FieldDef) {
85 | if( !fieldDefs.remove(fd) )
86 | throw "Unknown fieldDef";
87 |
88 | project.tidy();
89 | }
90 |
91 | public function sortField(from:Int, to:Int) : Null {
92 | if( from<0 || from>=fieldDefs.length || from==to )
93 | return null;
94 |
95 | if( to<0 || to>=fieldDefs.length )
96 | return null;
97 |
98 | var moved = fieldDefs.splice(from,1)[0];
99 | fieldDefs.insert(to, moved);
100 |
101 | return moved;
102 | }
103 |
104 | // TODO either
105 | public function getFieldDef(?name:String, ?id:Int) : Null {
106 | if( name==null && id==null )
107 | throw "Need 1 parameter";
108 |
109 | for(fd in fieldDefs)
110 | if( fd.uid==id || fd.name==name )
111 | return fd;
112 | return null;
113 | }
114 |
115 | }
--------------------------------------------------------------------------------
/led/src.api/led/def/EnumDef.hx:
--------------------------------------------------------------------------------
1 | package led.def;
2 |
3 | class EnumDef {
4 | public var uid(default,null) : Int;
5 | public var name(default,set) : String;
6 | public var values : Array = [];
7 |
8 | public function new(uid:Int, name:String) {
9 | this.uid = uid;
10 | this.name = name;
11 | }
12 |
13 | function set_name(v:String) {
14 | name = cleanUpString(v);
15 | return name;
16 | }
17 |
18 | @:keep public function toString() {
19 | return '$name(' + values.join(",")+")";
20 | }
21 |
22 | public static function fromJson(dataVersion:Int, json:Dynamic) {
23 | var ed = new EnumDef(JsonTools.readInt(json.uid), json.name);
24 |
25 | for(v in JsonTools.readArray(json.values))
26 | ed.values.push(v);
27 |
28 | return ed;
29 | }
30 |
31 | public function toJson() {
32 | return {
33 | uid: uid,
34 | name: name,
35 | values: values,
36 | };
37 | }
38 |
39 | public static inline function cleanUpString(str:String) {
40 | str = StringTools.trim(str);
41 | var reg = ~/[^0-9a-zA-Z_]+/gm;
42 | str = reg.replace(str, "_");
43 | return str;
44 | }
45 |
46 | function hasValue(v:String) {
47 | v = cleanUpString(v).toLowerCase();
48 | if( v.length==0 )
49 | return false;
50 |
51 | for(ev in values)
52 | if( ev.toLowerCase()==v )
53 | return true;
54 | return false;
55 | }
56 |
57 | public function isValueNameValid(v:String) {
58 | v = cleanUpString(v);
59 | return v.length>0 && !hasValue(v);
60 | }
61 |
62 | public function addValue(v:String) {
63 | if( !isValueNameValid(v) )
64 | return false;
65 |
66 | v = cleanUpString(v);
67 | values.push(v);
68 | return true;
69 | }
70 |
71 |
72 | public function tidy(p:Project) {
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/led/src.api/led/def/FieldDef.hx:
--------------------------------------------------------------------------------
1 | package led.def;
2 |
3 | class FieldDef {
4 | public var uid(default,null) : Int;
5 | public var type(default,null) : led.LedTypes.FieldType;
6 | public var name : String;
7 | public var canBeNull : Bool;
8 | public var editorDisplayMode : led.LedTypes.FieldDisplayMode;
9 | public var editorDisplayPos : led.LedTypes.FieldDisplayPosition;
10 |
11 | #if editor
12 | @:allow(ui.modal.panel.EditEntityDefs)
13 | #end
14 | var defaultOverride : Null;
15 |
16 | public var min : Null;
17 | public var max : Null;
18 |
19 | @:allow(led.def.EntityDef)
20 | private function new(uid:Int, t:led.LedTypes.FieldType) {
21 | this.uid = uid;
22 | type = t;
23 | editorDisplayMode = Hidden;
24 | editorDisplayPos = Above;
25 | name = "New field "+uid;
26 | canBeNull = type==F_String;
27 | min = max = null;
28 | defaultOverride = null;
29 | }
30 |
31 | @:keep public function toString() {
32 | return '$name('
33 | + ( canBeNull ? 'Null<$type>' : '$type' )
34 | + ', default=${getDefault()})'
35 | + ( type==F_Int || type==F_Float ? '[$min-$max]' : "" );
36 | }
37 |
38 | public static function fromJson(dataVersion:Int, json:Dynamic) {
39 | var o = new FieldDef( JsonTools.readInt(json.uid), JsonTools.readEnum(led.LedTypes.FieldType, json.type, false) );
40 | o.name = JsonTools.readString(json.name);
41 | o.canBeNull = JsonTools.readBool(json.canBeNull);
42 | o.editorDisplayMode = JsonTools.readEnum(led.LedTypes.FieldDisplayMode, json.editorDisplayMode, false, Hidden);
43 | o.editorDisplayPos = JsonTools.readEnum(led.LedTypes.FieldDisplayPosition, json.editorDisplayPos, false, Above);
44 | o.min = JsonTools.readNullableFloat(json.min);
45 | o.max = JsonTools.readNullableFloat(json.max);
46 | o.defaultOverride = JsonTools.readEnum(led.LedTypes.ValueWrapper, json.defaultOverride, true);
47 | return o;
48 | }
49 |
50 | public function toJson() {
51 | return {
52 | uid: uid,
53 | type: JsonTools.writeEnum(type, false),
54 | name: name,
55 | canBeNull: canBeNull,
56 | editorDisplayMode: JsonTools.writeEnum(editorDisplayMode, false),
57 | editorDisplayPos: JsonTools.writeEnum(editorDisplayPos, false),
58 | min: min==null ? null : JsonTools.clampFloatPrecision(min),
59 | max: max==null ? null : JsonTools.clampFloatPrecision(max),
60 | defaultOverride: JsonTools.writeEnum(defaultOverride, true),
61 | }
62 | }
63 |
64 |
65 | #if editor
66 | public function getDescription() {
67 | var infinity = "∞";
68 | return Lang.getFieldType(type)
69 | + ( canBeNull ? " nullable" : "" )
70 | + "=" + ( type==F_String && getDefault()!=null ? '"${getDefault()}"' : getDefault() )
71 | + ( min==null && max==null ? "" :
72 | ( type==F_Int ? " ["+(min==null?"-"+infinity:""+dn.M.round(min))+";"+(max==null?"+"+infinity:""+dn.M.round(max))+"]" : "" )
73 | + ( type==F_Float ? " ["+(min==null?"-"+infinity:""+min)+";"+(max==null?infinity:""+max)+"]" : "" )
74 | );
75 | }
76 | #end
77 |
78 | public inline function require(type:led.LedTypes.FieldType) {
79 | if( this.type!=type )
80 | throw "Only available on "+type+" fields";
81 | }
82 |
83 | public function iClamp(v:Null) {
84 | if( v==null )
85 | return v;
86 |
87 | if( min!=null )
88 | v = dn.M.imax(v, dn.M.round(min));
89 |
90 | if( max!=null )
91 | v = dn.M.imin(v, dn.M.round(max));
92 |
93 | return v;
94 | }
95 |
96 | public function fClamp(v:Null) {
97 | if( v==null )
98 | return v;
99 |
100 | if( min!=null )
101 | v = dn.M.fmax(v, min);
102 |
103 | if( max!=null )
104 | v = dn.M.fmin(v, max);
105 |
106 | return v;
107 | }
108 |
109 | public function getUntypedDefault() : Dynamic {
110 | return switch defaultOverride {
111 | case null: null;
112 | case V_Int(v): v;
113 | case V_Float(v): v;
114 | case V_Bool(v): v;
115 | case V_String(v): v;
116 | }
117 | }
118 |
119 | public function getBoolDefault() : Null {
120 | require(F_Bool);
121 | return switch defaultOverride {
122 | case null: canBeNull ? null : false;
123 | case V_Bool(v): v;
124 | case _: null;
125 | }
126 | }
127 |
128 | public function getColorDefault() : Null {
129 | require(F_Color);
130 | return switch defaultOverride {
131 | case null: canBeNull ? null : 0x0;
132 | case V_Int(v): v;
133 | case _: null;
134 | }
135 | }
136 |
137 | public function getIntDefault() : Null {
138 | require(F_Int);
139 | return iClamp(switch defaultOverride {
140 | case null: canBeNull ? null : 0;
141 | case V_Int(v): v;
142 | case _: null;
143 | });
144 | }
145 |
146 | public function getFloatDefault() : Null {
147 | require(F_Float);
148 | return fClamp( switch defaultOverride {
149 | case null: canBeNull ? null : 0.;
150 | case V_Float(v): v;
151 | case _: null;
152 | });
153 | }
154 |
155 | public function getStringDefault() : Null {
156 | require(F_String);
157 | return switch defaultOverride {
158 | case null: canBeNull ? null : "";
159 | case V_String(v): v;
160 | case _: null;
161 | }
162 | }
163 |
164 | public function restoreDefault() {
165 | defaultOverride = null;
166 | }
167 |
168 | public function setDefault(rawDef:Null) {
169 | if( rawDef==null )
170 | defaultOverride = null;
171 | else switch type {
172 | case F_Int:
173 | var def = Std.parseInt(rawDef);
174 | defaultOverride = !dn.M.isValidNumber(def) ? null : V_Int( iClamp(def) );
175 |
176 | case F_Color:
177 | var def = dn.Color.hexToInt(rawDef);
178 | defaultOverride = !dn.M.isValidNumber(def) ? null : V_Int(def);
179 |
180 | case F_Float:
181 | var def = Std.parseFloat(rawDef);
182 | defaultOverride = !dn.M.isValidNumber(def) ? null : V_Float( fClamp(def) );
183 |
184 | case F_String:
185 | rawDef = StringTools.trim(rawDef);
186 | defaultOverride = rawDef=="" ? null : V_String(rawDef);
187 |
188 | case F_Bool:
189 | rawDef = StringTools.trim(rawDef).toLowerCase();
190 | if( rawDef=="true" ) defaultOverride = V_Bool(true);
191 | else if( rawDef=="false" ) defaultOverride = V_Bool(false);
192 | else defaultOverride = null;
193 |
194 | }
195 | }
196 |
197 | public function getDefault() : Dynamic {
198 | return switch type {
199 | case F_Int: getIntDefault();
200 | case F_Color: getColorDefault();
201 | case F_Float: getFloatDefault();
202 | case F_String: getStringDefault();
203 | case F_Bool: getBoolDefault();
204 | }
205 | }
206 |
207 |
208 | public function setMin(raw:Null) {
209 | if( raw==null )
210 | min = null;
211 | else {
212 | switch type {
213 | case F_Int:
214 | var v = Std.parseInt(raw);
215 | if( !dn.M.isValidNumber(v) )
216 | min = null;
217 | else
218 | min = v;
219 |
220 | case F_Float:
221 | var v = Std.parseFloat(raw);
222 | if( !dn.M.isValidNumber(v) )
223 | min = null;
224 | else
225 | min = v;
226 |
227 | case _:
228 | }
229 | }
230 | checkMinMax();
231 | }
232 |
233 | public function setMax(raw:Null) {
234 | if( raw==null )
235 | max = null;
236 | else {
237 | switch type {
238 | case F_Int:
239 | var v = Std.parseInt(raw);
240 | if( !dn.M.isValidNumber(v) )
241 | max = null;
242 | else
243 | max = v;
244 |
245 | case F_Float:
246 | var v = Std.parseFloat(raw);
247 | if( !dn.M.isValidNumber(v) )
248 | max = null;
249 | else
250 | max = v;
251 |
252 | case _:
253 | }
254 | }
255 | checkMinMax();
256 | }
257 |
258 | function checkMinMax() {
259 | if( type!=F_Int && type!=F_Float )
260 | return;
261 |
262 | // Swap reversed min/max
263 | if( min!=null && max!=null && max = [];
14 |
15 | // Tileset
16 | public var tilesetDefId : Null;
17 | public var tilePivotX(default,set) : Float;
18 | public var tilePivotY(default,set) : Float;
19 |
20 | public function new(uid:Int, t:LayerType) {
21 | this.uid = uid;
22 | type = t;
23 | #if editor
24 | name = Lang.getLayerType(type)+" #"+uid;
25 | #else
26 | name = type+"#"+uid;
27 | #end
28 | addIntGridValue(0x0);
29 | }
30 |
31 | @:keep public function toString() {
32 | return '$name($type, ${gridSize}px)';
33 | }
34 |
35 | public static function fromJson(dataVersion:Int, json:Dynamic) {
36 | var o = new LayerDef( JsonTools.readInt(json.uid), JsonTools.readEnum(LayerType, json.type, false));
37 | o.name = JsonTools.readString(json.name);
38 | o.gridSize = JsonTools.readInt(json.gridSize, Project.DEFAULT_GRID_SIZE);
39 | o.displayOpacity = JsonTools.readFloat(json.displayOpacity, 1);
40 |
41 | o.intGridValues = [];
42 | for( v in JsonTools.readArray(json.intGridValues) )
43 | o.intGridValues.push(v);
44 |
45 | o.tilesetDefId = JsonTools.readNullableInt(json.tilesetDefId);
46 | o.tilePivotX = JsonTools.readFloat(json.tilePivotX, 0);
47 | o.tilePivotY = JsonTools.readFloat(json.tilePivotY, 0);
48 |
49 | return o;
50 | }
51 |
52 | public function toJson() {
53 | return {
54 | uid: uid,
55 | type: JsonTools.writeEnum(type, false),
56 | name: name,
57 | gridSize: gridSize,
58 | displayOpacity: JsonTools.clampFloatPrecision(displayOpacity),
59 |
60 | intGridValues: intGridValues,
61 |
62 | tilesetDefId: tilesetDefId,
63 | tilePivotX: tilePivotX,
64 | tilePivotY: tilePivotY,
65 | }
66 | }
67 |
68 |
69 | public function addIntGridValue(col:UInt, ?name:String) {
70 | if( !isIntGridValueNameValid(name) )
71 | throw "Invalid intGrid value name "+name;
72 | intGridValues.push({
73 | color: col,
74 | name: name,
75 | });
76 | }
77 |
78 | public function getIntGridValueDef(idx:Int) : Null {
79 | return intGridValues[idx];
80 | }
81 |
82 | public inline function getAllIntGridValues() return intGridValues;
83 | public inline function countIntGridValues() return intGridValues.length;
84 |
85 |
86 | public function isIntGridValueUsedInProject(p:Project, idx:Int) {
87 | for(level in p.levels) {
88 | var li = level.getLayerInstance(this);
89 | if( li!=null ) {
90 | for(cx in 0...li.cWid)
91 | for(cy in 0...li.cHei)
92 | if( li.getIntGrid(cx,cy)==idx )
93 | return true;
94 | }
95 | }
96 | return false;
97 | }
98 |
99 | public function isIntGridValueNameValid(name:Null) {
100 | if( name==null )
101 | return true;
102 |
103 | for(v in intGridValues)
104 | if( v.name==name )
105 | return false;
106 |
107 | return true;
108 | }
109 |
110 |
111 |
112 | public function hasTileset() return tilesetDefId!=null;
113 |
114 |
115 | inline function set_tilePivotX(v) return tilePivotX = dn.M.fclamp(v, 0, 1);
116 | inline function set_tilePivotY(v) return tilePivotY = dn.M.fclamp(v, 0, 1);
117 |
118 | }
--------------------------------------------------------------------------------
/led/src.api/led/def/TilesetDef.hx:
--------------------------------------------------------------------------------
1 | package led.def;
2 |
3 | import led.LedTypes;
4 |
5 | class TilesetDef {
6 | public var uid : Int;
7 | public var fileBase64(default,set) : Null;
8 | public var path : Null;
9 | public var customName : Null;
10 | public var pxWid = 0;
11 | public var pxHei = 0;
12 | public var tileGridSize : Int = Project.DEFAULT_GRID_SIZE;
13 | public var tileGridSpacing : Int = 0;
14 | public var savedSelections : Array = [];
15 |
16 | #if heaps
17 | var texture(get,never) : Null;
18 | var _textureCache : Null;
19 |
20 | var pixels(get,never) : Null;
21 | var _pixelsCache : Null;
22 | #end
23 |
24 | public var cWid(get,never) : Int; inline function get_cWid() return !hasAtlas() ? 0 : dn.M.ceil( pxWid / tileGridSize );
25 | public var cHei(get,never) : Int; inline function get_cHei() return !hasAtlas() ? 0 : dn.M.ceil( pxHei / tileGridSize );
26 |
27 |
28 | public function new(uid:Int) {
29 | this.uid = uid;
30 | }
31 |
32 | public function getName() {
33 | return customName!=null ? customName : getDefaultName();
34 | }
35 |
36 | public function getDefaultName() {
37 | return path!=null ? dn.FilePath.extractFileWithExt(path) : "Empty tileset "+uid;
38 | }
39 |
40 | public function getFileName() : Null {
41 | if( path==null || !hasAtlas() )
42 | return null;
43 |
44 | return dn.FilePath.extractFileWithExt(path);
45 | }
46 |
47 | function set_fileBase64(str:String) {
48 | disposeAtlasCache();
49 | return fileBase64 = str;
50 | }
51 |
52 | public function disposeAtlasCache() {
53 | #if heaps
54 | if( _textureCache!=null )
55 | _textureCache.dispose();
56 | _textureCache = null;
57 |
58 | if( _pixelsCache!=null )
59 | _pixelsCache.dispose();
60 | _pixelsCache = null;
61 | #end
62 | }
63 |
64 | public function clearAtlas() {
65 | fileBase64 = null;
66 | path = null;
67 | savedSelections = [];
68 | }
69 |
70 | public inline function hasAtlas() return fileBase64!=null;
71 |
72 |
73 | public function toJson() {
74 | return {
75 | uid: uid,
76 | fileBase64: fileBase64,
77 | path: path,
78 | customName: customName,
79 | pxWid: pxWid,
80 | pxHei: pxHei,
81 | tileGridSize: tileGridSize,
82 | tileGridSpacing: tileGridSpacing,
83 | savedSelections: savedSelections.map( function(sel) {
84 | return { ids:sel.ids, mode:JsonTools.writeEnum(sel.mode, false) }
85 | }),
86 | }
87 | }
88 |
89 |
90 | public static function fromJson(dataVersion:Int, json:Dynamic) {
91 | var td = new TilesetDef( JsonTools.readInt(json.uid) );
92 | td.tileGridSize = JsonTools.readInt(json.tileGridSize, Project.DEFAULT_GRID_SIZE);
93 | td.tileGridSpacing = JsonTools.readInt(json.tileGridSpacing, 0);
94 | td.pxWid = JsonTools.readInt( json.pxWid );
95 | td.pxHei = JsonTools.readInt( json.pxHei );
96 | td.fileBase64 = json.fileBase64;
97 | td.path = json.path;
98 | td.customName = json.customName;
99 |
100 | var arr = JsonTools.readArray( json.savedSelections );
101 | td.savedSelections = json.savedSelections==null ? [] : arr.map( function(jsonSel:Dynamic) {
102 | return {
103 | mode: JsonTools.readEnum(TileEditMode, jsonSel.mode, false, Stamp),
104 | ids: jsonSel.ids,
105 | }
106 | }) ;
107 | return td;
108 | }
109 |
110 | public function importImage(filePath:String, fileContent:haxe.io.Bytes) : Bool {
111 | clearAtlas();
112 |
113 | var img = dn.ImageDecoder.decode(fileContent);
114 | if( img==null )
115 | return false;
116 |
117 | path = dn.FilePath.fromFile(filePath).useSlashes().full;
118 | fileBase64 = haxe.crypto.Base64.encode(fileContent);
119 | pxWid = img.width;
120 | pxHei = img.height;
121 | return true;
122 | }
123 |
124 | public function getTileId(tcx,tcy) {
125 | return tcx + tcy * cWid;
126 | }
127 |
128 | public inline function getTileCx(tileId:Int) {
129 | return tileId - cWid * Std.int( tileId / cWid );
130 | }
131 |
132 | public inline function getTileCy(tileId:Int) {
133 | return Std.int( tileId / cWid );
134 | }
135 |
136 | public inline function getTileSourceX(tileId:Int) {
137 | return getTileCx(tileId) * ( tileGridSize + tileGridSpacing );
138 | }
139 |
140 | public inline function getTileSourceY(tileId:Int) {
141 | return getTileCy(tileId) * ( tileGridSize + tileGridSpacing );
142 | }
143 |
144 | public function dispose() {
145 | disposeAtlasCache();
146 | fileBase64 = null;
147 | }
148 |
149 |
150 | public function saveSelection(tsSel:TilesetSelection) {
151 | // Remove existing overlapping saved selections
152 | for(tid in tsSel.ids) {
153 | var saved = getSavedSelectionFor(tid);
154 | if( saved!=null )
155 | savedSelections.remove(saved);
156 | }
157 |
158 | if( tsSel.ids.length>1 )
159 | savedSelections.push({
160 | mode: tsSel.mode,
161 | ids: tsSel.ids.copy(),
162 | });
163 | }
164 |
165 | public inline function hasSavedSelectionFor(tid:Int) : Bool {
166 | return getSavedSelectionFor(tid)!=null;
167 | }
168 |
169 | public function getSavedSelectionFor(tid:Int) : Null< TilesetSelection > {
170 | for(sel in savedSelections)
171 | for(stid in sel.ids)
172 | if( stid==tid )
173 | return sel;
174 | return null;
175 | }
176 |
177 |
178 |
179 | /*** HEAPS API *********************************/
180 | #if heaps
181 |
182 | public inline function getAtlasTile() : Null {
183 | return texture==null ? null : h2d.Tile.fromTexture(texture);
184 | }
185 |
186 | public inline function getTile(tileId:Int) {
187 | return getAtlasTile().sub( getTileSourceX(tileId), getTileSourceY(tileId), tileGridSize, tileGridSize );
188 | }
189 |
190 | function get_texture() {
191 | if( _textureCache==null && pixels!=null )
192 | _textureCache = h3d.mat.Texture.fromPixels(pixels);
193 | return _textureCache;
194 | }
195 |
196 | function get_pixels() {
197 | if( _pixelsCache==null && fileBase64!=null ) {
198 | var bytes = haxe.crypto.Base64.decode( fileBase64 );
199 | _pixelsCache = dn.ImageDecoder.decodePixels(bytes);
200 | }
201 | return _pixelsCache;
202 | }
203 |
204 | #end
205 |
206 |
207 |
208 | /*** JS API *********************************/
209 | #if js
210 |
211 | public function createAtlasHtmlImage() : js.html.Image {
212 | var img = new js.html.Image();
213 | if( hasAtlas() )
214 | img.src = 'data:image/png;base64,$fileBase64';
215 | return img;
216 | }
217 |
218 | #if editor
219 | public function drawAtlasToCanvas(canvas:js.jquery.JQuery) {
220 | if( !canvas.is("canvas") )
221 | throw "Not a canvas";
222 |
223 | if( !hasAtlas() )
224 | return;
225 |
226 | var canvas = Std.downcast(canvas.get(0), js.html.CanvasElement);
227 | var ctx = canvas.getContext2d();
228 | ctx.clearRect(0, 0, canvas.width, canvas.height);
229 |
230 | var img = new js.html.Image(pixels.width, pixels.height);
231 | img.src = 'data:image/png;base64,$fileBase64';
232 | img.onload = function() {
233 | ctx.drawImage(img, 0, 0);
234 | }
235 | }
236 |
237 | public function drawTileToCanvas(canvas:js.jquery.JQuery, tileId:Int, toX:Int, toY:Int) {
238 | if( pixels==null )
239 | return;
240 |
241 | if( !canvas.is("canvas") )
242 | throw "Not a canvas";
243 |
244 | if( getTileSourceX(tileId)+tileGridSize>=pxWid || getTileSourceY(tileId)+tileGridSize>=pxHei )
245 | return; // out of bounds
246 |
247 | var subPixels = pixels.sub(getTileSourceX(tileId), getTileSourceY(tileId), tileGridSize, tileGridSize);
248 | var canvas = Std.downcast(canvas.get(0), js.html.CanvasElement);
249 | var ctx = canvas.getContext2d();
250 | var img = new js.html.Image(subPixels.width, subPixels.height);
251 | var b64 = haxe.crypto.Base64.encode( subPixels.toPNG() );
252 | img.src = 'data:image/png;base64,$b64';
253 | img.onload = function() {
254 | ctx.drawImage(img, toX, toY);
255 | }
256 | }
257 | #end
258 |
259 | #end
260 | }
--------------------------------------------------------------------------------
/led/src.api/led/inst/EntityInstance.hx:
--------------------------------------------------------------------------------
1 | package led.inst;
2 |
3 | class EntityInstance {
4 | public var _project : Project;
5 | public var def(get,never) : led.def.EntityDef; inline function get_def() return _project.defs.getEntityDef(defId);
6 |
7 | public var defId(default,null) : Int;
8 | public var x : Int;
9 | public var y : Int;
10 | var fieldInstances : Map = new Map();
11 |
12 | public var left(get,never) : Int; inline function get_left() return Std.int( x - def.width*def.pivotX );
13 | public var right(get,never) : Int; inline function get_right() return left + def.width-1;
14 | public var top(get,never) : Int; inline function get_top() return Std.int( y - def.height*def.pivotY );
15 | public var bottom(get,never) : Int; inline function get_bottom() return top + def.height-1;
16 |
17 |
18 | public function new(p:Project, entityDefId:Int) {
19 | _project = p;
20 | defId = entityDefId;
21 | }
22 |
23 | @:keep public function toString() {
24 | return 'Instance<${def.name}>@$x,$y';
25 | }
26 |
27 | public function toJson() {
28 | var fieldsJson = [];
29 | for(fi in fieldInstances)
30 | fieldsJson.push( fi.toJson() );
31 |
32 | return {
33 | defId: defId,
34 | x: x,
35 | y: y,
36 | fieldInstances: fieldsJson,
37 | }
38 | }
39 |
40 | public static function fromJson(project:Project, json:Dynamic) {
41 | var ei = new EntityInstance(project, JsonTools.readInt(json.defId));
42 | ei.x = JsonTools.readInt( json.x, 0 );
43 | ei.y = JsonTools.readInt( json.y, 0 );
44 |
45 | for( fieldJson in JsonTools.readArray(json.fieldInstances) ) {
46 | var fi = FieldInstance.fromJson(project, fieldJson);
47 | ei.fieldInstances.set(fi.defId, fi);
48 | }
49 |
50 | return ei;
51 | }
52 |
53 | // TODO get rid of this parameter
54 | public function getCx(ld:led.def.LayerDef) {
55 | return Std.int( ( x + (def.pivotX==1 ? -1 : 0) ) / ld.gridSize );
56 | }
57 |
58 | public function getCy(ld:led.def.LayerDef) {
59 | return Std.int( ( y + (def.pivotY==1 ? -1 : 0) ) / ld.gridSize );
60 | }
61 |
62 | public function isOver(levelX:Int, levelY:Int) {
63 | return levelX >= left && levelX <= right && levelY >= top && levelY <= bottom;
64 | }
65 |
66 | public function tidy(p:led.Project) {
67 | _project = p;
68 |
69 | // Remove field instances whose def was removed
70 | for(e in fieldInstances.keyValueIterator())
71 | if( e.value.def==null )
72 | fieldInstances.remove(e.key);
73 |
74 | for(fi in fieldInstances)
75 | fi.tidy(_project);
76 | }
77 |
78 |
79 | // ** FIELDS **********************************
80 |
81 | public function getFieldInstance(fieldDef:led.def.FieldDef) {
82 | if( !fieldInstances.exists(fieldDef.uid) )
83 | fieldInstances.set(fieldDef.uid, new led.inst.FieldInstance(_project, fieldDef.uid));
84 | return fieldInstances.get( fieldDef.uid );
85 | }
86 |
87 | public function getStringField(name:String) : Null {
88 | var fd = def.getFieldDef(name);
89 | fd.require(F_String);
90 | return getFieldInstance(fd).getString();
91 | }
92 |
93 | public function getFloatField(name:String) : Null {
94 | var fd = def.getFieldDef(name);
95 | fd.require(F_Float);
96 | return getFieldInstance(fd).getFloat();
97 | }
98 |
99 | public function getIntField(name:String) : Null {
100 | var fd = def.getFieldDef(name);
101 | fd.require(F_Int);
102 | return getFieldInstance(fd).getInt();
103 | }
104 |
105 | }
--------------------------------------------------------------------------------
/led/src.api/led/inst/FieldInstance.hx:
--------------------------------------------------------------------------------
1 | package led.inst;
2 |
3 | import led.LedTypes;
4 |
5 | class FieldInstance {
6 | public var _project : Project;
7 | public var def(get,never) : led.def.FieldDef; inline function get_def() return _project.defs.getFieldDef(defId);
8 |
9 | public var defId: Int;
10 | var internalValue : Null;
11 |
12 | @:allow(led.inst.EntityInstance)
13 | private function new(p:Project, fieldDefId:Int) {
14 | _project = p;
15 | defId = fieldDefId;
16 | internalValue = null;
17 | }
18 |
19 | @:keep
20 | public function toString() {
21 | return
22 | '${def.name} = '
23 | + getForDisplay()
24 | + ' [ $internalValue ]';
25 | }
26 |
27 | public static function fromJson(project:Project, json:Dynamic) {
28 | var o = new FieldInstance( project, JsonTools.readInt(json.defId) );
29 | o.internalValue = JsonTools.readEnum(ValueWrapper, json.internalValue, true);
30 | return o;
31 | }
32 |
33 | public function toJson() {
34 | return {
35 | defId: defId,
36 | internalValue: JsonTools.writeEnum(internalValue,true),
37 | }
38 | }
39 |
40 | inline function require(type:FieldType) {
41 | if( def.type!=type )
42 | throw "Only available on "+type+" fields";
43 | }
44 |
45 | function setInternal(fv:Null) {
46 | internalValue = fv;
47 | }
48 |
49 | public function isUsingDefault() {
50 | return internalValue==null;
51 | }
52 |
53 |
54 | public function parseValue(raw:Null) {
55 | if( raw==null )
56 | setInternal(null);
57 | else switch def.type {
58 | case F_Int:
59 | var v = Std.parseInt(raw);
60 | if( !dn.M.isValidNumber(v) )
61 | setInternal(null);
62 | else {
63 | v = def.iClamp(v);
64 | setInternal( V_Int(v) );
65 | }
66 |
67 | case F_Color:
68 | setInternal( raw==null ? null : V_Int(dn.Color.hexToInt(raw)) );
69 |
70 | case F_Float:
71 | var v = Std.parseFloat(raw);
72 | if( !dn.M.isValidNumber(v) )
73 | setInternal(null);
74 | else {
75 | v = def.fClamp(v);
76 | setInternal( V_Float(v) );
77 | }
78 |
79 | case F_String:
80 | raw = StringTools.trim(raw);
81 | if( raw.length==0 )
82 | setInternal(null);
83 | else
84 | setInternal(V_String(raw) );
85 |
86 | case F_Bool:
87 | raw = StringTools.trim(raw).toLowerCase();
88 | if( raw=="true" ) setInternal( V_Bool(true) );
89 | else if( raw=="false" ) setInternal( V_Bool(false) );
90 | else setInternal(null);
91 | }
92 | }
93 |
94 | public function valueIsNull() {
95 | var v : Dynamic = switch def.type {
96 | case F_Int: getInt();
97 | case F_Color: getColorAsInt();
98 | case F_Float: getFloat();
99 | case F_String: getString();
100 | case F_Bool: getBool();
101 | }
102 | return v == null;
103 | }
104 |
105 | public function getForDisplay() : String {
106 | var v : Dynamic = switch def.type {
107 | case F_Int: getInt();
108 | case F_Color: getColorAsHexStr();
109 | case F_Float: getFloat();
110 | case F_String: getString();
111 | case F_Bool: getBool();
112 | }
113 | if( v==null )
114 | return "null";
115 | else switch def.type {
116 | case F_Int, F_Float, F_Bool, F_Color: return Std.string(v);
117 | case F_String: return '"$v"';
118 | }
119 | }
120 |
121 | public function getInt() : Null {
122 | require(F_Int);
123 | return isUsingDefault() ? def.getIntDefault() : switch internalValue {
124 | case V_Int(v): def.iClamp(v);
125 | case _: throw "unexpected";
126 | }
127 | }
128 |
129 | public function getColorAsInt() : Null {
130 | require(F_Color);
131 | return isUsingDefault() ? def.getColorDefault() : switch internalValue {
132 | case V_Int(v): v;
133 | case _: throw "unexpected";
134 | }
135 | }
136 |
137 | public function getColorAsHexStr() : Null {
138 | require(F_Color);
139 | return isUsingDefault()
140 | ? def.getColorDefault()==null ? null : dn.Color.intToHex(def.getColorDefault())
141 | : switch internalValue {
142 | case V_Int(v): dn.Color.intToHex(v);
143 | case _: throw "unexpected";
144 | }
145 | }
146 |
147 | public function getFloat() : Null {
148 | require(F_Float);
149 | return isUsingDefault() ? def.getFloatDefault() : switch internalValue {
150 | case V_Float(v): def.fClamp(v);
151 | case _: throw "unexpected";
152 | }
153 | }
154 |
155 | public function getBool() : Bool {
156 | require(F_Bool);
157 | return isUsingDefault() ? def.getBoolDefault() : switch internalValue {
158 | case V_Bool(v): v;
159 | case _: throw "unexpected";
160 | }
161 | }
162 |
163 | public function getString() : String {
164 | require(F_String);
165 | return isUsingDefault() ? def.getStringDefault() : switch internalValue {
166 | case V_String(v): v;
167 | case _: throw "unexpected";
168 | }
169 | }
170 |
171 | public function tidy(p:Project) {
172 | _project = p;
173 | }
174 | }
175 |
--------------------------------------------------------------------------------
/led/src.api/led/inst/LayerInstance.hx:
--------------------------------------------------------------------------------
1 | package led.inst;
2 |
3 | import led.LedTypes;
4 |
5 | class LayerInstance {
6 | var _project : Project;
7 | public var def(get,never) : led.def.LayerDef; inline function get_def() return _project.defs.getLayerDef(layerDefId);
8 | public var level(get,never) : Level; function get_level() return _project.getLevel(levelId);
9 |
10 | public var levelId : Int;
11 | public var layerDefId : Int;
12 | public var pxOffsetX : Int = 0;
13 | public var pxOffsetY : Int = 0;
14 |
15 | // Layer content
16 | var intGrid : Map = new Map(); //
17 | public var entityInstances : Array = [];
18 | public var gridTiles : Map = []; //
19 |
20 | public var cWid(get,never) : Int; inline function get_cWid() return dn.M.ceil( level.pxWid / def.gridSize );
21 | public var cHei(get,never) : Int; inline function get_cHei() return dn.M.ceil( level.pxHei / def.gridSize );
22 |
23 |
24 | public function new(p:Project, levelId:Int, layerDefId:Int) {
25 | _project = p;
26 | this.levelId = levelId;
27 | this.layerDefId = layerDefId;
28 | }
29 |
30 |
31 | @:keep public function toString() {
32 | return 'LayerInstance#<${def.name}:${def.type}>';
33 | }
34 |
35 |
36 | public function toJson() {
37 | return {
38 | levelId: levelId,
39 | layerDefId: layerDefId,
40 | pxOffsetX: pxOffsetX,
41 | pxOffsetY: pxOffsetY,
42 | intGrid: {
43 | var arr = [];
44 | for(e in intGrid.keyValueIterator())
45 | arr.push({
46 | coordId: e.key,
47 | v: e.value,
48 | });
49 | arr;
50 | },
51 | gridTiles: {
52 | var arr = [];
53 | for(e in gridTiles.keyValueIterator())
54 | arr.push({
55 | coordId: e.key,
56 | v: e.value,
57 | });
58 | arr;
59 | },
60 | entityInstances: entityInstances.map( function(ei) return ei.toJson() ),
61 | }
62 | }
63 |
64 | public static function fromJson(p:Project, json:Dynamic) {
65 | var li = new led.inst.LayerInstance( p, JsonTools.readInt(json.levelId), JsonTools.readInt(json.layerDefId) );
66 |
67 | for( intGridJson in JsonTools.readArray(json.intGrid) )
68 | li.intGrid.set( intGridJson.coordId, intGridJson.v );
69 |
70 | for( gridTilesJson in JsonTools.readArray(json.gridTiles) )
71 | li.gridTiles.set( gridTilesJson.coordId, gridTilesJson.v );
72 |
73 | for( entityJson in JsonTools.readArray(json.entityInstances) )
74 | li.entityInstances.push( EntityInstance.fromJson(p, entityJson) );
75 |
76 | li.pxOffsetX = JsonTools.readInt(json.pxOffsetX, 0);
77 | li.pxOffsetY = JsonTools.readInt(json.pxOffsetY, 0);
78 |
79 | return li;
80 | }
81 |
82 | inline function requireType(t:LayerType) {
83 | if( def.type!=t )
84 | throw 'Only works on $t layer!';
85 | }
86 |
87 | public inline function isValid(cx:Int,cy:Int) {
88 | return cx>=0 && cx=0 && cy= def.countIntGridValues() )
112 | removeIntGrid(cx,cy);
113 | }
114 |
115 | case Entities:
116 | // Remove lost entities (def removed)
117 | var i = 0;
118 | while( i=0 && newCx=0 && newCy=0 && newCx=0 && newCy {
200 | var v = def.getIntGridValueDef( getIntGrid(cx,cy) );
201 | return v==null ? null : v.color;
202 | }
203 |
204 | public function setIntGrid(cx:Int, cy:Int, v:Int) {
205 | requireType(IntGrid);
206 | if( isValid(cx,cy) )
207 | intGrid.set( coordId(cx,cy), v );
208 | }
209 |
210 | public inline function hasIntGrid(cx:Int, cy:Int) {
211 | requireType(IntGrid);
212 | return getIntGrid(cx,cy)!=-1;
213 | }
214 |
215 | public function removeIntGrid(cx:Int, cy:Int) {
216 | requireType(IntGrid);
217 | if( isValid(cx,cy) )
218 | intGrid.remove( coordId(cx,cy) );
219 | }
220 |
221 |
222 | /** ENTITY INSTANCE *******************/
223 |
224 | public function createEntityInstance(ed:led.def.EntityDef) : Null {
225 | requireType(Entities);
226 | if( ed.maxPerLevel>0 ) {
227 | var all = entityInstances.filter( function(ei) return ei.defId==ed.uid );
228 | if( ed.discardExcess )
229 | while( all.length>=ed.maxPerLevel )
230 | removeEntityInstance( all.shift() );
231 | else if( all.length>=ed.maxPerLevel )
232 | return null;
233 | }
234 |
235 | var ei = new EntityInstance(_project, ed.uid);
236 | entityInstances.push(ei);
237 | return ei;
238 | }
239 |
240 | public function duplicateEntityInstance(ei:EntityInstance) : EntityInstance {
241 | var copy = EntityInstance.fromJson( _project, ei.toJson() );
242 | entityInstances.push(copy);
243 | return copy;
244 | }
245 |
246 | public function removeEntityInstance(e:EntityInstance) {
247 | requireType(Entities);
248 | if( !entityInstances.remove(e) )
249 | throw "Unknown instance "+e;
250 | }
251 |
252 |
253 |
254 | /** TILES *******************/
255 |
256 | public function setGridTile(cx:Int, cy:Int, tileId:Int) {
257 | if( isValid(cx,cy) )
258 | gridTiles.set( coordId(cx,cy), tileId );
259 | }
260 |
261 | public function removeGridTile(cx:Int, cy:Int) {
262 | if( isValid(cx,cy) )
263 | gridTiles.remove( coordId(cx,cy) );
264 | }
265 |
266 | public function getGridTile(cx:Int, cy:Int) : Null {
267 | return !isValid(cx,cy) || !gridTiles.exists( coordId(cx,cy) ) ? null : gridTiles.get( coordId(cx,cy) );
268 | }
269 |
270 | public inline function hasGridTile(cx:Int, cy:Int) : Bool {
271 | return getGridTile(cx,cy)!=null;
272 | }
273 |
274 |
275 |
276 |
277 | /** RENDERING *******************/
278 |
279 | #if heaps
280 |
281 | public function render(target:h2d.Object) {
282 | switch def.type {
283 | case IntGrid:
284 | var g = new h2d.Graphics(target);
285 | for(cy in 0...cHei)
286 | for(cx in 0...cWid) {
287 | var id = getIntGrid(cx,cy);
288 | if( id<0 )
289 | continue;
290 |
291 | g.beginFill( getIntGridColorAt(cx,cy) );
292 | g.drawRect(cx*def.gridSize, cy*def.gridSize, def.gridSize, def.gridSize);
293 | }
294 |
295 | case Entities:
296 | // not meant to be rendered
297 |
298 | case Tiles:
299 | for(cy in 0...cHei)
300 | for(cx in 0...cWid) {
301 | if( getGridTile(cx,cy)==null )
302 | continue;
303 |
304 | var td = _project.defs.getTilesetDef(def.tilesetDefId);
305 | var t = td.getTile( getGridTile(cx,cy) );
306 | t.setCenterRatio(def.tilePivotX, def.tilePivotY);
307 | var bmp = new h2d.Bitmap(t, target);
308 | bmp.x = (cx + def.tilePivotX) * def.gridSize;
309 | bmp.y = (cy + def.tilePivotY) * def.gridSize;
310 | }
311 |
312 | }
313 | }
314 |
315 | #else
316 |
317 | @:deprecated("Not implemented on this platform")
318 | public function render(target:Dynamic) {}
319 |
320 | #end
321 | }
--------------------------------------------------------------------------------
/redist/directx.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/directx.zip
--------------------------------------------------------------------------------
/redist/directx/DumberDwarves/DumberDwarves.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/directx/DumberDwarves/DumberDwarves.exe
--------------------------------------------------------------------------------
/redist/directx/DumberDwarves/OpenAL32.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/directx/DumberDwarves/OpenAL32.dll
--------------------------------------------------------------------------------
/redist/directx/DumberDwarves/d3dcompiler_47.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/directx/DumberDwarves/d3dcompiler_47.dll
--------------------------------------------------------------------------------
/redist/directx/DumberDwarves/directx.hdll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/directx/DumberDwarves/directx.hdll
--------------------------------------------------------------------------------
/redist/directx/DumberDwarves/fmt.hdll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/directx/DumberDwarves/fmt.hdll
--------------------------------------------------------------------------------
/redist/directx/DumberDwarves/hlboot.dat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/directx/DumberDwarves/hlboot.dat
--------------------------------------------------------------------------------
/redist/directx/DumberDwarves/libhl.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/directx/DumberDwarves/libhl.dll
--------------------------------------------------------------------------------
/redist/directx/DumberDwarves/msvcr120.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/directx/DumberDwarves/msvcr120.dll
--------------------------------------------------------------------------------
/redist/directx/DumberDwarves/openal.hdll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/directx/DumberDwarves/openal.hdll
--------------------------------------------------------------------------------
/redist/directx/DumberDwarves/ssl.hdll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/directx/DumberDwarves/ssl.hdll
--------------------------------------------------------------------------------
/redist/directx/DumberDwarves/ui.hdll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/directx/DumberDwarves/ui.hdll
--------------------------------------------------------------------------------
/redist/directx/DumberDwarves/uv.hdll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/directx/DumberDwarves/uv.hdll
--------------------------------------------------------------------------------
/redist/js.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/js.zip
--------------------------------------------------------------------------------
/redist/js/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | DumberDwarves
6 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/redist/sdl_mac.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/sdl_mac.zip
--------------------------------------------------------------------------------
/redist/sdl_mac/DumberDwarves/DumberDwarves:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/sdl_mac/DumberDwarves/DumberDwarves
--------------------------------------------------------------------------------
/redist/sdl_mac/DumberDwarves/hlboot.dat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/sdl_mac/DumberDwarves/hlboot.dat
--------------------------------------------------------------------------------
/redist/sdl_mac/DumberDwarves/libSDL2-2.0.0.dylib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/sdl_mac/DumberDwarves/libSDL2-2.0.0.dylib
--------------------------------------------------------------------------------
/redist/sdl_mac/DumberDwarves/libhl.dylib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/sdl_mac/DumberDwarves/libhl.dylib
--------------------------------------------------------------------------------
/redist/sdl_mac/DumberDwarves/libmbedtls.10.dylib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/sdl_mac/DumberDwarves/libmbedtls.10.dylib
--------------------------------------------------------------------------------
/redist/sdl_mac/DumberDwarves/libopenal.1.dylib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/sdl_mac/DumberDwarves/libopenal.1.dylib
--------------------------------------------------------------------------------
/redist/sdl_mac/DumberDwarves/libpng16.16.dylib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/sdl_mac/DumberDwarves/libpng16.16.dylib
--------------------------------------------------------------------------------
/redist/sdl_mac/DumberDwarves/libuv.1.dylib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/sdl_mac/DumberDwarves/libuv.1.dylib
--------------------------------------------------------------------------------
/redist/sdl_mac/DumberDwarves/libvorbis.0.dylib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/sdl_mac/DumberDwarves/libvorbis.0.dylib
--------------------------------------------------------------------------------
/redist/sdl_mac/DumberDwarves/libvorbisfile.3.dylib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/sdl_mac/DumberDwarves/libvorbisfile.3.dylib
--------------------------------------------------------------------------------
/redist/sdl_win.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/sdl_win.zip
--------------------------------------------------------------------------------
/redist/sdl_win/DumberDwarves/DumberDwarves.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/sdl_win/DumberDwarves/DumberDwarves.exe
--------------------------------------------------------------------------------
/redist/sdl_win/DumberDwarves/OpenAL32.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/sdl_win/DumberDwarves/OpenAL32.dll
--------------------------------------------------------------------------------
/redist/sdl_win/DumberDwarves/SDL2.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/sdl_win/DumberDwarves/SDL2.dll
--------------------------------------------------------------------------------
/redist/sdl_win/DumberDwarves/fmt.hdll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/sdl_win/DumberDwarves/fmt.hdll
--------------------------------------------------------------------------------
/redist/sdl_win/DumberDwarves/hlboot.dat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/sdl_win/DumberDwarves/hlboot.dat
--------------------------------------------------------------------------------
/redist/sdl_win/DumberDwarves/libhl.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/sdl_win/DumberDwarves/libhl.dll
--------------------------------------------------------------------------------
/redist/sdl_win/DumberDwarves/msvcr120.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/sdl_win/DumberDwarves/msvcr120.dll
--------------------------------------------------------------------------------
/redist/sdl_win/DumberDwarves/openal.hdll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/sdl_win/DumberDwarves/openal.hdll
--------------------------------------------------------------------------------
/redist/sdl_win/DumberDwarves/sdl.hdll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/sdl_win/DumberDwarves/sdl.hdll
--------------------------------------------------------------------------------
/redist/sdl_win/DumberDwarves/ssl.hdll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/sdl_win/DumberDwarves/ssl.hdll
--------------------------------------------------------------------------------
/redist/sdl_win/DumberDwarves/ui.hdll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/sdl_win/DumberDwarves/ui.hdll
--------------------------------------------------------------------------------
/redist/sdl_win/DumberDwarves/uv.hdll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/redist/sdl_win/DumberDwarves/uv.hdll
--------------------------------------------------------------------------------
/res/atlas/tiles.atlas:
--------------------------------------------------------------------------------
1 |
2 | tiles.png
3 | size: 256,256
4 | format: RGBA8888
5 | filter: Linear,Linear
6 | repeat: none
7 | a_atk0
8 | rotate: false
9 | xy: 35, 44
10 | size: 32, 16
11 | orig: 32, 16
12 | offset: 0, 0
13 | index: -1
14 | a_atk1
15 | rotate: false
16 | xy: 1, 46
17 | size: 32, 16
18 | orig: 32, 16
19 | offset: 0, 0
20 | index: -1
21 | a_atk2
22 | rotate: false
23 | xy: 68, 44
24 | size: 32, 16
25 | orig: 32, 16
26 | offset: 0, 0
27 | index: -1
28 | a_atk_charge0
29 | rotate: false
30 | xy: 77, 105
31 | size: 16, 16
32 | orig: 16, 16
33 | offset: 0, 0
34 | index: -1
35 | a_idle0
36 | rotate: false
37 | xy: 76, 122
38 | size: 16, 16
39 | orig: 16, 16
40 | offset: 0, 0
41 | index: -1
42 | a_idle1
43 | rotate: false
44 | xy: 173, 87
45 | size: 16, 16
46 | orig: 16, 16
47 | offset: 0, 0
48 | index: -1
49 | a_walk0
50 | rotate: false
51 | xy: 146, 93
52 | size: 16, 16
53 | orig: 16, 16
54 | offset: 0, 0
55 | index: -1
56 | a_walk1
57 | rotate: false
58 | xy: 120, 105
59 | size: 16, 16
60 | orig: 16, 16
61 | offset: 0, 0
62 | index: -1
63 | a_walk2
64 | rotate: false
65 | xy: 190, 87
66 | size: 16, 16
67 | orig: 16, 16
68 | offset: 0, 0
69 | index: -1
70 | bossDoor
71 | rotate: false
72 | xy: 101, 44
73 | size: 26, 33
74 | orig: 26, 33
75 | offset: 0, 0
76 | index: -1
77 | bubble
78 | rotate: false
79 | xy: 77, 87
80 | size: 17, 17
81 | orig: 17, 17
82 | offset: 0, 0
83 | index: -1
84 | cart
85 | rotate: false
86 | xy: 173, 67
87 | size: 21, 19
88 | orig: 21, 19
89 | offset: 0, 0
90 | index: -1
91 | crate0-60
92 | rotate: false
93 | xy: 207, 87
94 | size: 16, 16
95 | orig: 16, 16
96 | offset: 0, 0
97 | index: -1
98 | crate0-61
99 | rotate: false
100 | xy: 207, 87
101 | size: 16, 16
102 | orig: 16, 16
103 | offset: 0, 0
104 | index: -1
105 | crate0-63
106 | rotate: false
107 | xy: 207, 87
108 | size: 16, 16
109 | orig: 16, 16
110 | offset: 0, 0
111 | index: -1
112 | crate0-65
113 | rotate: false
114 | xy: 207, 87
115 | size: 16, 16
116 | orig: 16, 16
117 | offset: 0, 0
118 | index: -1
119 | crate0-66
120 | rotate: false
121 | xy: 207, 87
122 | size: 16, 16
123 | orig: 16, 16
124 | offset: 0, 0
125 | index: -1
126 | crate0-69
127 | rotate: false
128 | xy: 207, 87
129 | size: 16, 16
130 | orig: 16, 16
131 | offset: 0, 0
132 | index: -1
133 | crate0
134 | rotate: false
135 | xy: 224, 87
136 | size: 16, 16
137 | orig: 16, 16
138 | offset: 0, 0
139 | index: -1
140 | d_act0
141 | rotate: false
142 | xy: 121, 80
143 | size: 24, 24
144 | orig: 24, 24
145 | offset: 0, 0
146 | index: -1
147 | d_act1
148 | rotate: false
149 | xy: 27, 87
150 | size: 24, 24
151 | orig: 24, 24
152 | offset: 0, 0
153 | index: -1
154 | d_atk_charge0
155 | rotate: false
156 | xy: 1, 89
157 | size: 24, 24
158 | orig: 24, 24
159 | offset: 0, 0
160 | index: -1
161 | d_atkA0
162 | rotate: false
163 | xy: 150, 17
164 | size: 48, 24
165 | orig: 48, 24
166 | offset: 0, 0
167 | index: -1
168 | d_atkA1
169 | rotate: false
170 | xy: 199, 17
171 | size: 48, 24
172 | orig: 48, 24
173 | offset: 0, 0
174 | index: -1
175 | d_atkA2
176 | rotate: false
177 | xy: 1, 19
178 | size: 48, 24
179 | orig: 48, 24
180 | offset: 0, 0
181 | index: -1
182 | d_atkA3
183 | rotate: false
184 | xy: 1, 89
185 | size: 24, 24
186 | orig: 24, 24
187 | offset: 0, 0
188 | index: -1
189 | d_atkB0
190 | rotate: false
191 | xy: 50, 19
192 | size: 48, 24
193 | orig: 48, 24
194 | offset: 0, 0
195 | index: -1
196 | d_atkB1
197 | rotate: false
198 | xy: 99, 19
199 | size: 48, 24
200 | orig: 48, 24
201 | offset: 0, 0
202 | index: -1
203 | d_atkB2
204 | rotate: false
205 | xy: 148, 42
206 | size: 48, 24
207 | orig: 48, 24
208 | offset: 0, 0
209 | index: -1
210 | d_hit0
211 | rotate: false
212 | xy: 52, 87
213 | size: 24, 24
214 | orig: 24, 24
215 | offset: 0, 0
216 | index: -1
217 | d_idle0
218 | rotate: false
219 | xy: 95, 104
220 | size: 24, 24
221 | orig: 24, 24
222 | offset: 0, 0
223 | index: -1
224 | d_walk0
225 | rotate: false
226 | xy: 26, 112
227 | size: 24, 24
228 | orig: 24, 24
229 | offset: 0, 0
230 | index: -1
231 | d_walk1
232 | rotate: false
233 | xy: 1, 114
234 | size: 24, 24
235 | orig: 24, 24
236 | offset: 0, 0
237 | index: -1
238 | d_walk2
239 | rotate: false
240 | xy: 51, 112
241 | size: 24, 24
242 | orig: 24, 24
243 | offset: 0, 0
244 | index: -1
245 | danger
246 | rotate: false
247 | xy: 242, 45
248 | size: 13, 14
249 | orig: 13, 14
250 | offset: 0, 0
251 | index: -1
252 | empty
253 | rotate: false
254 | xy: 148, 19
255 | size: 1, 1
256 | orig: 1, 1
257 | offset: 0, 0
258 | index: -1
259 | emptyBone
260 | rotate: false
261 | xy: 180, 104
262 | size: 15, 8
263 | orig: 15, 8
264 | offset: 0, 0
265 | index: -1
266 | fxCircle0
267 | rotate: false
268 | xy: 1, 164
269 | size: 16, 16
270 | orig: 16, 16
271 | offset: 0, 0
272 | index: -1
273 | fxDot0
274 | rotate: false
275 | xy: 27, 79
276 | size: 3, 3
277 | orig: 3, 3
278 | offset: 0, 0
279 | index: -1
280 | fxExplosion0
281 | rotate: false
282 | xy: 147, 67
283 | size: 25, 25
284 | orig: 25, 25
285 | offset: 0, 0
286 | index: -1
287 | fxExplosion1
288 | rotate: false
289 | xy: 34, 61
290 | size: 25, 25
291 | orig: 25, 25
292 | offset: 0, 0
293 | index: -1
294 | fxExplosion2
295 | rotate: false
296 | xy: 1, 63
297 | size: 25, 25
298 | orig: 25, 25
299 | offset: 0, 0
300 | index: -1
301 | fxExplosion3
302 | rotate: false
303 | xy: 60, 61
304 | size: 25, 25
305 | orig: 25, 25
306 | offset: 0, 0
307 | index: -1
308 | fxExplosion4
309 | rotate: false
310 | xy: 95, 78
311 | size: 25, 25
312 | orig: 25, 25
313 | offset: 0, 0
314 | index: -1
315 | fxGib0
316 | rotate: false
317 | xy: 248, 39
318 | size: 6, 5
319 | orig: 6, 5
320 | offset: 0, 0
321 | index: -1
322 | fxGib1
323 | rotate: false
324 | xy: 248, 25
325 | size: 7, 6
326 | orig: 7, 6
327 | offset: 0, 0
328 | index: -1
329 | fxGib2
330 | rotate: false
331 | xy: 27, 63
332 | size: 6, 5
333 | orig: 6, 5
334 | offset: 0, 0
335 | index: -1
336 | fxImpact0
337 | rotate: false
338 | xy: 76, 139
339 | size: 15, 9
340 | orig: 15, 9
341 | offset: 0, 0
342 | index: -1
343 | fxLine0
344 | rotate: false
345 | xy: 221, 13
346 | size: 33, 3
347 | orig: 33, 3
348 | offset: 0, 0
349 | index: -1
350 | fxLineDir0
351 | rotate: false
352 | xy: 1, 44
353 | size: 33, 1
354 | orig: 33, 1
355 | offset: 0, 0
356 | index: -1
357 | fxProhib
358 | rotate: false
359 | xy: 248, 17
360 | size: 7, 7
361 | orig: 7, 7
362 | offset: 0, 0
363 | index: -1
364 | fxSmallCircle0
365 | rotate: false
366 | xy: 248, 32
367 | size: 6, 6
368 | orig: 6, 6
369 | offset: 0, 0
370 | index: -1
371 | fxSmoke0
372 | rotate: false
373 | xy: 197, 42
374 | size: 44, 44
375 | orig: 44, 44
376 | offset: 0, 0
377 | index: -1
378 | fxSplatter0
379 | rotate: false
380 | xy: 150, 1
381 | size: 70, 15
382 | orig: 70, 15
383 | offset: 0, 0
384 | index: -1
385 | fxSplatter1
386 | rotate: false
387 | xy: 79, 1
388 | size: 70, 17
389 | orig: 70, 17
390 | offset: 0, 0
391 | index: -1
392 | fxSplatter2
393 | rotate: false
394 | xy: 1, 1
395 | size: 77, 17
396 | orig: 77, 17
397 | offset: 0, 0
398 | index: -1
399 | fxStar0
400 | rotate: false
401 | xy: 27, 73
402 | size: 3, 5
403 | orig: 3, 5
404 | offset: 0, 0
405 | index: -1
406 | fxTail0
407 | rotate: false
408 | xy: 221, 1
409 | size: 33, 11
410 | orig: 33, 11
411 | offset: 0, 0
412 | index: -1
413 | gen
414 | rotate: false
415 | xy: 128, 44
416 | size: 18, 18
417 | orig: 18, 18
418 | offset: 0, 0
419 | index: -1
420 | gStone0
421 | rotate: false
422 | xy: 1, 181
423 | size: 16, 16
424 | orig: 16, 16
425 | offset: 0, 0
426 | index: -1
427 | gStone1
428 | rotate: false
429 | xy: 1, 198
430 | size: 16, 16
431 | orig: 16, 16
432 | offset: 0, 0
433 | index: -1
434 | gStone2
435 | rotate: false
436 | xy: 1, 215
437 | size: 16, 16
438 | orig: 16, 16
439 | offset: 0, 0
440 | index: -1
441 | i_Bait
442 | rotate: false
443 | xy: 1, 232
444 | size: 16, 16
445 | orig: 16, 16
446 | offset: 0, 0
447 | index: -1
448 | i_BaitFull
449 | rotate: false
450 | xy: 18, 164
451 | size: 16, 16
452 | orig: 16, 16
453 | offset: 0, 0
454 | index: -1
455 | i_BaitPart
456 | rotate: false
457 | xy: 18, 181
458 | size: 16, 16
459 | orig: 16, 16
460 | offset: 0, 0
461 | index: -1
462 | i_Bomb
463 | rotate: false
464 | xy: 18, 198
465 | size: 16, 16
466 | orig: 16, 16
467 | offset: 0, 0
468 | index: -1
469 | i_Cart
470 | rotate: false
471 | xy: 128, 63
472 | size: 18, 16
473 | orig: 18, 16
474 | offset: 0, 0
475 | index: -1
476 | i_Gem
477 | rotate: false
478 | xy: 26, 137
479 | size: 24, 24
480 | orig: 24, 24
481 | offset: 0, 0
482 | index: -1
483 | i_HeartFull
484 | rotate: false
485 | xy: 242, 60
486 | size: 13, 13
487 | orig: 13, 13
488 | offset: 0, 0
489 | index: -1
490 | i_HeartHollow
491 | rotate: false
492 | xy: 242, 74
493 | size: 13, 13
494 | orig: 13, 13
495 | offset: 0, 0
496 | index: -1
497 | i_HeartPart
498 | rotate: false
499 | xy: 86, 61
500 | size: 13, 13
501 | orig: 13, 13
502 | offset: 0, 0
503 | index: -1
504 | pixel
505 | rotate: false
506 | xy: 148, 21
507 | size: 1, 1
508 | orig: 1, 1
509 | offset: 0, 0
510 | index: -1
511 | pointer
512 | rotate: false
513 | xy: 93, 129
514 | size: 15, 12
515 | orig: 15, 12
516 | offset: 0, 0
517 | index: -1
518 | uiBaitOff
519 | rotate: false
520 | xy: 137, 110
521 | size: 16, 12
522 | orig: 16, 12
523 | offset: 0, 0
524 | index: -1
525 | uiBaitOn
526 | rotate: false
527 | xy: 120, 122
528 | size: 16, 12
529 | orig: 16, 12
530 | offset: 0, 0
531 | index: -1
532 | uiBar
533 | rotate: false
534 | xy: 27, 69
535 | size: 6, 3
536 | orig: 6, 3
537 | offset: 0, 0
538 | index: -1
539 | uiBarBg
540 | rotate: false
541 | xy: 86, 75
542 | size: 8, 5
543 | orig: 8, 5
544 | offset: 0, 0
545 | index: -1
546 | wall0
547 | rotate: false
548 | xy: 1, 139
549 | size: 24, 24
550 | orig: 24, 24
551 | offset: 0, 0
552 | index: -1
553 | wall1
554 | rotate: false
555 | xy: 51, 137
556 | size: 24, 24
557 | orig: 24, 24
558 | offset: 0, 0
559 | index: -1
560 | wallDetail0
561 | rotate: false
562 | xy: 18, 215
563 | size: 16, 16
564 | orig: 16, 16
565 | offset: 0, 0
566 | index: -1
567 | wallDetail1
568 | rotate: false
569 | xy: 18, 232
570 | size: 16, 16
571 | orig: 16, 16
572 | offset: 0, 0
573 | index: -1
574 | wallDetail2
575 | rotate: false
576 | xy: 163, 104
577 | size: 16, 16
578 | orig: 16, 16
579 | offset: 0, 0
580 | index: -1
581 |
--------------------------------------------------------------------------------
/res/atlas/tiles.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/res/atlas/tiles.png
--------------------------------------------------------------------------------
/res/data.cdb:
--------------------------------------------------------------------------------
1 | {
2 | "sheets": [],
3 | "customTypes": [],
4 | "compress": false
5 | }
--------------------------------------------------------------------------------
/res/fonts/barlow_condensed_medium_regular_11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/res/fonts/barlow_condensed_medium_regular_11.png
--------------------------------------------------------------------------------
/res/fonts/barlow_condensed_medium_regular_17.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/res/fonts/barlow_condensed_medium_regular_17.png
--------------------------------------------------------------------------------
/res/fonts/barlow_condensed_medium_regular_32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/res/fonts/barlow_condensed_medium_regular_32.png
--------------------------------------------------------------------------------
/res/fonts/barlow_condensed_medium_regular_9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/res/fonts/barlow_condensed_medium_regular_9.png
--------------------------------------------------------------------------------
/res/fonts/minecraftiaOutline.fnt:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
--------------------------------------------------------------------------------
/res/fonts/minecraftiaOutline.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/res/fonts/minecraftiaOutline.png
--------------------------------------------------------------------------------
/res/lang/en.mo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/res/lang/en.mo
--------------------------------------------------------------------------------
/res/lang/en.po:
--------------------------------------------------------------------------------
1 | msgid ""
2 | msgstr ""
3 | "Project-Id-Version: \n"
4 | "POT-Creation-Date: \n"
5 | "PO-Revision-Date: 2019-10-29 15:17+0100\n"
6 | "Last-Translator: \n"
7 | "Language-Team: \n"
8 | "Language: en\n"
9 | "MIME-Version: 1.0\n"
10 | "Content-Type: text/plain; charset=UTF-8\n"
11 | "Content-Transfer-Encoding: 8bit\n"
12 | "X-Generator: Poedit 2.2.4\n"
13 | "X-Poedit-Basepath: .\n"
14 | "Plural-Forms: nplurals=2; plural=(n != 1);\n"
15 |
16 | #: src/Game.hx:19
17 | msgid "Game is ready."
18 | msgstr ""
19 |
20 | #: src/Game.hx:57
21 | msgid "Press ESCAPE again to exit."
22 | msgstr ""
23 |
--------------------------------------------------------------------------------
/res/lang/sourceTexts.pot:
--------------------------------------------------------------------------------
1 | msgid ""
2 | msgstr ""
3 | "Content-Type: text/plain; charset=UTF-8\n"
4 | "Content-Transfer-Encoding: 8bit\n"
5 | "MIME-Version: 1.0\n"
6 |
7 | #: src/Game.hx:30
8 | msgid "Game is ready."
9 | msgstr ""
10 |
11 | #: src/Game.hx:69
12 | msgid "Press ESCAPE again to exit."
13 | msgstr ""
14 |
15 |
16 |
--------------------------------------------------------------------------------
/res/ld/tileset.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/res/ld/tileset.png
--------------------------------------------------------------------------------
/res/props.json:
--------------------------------------------------------------------------------
1 | {
2 | "fs.convert" : {
3 | "wav" : "mp3"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/screenshots/dumberDwarves-cover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/screenshots/dumberDwarves-cover.png
--------------------------------------------------------------------------------
/screenshots/god0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/screenshots/god0.png
--------------------------------------------------------------------------------
/screenshots/s0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/screenshots/s0.png
--------------------------------------------------------------------------------
/screenshots/s1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/screenshots/s1.png
--------------------------------------------------------------------------------
/screenshots/s2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/screenshots/s2.png
--------------------------------------------------------------------------------
/screenshots/s3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/screenshots/s3.png
--------------------------------------------------------------------------------
/screenshots/s4.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/screenshots/s4.gif
--------------------------------------------------------------------------------
/screenshots/s5.avi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/screenshots/s5.avi
--------------------------------------------------------------------------------
/screenshots/s6.avi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/screenshots/s6.avi
--------------------------------------------------------------------------------
/screenshots/s7.avi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/screenshots/s7.avi
--------------------------------------------------------------------------------
/screenshots/s8.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/screenshots/s8.mp4
--------------------------------------------------------------------------------
/screenshots/s9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepnight/gmtk20-dumberDwarves/dfcd5191facf168a3548f9166dc72a0d5dcdc24f/screenshots/s9.png
--------------------------------------------------------------------------------
/src.langParser/LangParser.hx:
--------------------------------------------------------------------------------
1 | import dn.data.GetText;
2 |
3 | class LangParser {
4 | public static function main() {
5 | var name = "sourceTexts";
6 | Sys.println("Building "+name+" file...");
7 | var cdbs = findAll("res", "cdb");
8 | try {
9 | var data = GetText.doParseGlobal({
10 | codePath: "src",
11 | codeIgnore: null,
12 | cdbFiles: cdbs,
13 | cdbSpecialId: [],
14 | potFile: "res/lang/"+name+".pot",
15 | });
16 | }
17 | catch(e:String) {
18 | Sys.println("");
19 | Sys.println(e);
20 | Sys.println("Extraction failed: fatal error!");
21 | Sys.println("");
22 | Sys.exit(1);
23 | }
24 | Sys.println("Done.");
25 | }
26 |
27 | static function findAll(path:String, ext:String, ?cur:Array) {
28 | var ext = "."+ext;
29 | var all = cur==null ? [] : cur;
30 | for(e in sys.FileSystem.readDirectory(path)) {
31 | e = path+"/"+e;
32 | if( e.indexOf(ext)>=0 && e.lastIndexOf(ext)==e.length-ext.length )
33 | all.push(e);
34 | if( sys.FileSystem.isDirectory(e) && e.indexOf(".tmp")<0 )
35 | findAll(e, ext, all);
36 | }
37 | return all;
38 | }
39 | }
--------------------------------------------------------------------------------
/src/Assets.hx:
--------------------------------------------------------------------------------
1 | import dn.heaps.slib.*;
2 |
3 | class Assets {
4 | public static var fontPixel : h2d.Font;
5 | public static var fontTiny : h2d.Font;
6 | public static var fontSmall : h2d.Font;
7 | public static var fontMedium : h2d.Font;
8 | public static var fontLarge : h2d.Font;
9 | public static var tiles : SpriteLib;
10 |
11 | static var initDone = false;
12 | public static function init() {
13 | if( initDone )
14 | return;
15 | initDone = true;
16 |
17 | fontPixel = hxd.Res.fonts.minecraftiaOutline.toFont();
18 | fontTiny = hxd.Res.fonts.barlow_condensed_medium_regular_9.toFont();
19 | fontSmall = hxd.Res.fonts.barlow_condensed_medium_regular_11.toFont();
20 | fontMedium = hxd.Res.fonts.barlow_condensed_medium_regular_17.toFont();
21 | fontLarge = hxd.Res.fonts.barlow_condensed_medium_regular_32.toFont();
22 | tiles = dn.heaps.assets.Atlas.load("atlas/tiles.atlas");
23 |
24 | tiles.defineAnim("a_walk", "0(2), 1, 2(2), 1");
25 | tiles.defineAnim("a_atk", "0, 1(1), 2(2)");
26 |
27 | tiles.defineAnim("d_walk", "0(2), 1, 2(2), 1");
28 | tiles.defineAnim("d_atkA", "0, 1(2), 2(2), 3(3)");
29 | tiles.defineAnim("d_atkB", "0, 1(2), 2(2)");
30 | }
31 | }
--------------------------------------------------------------------------------
/src/Boot.hx:
--------------------------------------------------------------------------------
1 | class Boot extends hxd.App {
2 | public static var ME : Boot;
3 |
4 | // Boot
5 | static function main() {
6 | new Boot();
7 | }
8 |
9 | // Engine ready
10 | override function init() {
11 | ME = this;
12 | new Main(s2d);
13 | onResize();
14 | }
15 |
16 | override function onResize() {
17 | super.onResize();
18 | dn.Process.resizeAll();
19 | }
20 |
21 | var speed = 1.0;
22 | override function update(deltaTime:Float) {
23 | super.update(deltaTime);
24 |
25 | // Bullet time
26 | #if debug
27 | if( hxd.Key.isPressed(hxd.Key.BACKSPACE) || Main.ME.ca.dpadDownPressed() )
28 | speed = speed>=1 ? 0.2 : 1;
29 | #end
30 |
31 | var tmod = hxd.Timer.tmod * speed;
32 | #if debug
33 | tmod *= hxd.Key.isDown(hxd.Key.CTRL) ? 0.2 : hxd.Key.isDown(hxd.Key.SPACE) || Main.ME!=null && Main.ME.ca.ltDown() ? 5 : 1;
34 | #end
35 | dn.heaps.Controller.beforeUpdate();
36 | dn.Process.updateAll(tmod);
37 | }
38 | }
39 |
40 |
--------------------------------------------------------------------------------
/src/Camera.hx:
--------------------------------------------------------------------------------
1 | class Camera extends dn.Process {
2 | public var target : Null;
3 | public var x : Float;
4 | public var y : Float;
5 | public var dx : Float;
6 | public var dy : Float;
7 | public var wid(get,never) : Int;
8 | public var hei(get,never) : Int;
9 | var bumpOffX = 0.;
10 | var bumpOffY = 0.;
11 |
12 | public function new() {
13 | super(Game.ME);
14 | x = y = 0;
15 | dx = dy = 0;
16 | }
17 |
18 | function get_wid() {
19 | return M.ceil( Game.ME.w() / Const.SCALE );
20 | }
21 |
22 | function get_hei() {
23 | return M.ceil( Game.ME.h() / Const.SCALE );
24 | }
25 |
26 | public function trackTarget(e:Entity, immediate:Bool) {
27 | target = e;
28 | if( immediate )
29 | recenter();
30 | }
31 |
32 | public inline function stopTracking() {
33 | target = null;
34 | }
35 |
36 | public function recenter() {
37 | if( target!=null ) {
38 | x = target.centerX;
39 | y = target.centerY;
40 | }
41 | }
42 |
43 | public inline function scrollerToGlobalX(v:Float) return v*Const.SCALE + Game.ME.scroller.x;
44 | public inline function scrollerToGlobalY(v:Float) return v*Const.SCALE + Game.ME.scroller.y;
45 |
46 | var shakePower = 1.0;
47 | public function shakeS(t:Float, ?pow=1.0) {
48 | cd.setS("shaking", t, false);
49 | shakePower = pow;
50 | }
51 |
52 | override function update() {
53 | super.update();
54 |
55 | // Follow target entity
56 | if( target!=null ) {
57 | var s = 0.006;
58 | var deadZone = 5;
59 | var tx = target.footX;
60 | var ty = target.footY;
61 |
62 | var d = M.dist(x,y, tx, ty);
63 | if( d>=deadZone ) {
64 | var a = Math.atan2( ty-y, tx-x );
65 | dx += Math.cos(a) * (d-deadZone) * s * tmod;
66 | dy += Math.sin(a) * (d-deadZone) * s * tmod;
67 | }
68 | }
69 |
70 | // Follow all dwarves
71 | if( en.ai.Dwarf.ALL.length>0 ) {
72 | var s = 0.006;
73 | var deadZone = 5;
74 | var tx = 0.;
75 | var ty = 0.;
76 | for(e in en.ai.Dwarf.ALL) {
77 | tx+=e.footX;
78 | ty+=e.footY;
79 | }
80 | tx/=en.ai.Dwarf.ALL.length;
81 | ty/=en.ai.Dwarf.ALL.length;
82 |
83 | var d = M.dist(x,y, tx, ty);
84 | if( d>=deadZone ) {
85 | var a = Math.atan2( ty-y, tx-x );
86 | dx += Math.cos(a) * (d-deadZone) * s * tmod;
87 | dy += Math.sin(a) * (d-deadZone) * s * tmod;
88 | }
89 | }
90 |
91 |
92 | var frict = 0.89;
93 | x += dx*tmod;
94 | dx *= Math.pow(frict,tmod);
95 |
96 | y += dy*tmod;
97 | dy *= Math.pow(frict,tmod);
98 | }
99 |
100 | public inline function bumpAng(a, dist) {
101 | bumpOffX+=Math.cos(a)*dist;
102 | bumpOffY+=Math.sin(a)*dist;
103 | }
104 |
105 | public inline function bump(x,y) {
106 | bumpOffX+=x;
107 | bumpOffY+=y;
108 | }
109 |
110 |
111 | override function postUpdate() {
112 | super.postUpdate();
113 |
114 | if( !ui.Console.ME.hasFlag("scroll") ) {
115 | var level = Game.ME.level;
116 | var scroller = Game.ME.scroller;
117 |
118 | // Update scroller
119 | if( wid > = new Map();
23 | var invalidated = true;
24 | public var levelId : Int;
25 | public var data : led.Level;
26 |
27 | var fastCollGrid: Map;
28 | public var pf : dn.pathfinder.AStar;
29 |
30 | public function new(idx:Int, data:led.Level) {
31 | super(Game.ME);
32 | levelId = idx;
33 | this.data = data;
34 | wid = Std.int(data.pxWid/Const.GRID);
35 | hei= Std.int(data.pxHei/Const.GRID);
36 | createRootInLayers(Game.ME.scroller, Const.DP_BG);
37 |
38 | initCollisions();
39 | pf = new dn.pathfinder.AStar( function(x,y) return new CPoint(x,y,0.5,0.5) );
40 | pf.init(wid, hei, hasCollision);
41 | }
42 |
43 | public function initCollisions() {
44 | fastCollGrid = new Map();
45 |
46 | var li = data.getLayerInstance("Collisions");
47 | for(cy in 0...hei)
48 | for(cx in 0...wid)
49 | fastCollGrid.set( coordId(cx,cy), li.getIntGrid(cx,cy) );
50 | }
51 |
52 | public inline function isValid(cx,cy) return cx>=0 && cx=0 && cy0 )
65 | Const.SCALE = M.ceil( w()/Const.AUTO_SCALE_TARGET_WID );
66 | else if( Const.AUTO_SCALE_TARGET_HEI>0 )
67 | Const.SCALE = M.ceil( h()/Const.AUTO_SCALE_TARGET_HEI );
68 |
69 | Const.UI_SCALE = Const.SCALE;
70 | }
71 |
72 | override function update() {
73 | Assets.tiles.tmod = tmod;
74 | super.update();
75 | }
76 | }
--------------------------------------------------------------------------------
/src/Types.hx:
--------------------------------------------------------------------------------
1 | enum Affect {
2 | Stun;
3 | }
4 |
5 | enum LevelMark {
6 | }
7 |
8 | enum ItemType {
9 | Gem;
10 | BaitFull;
11 | BaitPart;
12 | Bomb;
13 | }
14 |
15 | enum Task {
16 | Wait(untilFrame:Float);
17 | Idle;
18 | Grab(e:en.Item);
19 | Break(e:en.Breakable);
20 | BringToCart;
21 | AttackDwarf(e:en.ai.Dwarf);
22 | WaitWithItem(e:en.Item);
23 | ExitLevel;
24 | FleeBoss(e:en.ai.mob.Boss);
25 | }
26 |
--------------------------------------------------------------------------------
/src/en/Ai.hx:
--------------------------------------------------------------------------------
1 | package en;
2 |
3 | class Ai extends Entity {
4 | public static var ALL : Array = [];
5 |
6 | var task : Task;
7 | var detectRadius = 5;
8 | var path : Array = [];
9 | var origin : CPoint;
10 | var atkRange = 1.0; // case
11 | var bubble : Null;
12 | var prohibiteds : Array<{ e:Entity, sec:Float }> = [];
13 | var baseSpeed = rnd(0.005,0.007);
14 |
15 | private function new(x,y) {
16 | super(x,y);
17 |
18 | origin = this.makePoint();
19 | spr.filter = new dn.heaps.filter.PixelOutline();
20 |
21 | ALL.push(this);
22 | task = Idle;
23 | enableShadow();
24 |
25 | doTask(Idle);
26 | }
27 |
28 | public function prohibit(e:Entity) {
29 | if( !e.isAlive() )
30 | return;
31 |
32 | for(p in prohibiteds)
33 | if( p.e==e )
34 | return;
35 |
36 | var t = 20;
37 | if( e.is(Item) )
38 | t = switch e.as(Item).type {
39 | case Gem: 8;
40 | case BaitFull, BaitPart: t;
41 | case Bomb: t;
42 | }
43 |
44 | prohibiteds.push({
45 | e: e,
46 | sec: t,
47 | });
48 | }
49 |
50 | override function chargeAction(id:String, sec:Float, cb:() -> Void) {
51 | super.chargeAction(id, sec, cb);
52 | dx*=0.2;
53 | dy*=0.2;
54 | bdx*=0.2;
55 | bdy*=0.2;
56 | }
57 |
58 | public function isProhibited(e:Entity) {
59 | for(p in prohibiteds)
60 | if( p.e==e )
61 | return true;
62 | return false;
63 | }
64 |
65 | public function isItemProhibited(it:ItemType) {
66 | for(p in prohibiteds)
67 | if( p.e.is(Item) && p.e.as(Item).type==it )
68 | return true;
69 | return false;
70 | }
71 |
72 | public function isWalking() {
73 | return canAct() && ( M.fabs(dx)>=0.004 || M.fabs(dy)>=0.004 );
74 | }
75 |
76 | public function canDetect(e:Entity) {
77 | return isAlive() && e.isAlive() && distCase(e)<=detectRadius && sightCheckEnt(e);
78 | }
79 |
80 | override function dispose() {
81 | super.dispose();
82 | ALL.remove(this);
83 | origin = null;
84 | path = null;
85 | prohibiteds = null;
86 |
87 |
88 | if( bubble!=null ) {
89 | bubble.remove();
90 | bubble = null;
91 | }
92 | }
93 |
94 | function setBubble(iconId:String, resize=true) {
95 | clearBubble();
96 | bubble = new h2d.Object();
97 | game.scroller.add(bubble, Const.DP_UI);
98 |
99 | var bg = Assets.tiles.getBitmap("bubble",0, 0.5,1, bubble);
100 |
101 | var icon = Assets.tiles.getBitmap(iconId,0, 0.5, 0.5, bubble);
102 | icon.x = 1;
103 | icon.y = Std.int( -bg.tile.height*0.5 - 3 );
104 | if( resize )
105 | icon.setScale(0.66);
106 | icon.alpha = 0.7;
107 | icon.smooth = true;
108 | }
109 |
110 | function clearBubble() {
111 | if( bubble!=null ) {
112 | bubble.remove();
113 | bubble = null;
114 | }
115 | }
116 |
117 | function cancelPath() {
118 | path = [];
119 | }
120 |
121 | public function doTask(t:Task) {
122 | cancelPath();
123 | task = t;
124 | clearBubble();
125 | }
126 |
127 | override function slap(x:Int,y:Int) {
128 | super.slap(x,y);
129 |
130 | switch task {
131 | case Idle:
132 | popText("??");
133 |
134 | case Wait(_):
135 |
136 | case ExitLevel:
137 | popText("I need to go!");
138 |
139 | case Grab(i):
140 | prohibit(i);
141 | releaseCarriedEnt(true);
142 |
143 | case Break(e):
144 | prohibit(e);
145 |
146 | case WaitWithItem(e):
147 | prohibit(e);
148 | releaseCarriedEnt(true);
149 |
150 | case BringToCart:
151 | if( isCarrying(Item) )
152 | prohibit( carriedEnt );
153 | releaseCarriedEnt(true);
154 |
155 | case AttackDwarf(e):
156 |
157 | case FleeBoss(e):
158 | popText("??");
159 | }
160 |
161 | doTask( Idle );
162 | }
163 |
164 |
165 | function showTaskFocus(e:Entity) {}
166 |
167 |
168 | public function goto(tcx:Int, tcy:Int) {
169 | path = game.level.pf.getPath(cx,cy, tcx,tcy);
170 |
171 | }
172 |
173 | function updateAi() {
174 | // Run task
175 | switch task {
176 |
177 | case Idle:
178 |
179 | case Wait(until):
180 | if( ftime>=until ) {
181 | doTask(Idle);
182 | return;
183 | }
184 |
185 | if( !cd.hasSetS("jumpWait",0.3) )
186 | dz = -0.11;
187 |
188 | case WaitWithItem(e):
189 | if( carriedEnt==null )
190 | doTask(Idle);
191 |
192 | case Grab(i):
193 | if( !i.isAlive() || i.isCarried && i.getCarrier()!=this ) {
194 | // Lost target
195 | doTask(Idle);
196 | return;
197 | }
198 |
199 | // Seek target
200 | releaseCarriedEnt();
201 | goto(i.cx,i.cy);
202 | showTaskFocus(i);
203 | setBubble(i.spr.groupName, i.type!=Bomb);
204 | // setBubble("i_"+Std.string(i.type), i.type!=Bomb);
205 | if( distCase(i)<=0.8 ) {
206 | var t = switch i.type {
207 | case BaitFull, BaitPart: 0.3;
208 | case Gem: 0.6;
209 | case _: 1;
210 | }
211 | chargeAction("pick", t, function() {
212 | if( i.isCarried || !i.isAlive() ) {
213 | popText("?");
214 | return;
215 | }
216 | switch i.type {
217 | case Gem:
218 | carry(i);
219 | doTask(BringToCart);
220 |
221 | case BaitFull, BaitPart:
222 | i.consume(this);
223 | doTask(Idle);
224 |
225 | case Bomb:
226 | carry(i);
227 | doTask(WaitWithItem(i));
228 | }
229 | });
230 | }
231 |
232 | case BringToCart:
233 | if( carriedEnt==null ) {
234 | doTask(Idle);
235 | return;
236 | }
237 | var c = en.Cart.ME;
238 | showTaskFocus(c);
239 | setBubble("i_Cart", false);
240 | goto(c.cx, c.cy);
241 | if( distCase(c)<=1 )
242 | chargeAction("drop", 1, function() {
243 | carriedEnt.destroy();
244 | c.onDropGem();
245 | doTask(Idle);
246 | });
247 |
248 | case FleeBoss(e):
249 | if( distCase(e)>=8 ) {
250 | doTask(Idle);
251 | return;
252 | }
253 |
254 | setBubble("danger", false);
255 |
256 | if( !cd.hasSetS("pickFleePt",0.5) ) {
257 | var dh = new dn.DecisionHelper( dn.Bresenham.getDisc(cx,cy,7) );
258 | dh.keepOnly( function(pt) return !level.hasCollision(pt.x,pt.y) && sightCheckCase(pt.x,pt.y) );
259 | dh.score( function(pt) return e.distCaseFree(pt.x, pt.y) );
260 | dh.score( function(pt) return !e.sightCheckCase(pt.x, pt.y) ? 3 : 0 );
261 | dh.useBest( function(pt) {
262 | goto(pt.x, pt.y);
263 | });
264 | }
265 |
266 | case ExitLevel:
267 | var c = en.Cart.ME;
268 | setBubble("i_Cart", false);
269 | goto(c.cx, c.cy);
270 | if( distCase(c)<=1 )
271 | destroy();
272 |
273 | case Break(e):
274 | setBubble("crate");
275 | showTaskFocus(e);
276 | goto(e.cx,e.cy);
277 |
278 | case AttackDwarf(e):
279 | if( !e.isAlive() ) {
280 | // Lost target
281 | doTask(Idle);
282 | return;
283 | }
284 |
285 | if( distCase(e)>2 || !sightCheckEnt(e) ) {
286 | showTaskFocus(e);
287 | goto(e.cx, e.cy);
288 | }
289 | else {
290 | cancelPath();
291 | var a = angTo(e);
292 | var spd = getSpeed();
293 | dx += Math.cos(a) * spd * tmod;
294 | dy += Math.sin(a) * spd * tmod;
295 | }
296 | }
297 |
298 | // Remove reached path nodes
299 | while( path.length>0 && distCaseFree(path[0].cx, path[0].cy)<=0.3 )
300 | path.shift();
301 |
302 | // Follow path
303 | if( path.length>0 && !cd.has("stepLock") ) {
304 | var pt = path[0];
305 | dir = pt.footX {
330 | return [];
331 | }
332 |
333 | var curAtkTarget : Null;
334 | function chargeAtk(e:Entity) {
335 | curAtkTarget = e;
336 | }
337 |
338 | function updateAutoAttack() {
339 | if( isChargingAction("atk") || !canAct() && !isChargingAction() )
340 | return;
341 |
342 | for(e in getAttackables())
343 | if( e.isAlive() && distCase(e)<=atkRange && !e.is(en.ai.mob.Boss) && sightCheckEnt(e) ) {
344 | cancelAction();
345 | dir = dirTo(e);
346 | dx*=0.8;
347 | dy*=0.8;
348 | chargeAtk(e);
349 | break;
350 | }
351 | }
352 |
353 | function getSpeed() {
354 | return baseSpeed;
355 | }
356 |
357 | inline function lockAtk(s:Float) {
358 | cd.setS("atkLock",s);
359 | }
360 |
361 | override function update() {
362 | super.update();
363 |
364 | if( canAct() )
365 | updateAi();
366 |
367 | if( !cd.has("atkLock") )
368 | updateAutoAttack();
369 |
370 | // Garbage collect prohibiteds
371 | var i = 0;
372 | while( i0 ) {
38 | timeS -= tmod/Const.FPS;
39 | tf.text = Std.string( Std.int(timeS) );
40 | tf.x = Std.int( -tf.textWidth*0.5-1 );
41 | tf.y = -20;
42 | if( timeS<=10 && !cd.hasSetS("jump",1) )
43 | dz = -0.05;
44 |
45 | if( timeS<=0 ) {
46 | var b = new en.ai.mob.Boss(cx,cy+1);
47 | b.dz = -0.2;
48 | b.dy = 0.06;
49 | b.lockAiS(2);
50 | game.announce("Boss has arrived!!", 0xff0000, true);
51 | }
52 | }
53 | else
54 | tf.visible = false;
55 | }
56 | }
--------------------------------------------------------------------------------
/src/en/Breakable.hx:
--------------------------------------------------------------------------------
1 | package en;
2 |
3 | class Breakable extends Entity {
4 | public static var ALL : Array = [];
5 |
6 | public function new(x,y) {
7 | super(x,y);
8 | initLife(3);
9 | spr.set("crate");
10 | ALL.push(this);
11 | weight = 3;
12 | enableShadow();
13 | bumpFrict*=0.8;
14 | toBack();
15 | }
16 |
17 | override function onDie(?from:Entity) {
18 | super.onDie(from);
19 | fx.dirtExplosion(centerX, centerY, 0xb57a40);
20 | }
21 |
22 | override function dispose() {
23 | super.dispose();
24 | ALL.remove(this);
25 | }
26 | }
--------------------------------------------------------------------------------
/src/en/Cart.hx:
--------------------------------------------------------------------------------
1 | package en;
2 |
3 | class Cart extends Entity {
4 | public static var ME : Cart;
5 |
6 | public var score : Int;
7 |
8 | public function new(x,y) {
9 | super(x,y);
10 | spr.set("cart");
11 | ME = this;
12 | weight = 20;
13 | enableShadow();
14 | }
15 |
16 | public function onDropGem() {
17 | score++;
18 | fx.sparks(centerX, centerY, 0x06b4ed);
19 | popText("+1 GEM");
20 | game.refillBaits();
21 | if( game.countRemainingGems()>0 )
22 | game.announce("Gem stolen!", "Food restored. "+game.countRemainingGems()+" gems remaining", 0x1ebae1, false);
23 | else
24 | game.announce("Level wiped!", 0xffcc00, true);
25 |
26 | dz = -0.08;
27 |
28 | var g = new h2d.Bitmap(Assets.tiles.getTile("i_Gem"), spr);
29 | g.tile = g.tile.sub(0,0, g.tile.width, Std.int( g.tile.height*rnd(0.7,1) ));
30 | g.tile.setCenterRatio(0.5,1);
31 | g.x = 1 + irnd(0,6,true);
32 | g.y = -7;
33 | g.setScale( rnd(0.5,0.8) );
34 | }
35 |
36 | override function onBeforePhysics() {
37 | super.onBeforePhysics();
38 | dy = 0;
39 | bdy = 0;
40 | }
41 |
42 | override function postUpdate() {
43 | super.postUpdate();
44 | if( score>0 )
45 | fx.shine(this, 0x0088ff);
46 | }
47 |
48 | override function dispose() {
49 | super.dispose();
50 | if( ME==this )
51 | ME = null;
52 | }
53 | }
--------------------------------------------------------------------------------
/src/en/Item.hx:
--------------------------------------------------------------------------------
1 | package en;
2 |
3 | class Item extends Entity {
4 | public static var ALL : Array- = [];
5 |
6 | public var type : ItemType;
7 | public var bombTimerS = 0.;
8 |
9 | public function new(x,y, t:ItemType) {
10 | super(x,y);
11 |
12 | if( t==null )
13 | throw "Unknown item type";
14 |
15 | ALL.push(this);
16 | type = t;
17 | enableShadow();
18 | hei = Const.GRID*1.05;
19 |
20 | if( type!=Gem )
21 | spr.filter = new dn.heaps.filter.PixelOutline();
22 |
23 | refreshIcon();
24 | cd.setS("jump",rnd(0,1));
25 | }
26 |
27 | public function refreshIcon() {
28 | if( game.kidMode && type==BaitFull )
29 | spr.set("i_HeartFull");
30 | else if( game.kidMode && type==BaitPart )
31 | spr.set("i_HeartPart");
32 | else
33 | spr.set("i_"+type.getName());
34 | }
35 |
36 | override function dispose() {
37 | super.dispose();
38 | ALL.remove(this);
39 | }
40 |
41 | public function consume(by:en.Ai) {
42 | switch type {
43 | case Gem:
44 | case Bomb:
45 |
46 | case BaitFull:
47 | type = BaitPart;
48 | refreshIcon();
49 | dz = -0.1;
50 | blink(0xffcc00);
51 | by.prohibit(this);
52 |
53 | case BaitPart:
54 | fx.emptyBone(this);
55 | destroy();
56 | }
57 | }
58 |
59 | override function postUpdate() {
60 | super.postUpdate();
61 | if( type==Gem && !cd.hasSetS("shine",0.1) )
62 | fx.shine(this, 0x78deff);
63 | }
64 |
65 | override function update() {
66 | super.update();
67 |
68 | if( !isCarried && type==Gem && zr==0 && !cd.hasSetS("jump",1) )
69 | dz = -0.05;
70 |
71 | if( type==Bomb && ( isCarried || bombTimerS>0 ) ) {
72 | bombTimerS += tmod/Const.FPS;
73 | if( !cd.hasSetS("warn",0.2) )
74 | blink(0xffffff, 0.1);
75 |
76 | if( bombTimerS>=2 ) {
77 | if( isCarried ) {
78 | getCarrier().hit(9999,this);
79 | fx.flashBangS(0xffcc00, 0.5, 0.5);
80 | game.camera.shakeS(2, 0.2);
81 | }
82 | fx.explosion(centerX, centerY);
83 | destroy();
84 | }
85 | }
86 | }
87 | }
88 |
89 |
--------------------------------------------------------------------------------
/src/en/Label.hx:
--------------------------------------------------------------------------------
1 | package en;
2 |
3 | class Label extends Entity {
4 | public function new(x,y, str:String) {
5 | super(x,y);
6 |
7 | spr.set("empty");
8 | var tf = new h2d.Text(Assets.fontTiny, spr);
9 | tf.text = str;
10 | tf.maxWidth = 150;
11 | tf.x = Std.int(-tf.textWidth*0.5);
12 | tf.y = Std.int(-tf.textHeight );
13 | }
14 |
15 | override function postUpdate() {
16 | super.postUpdate();
17 | spr.visible = !Console.ME.hasFlag("screen");
18 | }
19 | }
--------------------------------------------------------------------------------
/src/en/MobGen.hx:
--------------------------------------------------------------------------------
1 | package en;
2 |
3 | class MobGen extends Entity {
4 | public static var ALL : Array
= [];
5 |
6 | var children : Array = [];
7 | public var maxChildren = 5;
8 | public var perSpawn = 2;
9 | public var delay = 5.;
10 |
11 | public function new(x,y) {
12 | super(x,y);
13 | ALL.push(this);
14 | spr.set("gen");
15 | enableShadow();
16 | game.scroller.add(spr, Const.DP_BG);
17 | }
18 |
19 | override function dispose() {
20 | super.dispose();
21 | ALL.remove(this);
22 | children = null;
23 | }
24 |
25 | function spawn() {
26 | var e = new en.ai.mob.Goblin(cx,cy);
27 | e.dz = -rnd(0.2,0.4);
28 | e.dx = rnd(0,0.2,true);
29 | e.dy = rnd(0,0.2,true);
30 | return e;
31 | }
32 |
33 | override function postUpdate() {
34 | super.postUpdate();
35 | spr.alpha = 0.6;
36 | }
37 |
38 | override function update() {
39 | super.update();
40 |
41 | // GC
42 | var i = 0;
43 | while( i0 && children.length = [];
5 |
6 | public function new(x,y) {
7 | super(x,y);
8 |
9 | initLife(999);
10 | ALL.push(this);
11 | weight = 8;
12 | detectRadius = 12;
13 | atkRange = 1.5;
14 |
15 | spr.anim.registerStateAnim("d_hit", 10, 0.15, function() return hasAffect(Stun) );
16 | spr.anim.registerStateAnim("d_atk_charge", 3, 0.15, function() return isChargingAction("atk") );
17 | spr.anim.registerStateAnim("d_act", 2, 0.15, function() return isChargingAction() );
18 | spr.anim.registerStateAnim("d_walk", 1, rnd(0.11,0.15), function() return isWalking() );
19 | spr.anim.registerStateAnim("d_idle", 0, 0.1);
20 | game.scroller.add(spr, Const.DP_DWARF);
21 |
22 | doTask( Wait(ftime+1.5*Const.FPS) );
23 | }
24 |
25 | override function dispose() {
26 | super.dispose();
27 |
28 | ALL.remove(this);
29 | }
30 |
31 | override function onDamage(dmg:Int, from:Null) {
32 | super.onDamage(dmg, from);
33 |
34 | cancelAction();
35 | if( isAlive() )
36 | releaseCarriedEnt(true);
37 |
38 | blink(0xffffff);
39 |
40 | setAffectS(Stun,0.45);
41 | fx.flashBangS(0xff0000, 0.1, 0.2);
42 |
43 | if( from!=null )
44 | bumpFrom(from, 0.08);
45 | }
46 |
47 | override function onDie(?from:Entity) {
48 | super.onDie(from);
49 | if( ALL.length==1 )
50 | game.gameOver();
51 | fx.bloodExplosion(centerX, centerY);
52 | game.announce("Dwarf obliterated", 0xff0000, true);
53 | }
54 |
55 | override function getSpeed():Float {
56 | return super.getSpeed();
57 | }
58 |
59 | function takeDecision() {
60 | if( game.countRemainingGems()==0 && Cart.ME!=null ) {
61 | doTask(ExitLevel);
62 | return;
63 | }
64 |
65 | var boss = en.ai.mob.Boss.ME;
66 | if( boss!=null && distCase(boss)<=4 && ( sightCheckEnt(boss) || boss.isChargingAction("atk") ) ) {
67 | doTask(FleeBoss(boss));
68 | return;
69 | }
70 |
71 | var dh = new dn.DecisionHelper(Entity.ALL);
72 | dh.keepOnly( function(e) return e.is(Item) || e.is(Breakable) );
73 | dh.keepOnly( function(e) return e.isAlive() && !isProhibited(e) && canDetect(e) );
74 | dh.score( function(e) return rnd(0,2) );
75 | dh.score( function(e) return -distCase(e)*0.2 );
76 |
77 | // Score based on itemType
78 | dh.score( function(e) {
79 | return
80 | if( e.is(Item) )
81 | switch e.as(Item).type {
82 | case Gem: 2;
83 | case BaitFull, BaitPart: 5;
84 | case Bomb: 0.75;
85 | }
86 | else if( e.is(Breakable) )
87 | 0.75;
88 | else
89 | 0;
90 | });
91 |
92 | dh.useBest( function(e) {
93 | if( e.is(Item) )
94 | doTask( Grab(e.as(Item)) );
95 | else if( e.is(Breakable) )
96 | doTask( Break(e.as(Breakable)) );
97 | });
98 | }
99 |
100 | override function doTask(t:Task) {
101 | if( t==Idle && task!=Idle )
102 | cd.setS("decision", rnd(0.2,0.3));
103 |
104 | super.doTask(t);
105 | }
106 |
107 | override function showTaskFocus(e:Entity) {
108 | super.showTaskFocus(e);
109 |
110 | if( !cd.hasSetS("focusFx",0.1) )
111 | fx.focus(this, e);
112 | }
113 |
114 | override function updateAi() {
115 | super.updateAi();
116 |
117 | switch task {
118 | case Idle:
119 | if( !cd.has("pickIdlePt") ) {
120 | cd.setS("pickIdlePt",rnd(1,1.5));
121 | var dh = new dn.DecisionHelper( dn.Bresenham.getDisc(cx,cy, 4) );
122 | dh.keepOnly( function(pt) return !level.hasCollision(pt.x,pt.y) && sightCheckCase(pt.x,pt.y) );
123 | dh.score( function(pt) return rnd(0,1,true) + distCaseFree(pt.x,pt.y)*0.5 );
124 | for(d in ALL)
125 | if( d!=this && distCase(d)<=5 )
126 | dh.score( function(pt) return d.distCaseFree(pt.x,pt.y)*0.08 );
127 |
128 | dh.useBest( function(pt) {
129 | goto(pt.x,pt.y);
130 | });
131 | }
132 |
133 | if( !cd.hasSetS("decision", 0.6) )
134 | takeDecision();
135 |
136 | case Break(e):
137 | if( !e.isAlive() ) {
138 | doTask(Idle);
139 | return;
140 | }
141 | if( distCase(e)<=1 )
142 | chargeAtk(e);
143 |
144 | case WaitWithItem(e):
145 | if( !cd.hasSetS("huh",3) )
146 | popText("Huh?", 0xff6600);
147 |
148 | case _:
149 | }
150 | }
151 |
152 |
153 | var atkA = true;
154 | override function chargeAtk(e) {
155 | super.chargeAtk(e);
156 |
157 | chargeAction("atk", 0.07, function() {
158 | spr.anim.play(atkA ? "d_atkA" : "d_atkB").setSpeed(0.2);
159 | lockAiS(atkA ? 0.1 : 0.3);
160 | cd.setS("resetAtk",0.4);
161 | atkA = !atkA;
162 |
163 | if( !e.isAlive() || distCase(e)>atkRange*2 )
164 | return;
165 |
166 | e.hit(1, this);
167 | if( atkA && path.length==0 ) {
168 | dx += Math.cos(angTo(e))*0.05;
169 | dy += Math.sin(angTo(e))*0.05;
170 | }
171 | else
172 | bumpEnt(e, rnd(0.08,0.09));
173 |
174 | game.camera.shakeS(0.2,0.2);
175 | game.camera.bump(dir*4,0);
176 | fx.impact(e.headX, e.headY, angTo(e));
177 | if( e.is(Mob) ) {
178 | fx.bloodImpact(e.headX, e.headY, angTo(e));
179 | fx.blood(e.headX, e.headY, angTo(e));
180 | }
181 | else
182 | fx.dirtImpact(e.centerX, e.centerY, 0xb57a40, angTo(e));
183 | });
184 | }
185 |
186 | override function getAttackables() : Array {
187 | return cast Mob.ALL;
188 | }
189 |
190 | override function postUpdate() {
191 | super.postUpdate();
192 | if( bubble!=null ) {
193 | bubble.x = Std.int( headX );
194 | bubble.y = Std.int( headY-3 - M.fabs( Math.cos(ftime*0.1)*2 ) );
195 | }
196 | }
197 |
198 | override function update() {
199 | super.update();
200 |
201 | if( !atkA && !cd.has("resetAtk") )
202 | atkA = true;
203 | }
204 | }
--------------------------------------------------------------------------------
/src/en/ai/Mob.hx:
--------------------------------------------------------------------------------
1 | package en.ai;
2 |
3 | class Mob extends en.Ai {
4 | public static var ALL : Array = [];
5 |
6 | private function new(x,y) {
7 | super(x,y);
8 | ALL.push(this);
9 | detectRadius = 7;
10 | weight = 1;
11 | }
12 |
13 | override function onDamage(dmg:Int, from:Null) {
14 | super.onDamage(dmg, from);
15 | }
16 |
17 | override function dispose() {
18 | super.dispose();
19 | ALL.remove(this);
20 | }
21 |
22 |
23 | override function updateAi() {
24 | super.updateAi();
25 | updateAggro();
26 | }
27 |
28 | function updateAggro() {
29 | if( task==Idle ) {
30 | for(e in Dwarf.ALL)
31 | if( distCase(e)<=detectRadius && sightCheckEnt(e) ) {
32 | for(m in ALL)
33 | if( m!=this && m.isAlive() && distCase(m)<=4 && sightCheckEnt(m) )
34 | m.doTask( AttackDwarf(e) );
35 | doTask( AttackDwarf(e) );
36 | }
37 | }
38 | }
39 |
40 | override function getAttackables() {
41 | return cast Dwarf.ALL;
42 | }
43 | }
--------------------------------------------------------------------------------
/src/en/ai/mob/Boss.hx:
--------------------------------------------------------------------------------
1 | package en.ai.mob;
2 |
3 | class Boss extends en.ai.Mob {
4 | public static var ME : Boss;
5 |
6 | public function new(x,y) {
7 | super(x,y);
8 | ME = this;
9 | initLife(9999);
10 | atkRange = 2;
11 | weight = 1;
12 | sprScaleX = sprScaleY = 3;
13 |
14 | spr.anim.registerStateAnim("a_atk_charge", 2, 0.15, function() return isChargingAction("atk") );
15 | spr.anim.registerStateAnim("a_walk", 1, 0.15, function() return isWalking() );
16 | spr.anim.registerStateAnim("a_idle", 0, 0.1);
17 | }
18 |
19 | override function dispose() {
20 | super.dispose();
21 | if( ME==this )
22 | ME = null;
23 | }
24 |
25 | override function getSpeed():Float {
26 | return super.getSpeed()*0.55;
27 | }
28 |
29 | override function onBeforePhysics() {
30 | super.onBeforePhysics();
31 | bdx*=Math.pow(0.1,tmod);
32 | bdy*=Math.pow(0.1,tmod);
33 | }
34 |
35 | override function chargeAtk(e:Entity) {
36 | super.chargeAtk(e);
37 |
38 | bumpTo(e, 0.05);
39 | chargeAction("atk", 2, function() {
40 | dir = dirTo(e);
41 |
42 | spr.anim.play("a_atk").setSpeed(0.2);
43 | lockAiS(1);
44 |
45 | var a = angTo(e);
46 | fx.bossAtk(footX+Math.cos(a)*atkRange*Const.GRID, footY+Math.sin(a)*atkRange*Const.GRID);
47 | game.camera.shakeS(0.4, 1);
48 |
49 | if( !e.isAlive() || distCase(e)>atkRange*2 || !sightCheckEnt(e) )
50 | return;
51 |
52 | lockAtk(1);
53 | e.hit(99999, this);
54 | game.addSlowMo("boss",0.5, 0.3);
55 | fx.bloodImpact(e.headX, e.headY, angTo(e));
56 | });
57 | }
58 |
59 |
60 | override function updateAggro() {
61 | if( Dwarf.ALL.length==0 )
62 | return;
63 |
64 | if( task==Idle )
65 | doTask( AttackDwarf(Dwarf.ALL[0]) );
66 |
67 | if( !cd.hasSetS("aggroBoss", 1) ) {
68 | var dh = new dn.DecisionHelper(Dwarf.ALL);
69 | dh.keepOnly( function(e) return e.isAlive() );
70 | dh.score( function(e) return -distCase(e)*0.2 );
71 | dh.score( function(e) return sightCheckEnt(e) ? 3 : 0 );
72 | dh.useBest( function(e) {
73 | doTask( AttackDwarf(e) );
74 | });
75 | }
76 | }
77 |
78 | override function showTaskFocus(e:Entity) {
79 | super.showTaskFocus(e);
80 | fx.focus(this, e, 0xff0000);
81 | }
82 |
83 |
84 | override function postUpdate() {
85 | super.postUpdate();
86 | if( isChargingAction("atk") && !cd.has("blinkBoss") ) {
87 | if( getActionRemainingSec("atk")<=1 ) {
88 | blink(0xffff00, 0.1);
89 | cd.setS("blinkBoss", 0.15);
90 | }
91 | // else {
92 | // blink(0xff0000);
93 | // cd.setS("blinkBoss", 0.4);
94 | // }
95 | }
96 | }
97 |
98 | }
--------------------------------------------------------------------------------
/src/en/ai/mob/Goblin.hx:
--------------------------------------------------------------------------------
1 | package en.ai.mob;
2 |
3 | class Goblin extends en.ai.Mob {
4 | public function new(x,y) {
5 | super(x,y);
6 | initLife( irnd(1,2) );
7 | detectRadius = 6;
8 | atkRange = 0.8;
9 | weight = 1;
10 |
11 | spr.anim.registerStateAnim("a_atk_charge", 2, 0.15, function() return isChargingAction("atk") );
12 | spr.anim.registerStateAnim("a_walk", 1, 0.15, function() return isWalking() );
13 | spr.anim.registerStateAnim("a_idle", 0, 0.1);
14 | }
15 |
16 | override function onDamage(dmg:Int, from:Null) {
17 | super.onDamage(dmg, from);
18 | cancelAction();
19 | lockAiS(rnd(0.6,0.8));
20 | blink(0xffffff);
21 | }
22 |
23 | override function onDie(?from:Entity) {
24 | super.onDie(from);
25 | fx.gibs(centerX, centerY, from.angTo(this), 0x748954);
26 | }
27 |
28 | override function getSpeed():Float {
29 | return super.getSpeed()*2;
30 | }
31 |
32 |
33 | override function chargeAtk(e:Entity) {
34 | super.chargeAtk(e);
35 |
36 | bumpTo(e, 0.05);
37 | chargeAction("atk", 0.5, function() {
38 | dir = dirTo(e);
39 |
40 | spr.anim.play("a_atk").setSpeed(0.2);
41 | lockAiS(1);
42 |
43 |
44 | if( !e.isAlive() || distCase(e)>2 )
45 | return;
46 |
47 | lockAtk(1);
48 | e.hit(1, this);
49 | fx.bloodImpact(e.headX, e.headY, angTo(e));
50 | });
51 | }
52 | }
--------------------------------------------------------------------------------
/src/import.hx:
--------------------------------------------------------------------------------
1 | import dn.M;
2 | import dn.Lib;
3 | import dn.Color;
4 | import dn.Color as C;
5 | import dn.Tweenie;
6 | import dn.data.GetText;
7 | import dn.heaps.slib.*;
8 | import ui.Console;
9 | import tools.*;
10 | import Types;
--------------------------------------------------------------------------------
/src/tools/CPoint.hx:
--------------------------------------------------------------------------------
1 | package tools;
2 |
3 | class CPoint {
4 | public var cx : Int;
5 | public var cy : Int;
6 | public var xr : Float;
7 | public var yr : Float;
8 |
9 | public var footX(get,never) : Float; inline function get_footX() return (cx+xr)*Const.GRID;
10 | public var footY(get,never) : Float; inline function get_footY() return (cy+yr)*Const.GRID;
11 | public var centerX(get,never) : Float; inline function get_centerX() return footX;
12 | public var centerY(get,never) : Float; inline function get_centerY() return footY-Const.GRID*0.5;
13 |
14 | public function new(x,y, ?xr=0.5, ?yr=0.5) {
15 | cx = x;
16 | cy = y;
17 | this.xr = xr;
18 | this.yr = yr;
19 | }
20 |
21 | public function set(x,y,?xr=0.5,?yr=0.5) {
22 | this.cx = x;
23 | this.cy = y;
24 | this.xr = xr;
25 | this.yr = yr;
26 | }
27 |
28 | public function setPixel(x:Float, y:Float) {
29 | cx = Std.int(x/Const.GRID);
30 | cy = Std.int(y/Const.GRID);
31 | xr = (x-cx*Const.GRID)/Const.GRID;
32 | yr = (y-cy*Const.GRID)/Const.GRID;
33 | }
34 |
35 | public function setEntity(e:Entity) {
36 | cx = e.cx;
37 | cy = e.cy;
38 | xr = e.xr;
39 | yr = e.yr;
40 | }
41 |
42 | public function distCase(?e:Entity, ?pt:CPoint, ?cx=0, ?cy=0, ?xr=0.5, ?yr=0.5) {
43 | if( e!=null )
44 | return M.dist(this.cx+this.xr, this.cy+this.yr, e.cx+e.xr, e.cy+e.yr);
45 | else if( pt!=null )
46 | return M.dist(this.cx+this.xr, this.cy+this.yr, pt.cx+pt.xr, pt.cy+pt.yr);
47 | else
48 | return M.dist(this.cx+this.xr, this.cy+this.yr, cx+xr, cy+yr);
49 | }
50 |
51 | public inline function distPx(?e:Entity, ?pt:CPoint, ?x=0., ?y=0.) {
52 | if( e!=null )
53 | return M.dist(footX, footY, e.footX, e.footY);
54 | else if( pt!=null )
55 | return M.dist(footX, footY, pt.footX, pt.footY);
56 | else
57 | return M.dist(footX, footY, x, y);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/tools/MouseCoords.hx:
--------------------------------------------------------------------------------
1 | package tools;
2 |
3 | class MouseCoords {
4 | public var gx : Float;
5 | public var gy : Float;
6 |
7 | public var levelX(get,never) : Int;
8 | inline function get_levelX() return M.round( ( gx - game.scroller.x ) / Const.SCALE );
9 |
10 | public var levelY(get,never) : Int;
11 | inline function get_levelY() return M.round( ( gy - game.scroller.y ) / Const.SCALE );
12 |
13 | public var cx(get,never) : Int;
14 | inline function get_cx() return M.floor( levelX / Const.GRID );
15 |
16 | public var cy(get,never) : Int;
17 | inline function get_cy() return M.floor( levelY / Const.GRID );
18 |
19 | var game(get,never) : Game; inline function get_game() return Game.ME;
20 |
21 | public function new(gx:Float,gy:Float) {
22 | this.gx = gx;
23 | this.gy = gy;
24 | }
25 | }
26 |
27 |
--------------------------------------------------------------------------------
/src/ui/Bar.hx:
--------------------------------------------------------------------------------
1 | package ui;
2 |
3 | class Bar extends h2d.Object {
4 | var cd : dn.Cooldown;
5 | var bg : h2d.ScaleGrid;
6 | var bar : h2d.ScaleGrid;
7 | var oldBar : Null;
8 |
9 | public var innerBarMaxWidth(get,never) : Float;
10 | public var innerBarHeight(get,never) : Float;
11 | public var outerWidth(get,never) : Float;
12 | public var outerHeight(get,never) : Float;
13 | public var color(default,set) : UInt;
14 | public var defaultColor(default,null) : UInt;
15 | var padding : Int;
16 | var oldBarSpeed : Float;
17 |
18 | var blinkColor : h3d.Vector;
19 | var gradTg : Null;
20 |
21 | var curValue : Float;
22 | var curMax : Float;
23 |
24 | public function new(wid:Int, hei:Int, c:UInt, ?p:h2d.Object) {
25 | super(p);
26 |
27 | curValue = 0;
28 | curMax = 1;
29 | cd = new dn.Cooldown(Const.FPS);
30 |
31 | bg = new h2d.ScaleGrid( Assets.tiles.getTile("uiBarBg"), 2, 2, this );
32 | bg.colorAdd = blinkColor = new h3d.Vector();
33 |
34 | bar = new h2d.ScaleGrid( Assets.tiles.getTile("uiBar"), 1,1, this );
35 |
36 | setSize(wid,hei,1);
37 | defaultColor = color = c;
38 | }
39 |
40 | public function enableOldValue(oldBarColor:UInt, speed=1.0) {
41 | if( oldBar!=null )
42 | oldBar.remove();
43 | oldBar = new h2d.ScaleGrid( h2d.Tile.fromColor(oldBarColor,3,3), 1, 1 );
44 | this.addChildAt( oldBar, this.getChildIndex(bar) );
45 | oldBar.height = bar.height;
46 | oldBar.width = 0;
47 | oldBar.setPosition(padding,padding);
48 |
49 | oldBarSpeed = speed;
50 | }
51 |
52 | public function setGraduationPx(step:Int, ?alpha=0.5) {
53 | if( step<=1 )
54 | throw "Invalid bar graduation "+step;
55 |
56 | if( gradTg!=null )
57 | gradTg.remove();
58 |
59 | gradTg = new h2d.TileGroup(Assets.tiles.tile, this);
60 | gradTg.colorAdd = blinkColor;
61 | gradTg.setDefaultColor(0x0, alpha);
62 |
63 | var x = step-1;
64 | var t = Assets.tiles.getTile("pixel");
65 | while( xbar.width) {
114 | cd.setS("oldMaintain",0.06);
115 | oldBar.width = oldWidth;
116 | }
117 | }
118 |
119 | function renderBar() {
120 | bar.visible = curValue>0;
121 | bar.width = innerBarMaxWidth * (curValue/curMax);
122 | }
123 |
124 | public function skipOldValueBar() {
125 | if( oldBar!=null )
126 | oldBar.width = 0;
127 | }
128 |
129 | public function blink(?c:UInt, ?a=1.0) {
130 | blinkColor.setColor( Color.addAlphaF(c==null ? color : c,a) );
131 | cd.setS("blinkMaintain", 0.15 * 1/oldBarSpeed);
132 | }
133 |
134 | override function sync(ctx:h2d.RenderContext) {
135 | var tmod = Game.ME.tmod;
136 | cd.update(tmod);
137 |
138 | // Decrease oldValue bar
139 | if( oldBar!=null ) {
140 | if( !cd.has("oldMaintain") )
141 | oldBar.width = M.fmax(0, oldBar.width - oldBarSpeed*2*tmod);
142 | oldBar.visible = oldBar.width>0;
143 | }
144 |
145 | // Blink fade
146 | if( !cd.has("blinkMaintain") ) {
147 | blinkColor.r*=Math.pow(0.60, tmod);
148 | blinkColor.g*=Math.pow(0.55, tmod);
149 | blinkColor.b*=Math.pow(0.50, tmod);
150 | }
151 |
152 | super.sync(ctx);
153 | }
154 | }
--------------------------------------------------------------------------------
/src/ui/Console.hx:
--------------------------------------------------------------------------------
1 | package ui;
2 |
3 | class Console extends h2d.Console {
4 | public static var ME : Console;
5 | #if debug
6 | var flags : Map;
7 | #end
8 |
9 | public function new(f:h2d.Font, p:h2d.Object) {
10 | super(f, p);
11 |
12 | scale(2); // TODO smarter scaling for 4k screens
13 |
14 | // Settings
15 | ME = this;
16 | h2d.Console.HIDE_LOG_TIMEOUT = 30;
17 | Lib.redirectTracesToH2dConsole(this);
18 |
19 | // Debug flags
20 | #if debug
21 | flags = new Map();
22 | this.addCommand("set", [{ name:"k", t:AString }], function(k:String) {
23 | setFlag(k,true);
24 | log("+ "+k.toLowerCase(), 0x80FF00);
25 | });
26 | this.addCommand("unset", [{ name:"k", t:AString, opt:true } ], function(?k:String) {
27 | if( k==null ) {
28 | log("Reset all.",0xFF0000);
29 | for(k in flags.keys())
30 | setFlag(k,false);
31 | }
32 | else {
33 | log("- "+k,0xFF8000);
34 | setFlag(k,false);
35 | }
36 | });
37 | this.addCommand("list", [], function() {
38 | for(k in flags.keys())
39 | log(k, 0x80ff00);
40 | });
41 | this.addAlias("+","set");
42 | this.addAlias("-","unset");
43 | #end
44 | }
45 |
46 | override function handleCommand(command:String) {
47 | var flagReg = ~/[\/ \t]*\+[ \t]*([\w]+)/g; // cleanup missing spaces
48 | super.handleCommand( flagReg.replace(command, "/+ $1") );
49 | }
50 |
51 | public function error(msg:Dynamic) {
52 | log("[ERROR] "+Std.string(msg), 0xff0000);
53 | h2d.Console.HIDE_LOG_TIMEOUT = Const.INFINITE;
54 | }
55 |
56 | #if debug
57 | public function setFlag(k:String,v) {
58 | k = k.toLowerCase();
59 | var hadBefore = hasFlag(k);
60 |
61 | if( v )
62 | flags.set(k,v);
63 | else
64 | flags.remove(k);
65 |
66 | if( v && !hadBefore || !v && hadBefore )
67 | onFlagChange(k,v);
68 | return v;
69 | }
70 | public function hasFlag(k:String) return flags.get( k.toLowerCase() )==true;
71 | #else
72 | public function hasFlag(k:String) return false;
73 | #end
74 |
75 | public function onFlagChange(k:String, v:Bool) {}
76 | }
--------------------------------------------------------------------------------
/src/ui/Hud.hx:
--------------------------------------------------------------------------------
1 | package ui;
2 |
3 | class Hud extends dn.Process {
4 | public var game(get,never) : Game; inline function get_game() return Game.ME;
5 | public var fx(get,never) : Fx; inline function get_fx() return Game.ME.fx;
6 | public var level(get,never) : Level; inline function get_level() return Game.ME.level;
7 |
8 | var flow : h2d.Flow;
9 | var invalidated = true;
10 | var lastBaits = 0;
11 |
12 | public function new() {
13 | super(Game.ME);
14 |
15 | createRootInLayers(game.root, Const.DP_UI);
16 | root.filter = new h2d.filter.ColorMatrix(); // force pixel perfect rendering
17 |
18 | flow = new h2d.Flow(root);
19 | flow.layout = Vertical;
20 | // flow.backgroundTile = h2d.Tile.fromColor(0x0);
21 | flow.padding = 2;
22 | }
23 |
24 | override function onResize() {
25 | super.onResize();
26 | root.setScale(Const.UI_SCALE);
27 | flow.x = 2;
28 | flow.y = Std.int( h()/Const.UI_SCALE*0.5 - flow.outerHeight*0.5 );
29 | }
30 |
31 | public inline function invalidate() invalidated = true;
32 |
33 | function render() {
34 | flow.removeChildren();
35 | for(i in 0...Const.BAITS) {
36 | var active = i+1<=game.baits;
37 | var k = "uiBait"+(active?"On":"Off");
38 | if( game.kidMode )
39 | k = active ? "i_HeartFull" : "i_HeartHollow";
40 | var e = Assets.tiles.h_get(k, flow);
41 | e.scale(2);
42 | if( active && i+1>lastBaits ) {
43 | var a = Assets.tiles.h_get("fxExplosion", flow);
44 | a.blendMode = Add;
45 | a.colorize(0x9effa5);
46 | a.setCenterRatio(0.5,0.5);
47 | a.rotation = M.PI;
48 | a.scale(2);
49 |
50 | a.anim.play("fxExplosion");
51 | a.anim.killAfterPlay();
52 | a.anim.setSpeed(0.2);
53 |
54 | flow.getProperties(a).isAbsolute = true;
55 | flow.reflow();
56 | a.x = e.x + e.tile.width*0.5 * e.scaleX;
57 | a.y = e.y + e.tile.height*0.5 * e.scaleY;
58 | }
59 | }
60 | lastBaits = game.baits;
61 | }
62 |
63 | override function postUpdate() {
64 | super.postUpdate();
65 |
66 | if( invalidated ) {
67 | invalidated = false;
68 | render();
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/ui/Modal.hx:
--------------------------------------------------------------------------------
1 | package ui;
2 |
3 | class Modal extends ui.Window {
4 | public static var ALL : Array = [];
5 | static var COUNT = 0;
6 |
7 | var ca : dn.heaps.Controller.ControllerAccess;
8 | var mask : h2d.Bitmap;
9 | var modalIdx : Int;
10 |
11 | public function new() {
12 | super();
13 |
14 | ALL.push(this);
15 | modalIdx = COUNT++;
16 | if( modalIdx==0 )
17 | Game.ME.pause();
18 |
19 | ca = Main.ME.controller.createAccess("modal", true);
20 | mask = new h2d.Bitmap(h2d.Tile.fromColor(0x0, 1, 1, 0.6), root);
21 | root.under(mask);
22 | dn.Process.resizeAll();
23 | }
24 |
25 | public static function hasAny() {
26 | for(e in ALL)
27 | if( !e.destroyed )
28 | return true;
29 | return false;
30 | }
31 |
32 | override function onDispose() {
33 | super.onDispose();
34 | ca.dispose();
35 | ALL.remove(this);
36 | COUNT--;
37 | if( !hasAny() )
38 | Game.ME.resume();
39 | }
40 |
41 | function closeAllModals() {
42 | for(e in ALL)
43 | if( !e.destroyed )
44 | e.close();
45 | }
46 |
47 | override function onResize() {
48 | super.onResize();
49 | if( mask!=null ) {
50 | var w = M.ceil( w()/Const.UI_SCALE );
51 | var h = M.ceil( h()/Const.UI_SCALE );
52 | mask.scaleX = w;
53 | mask.scaleY = h;
54 | }
55 | }
56 |
57 | override function postUpdate() {
58 | super.postUpdate();
59 | mask.visible = modalIdx==0;
60 | win.alpha = modalIdx==COUNT-1 ? 1 : 0.6;
61 | }
62 |
63 | override function update() {
64 | super.update();
65 | if( ca.bPressed() || ca.isKeyboardPressed(hxd.Key.ESCAPE) )
66 | close();
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/ui/Window.hx:
--------------------------------------------------------------------------------
1 | package ui;
2 |
3 | class Window extends dn.Process {
4 | public var win: h2d.Flow;
5 |
6 | public function new() {
7 | super(Game.ME);
8 |
9 | createRootInLayers(Game.ME.root, Const.DP_UI);
10 | root.filter = new h2d.filter.ColorMatrix(); // force pixel perfect rendering
11 |
12 | win = new h2d.Flow(root);
13 | win.backgroundTile = h2d.Tile.fromColor(0xffffff, 32,32);
14 | win.borderWidth = 7;
15 | win.borderHeight = 7;
16 | win.layout = Vertical;
17 | win.verticalSpacing = 2;
18 |
19 | dn.Process.resizeAll();
20 | }
21 |
22 | public function clearWindow() {
23 | win.removeChildren();
24 | }
25 |
26 | public inline function add(e:h2d.Flow) {
27 | win.addChild(e);
28 | onResize();
29 | }
30 |
31 | override function onResize() {
32 | super.onResize();
33 |
34 | root.scale(Const.UI_SCALE);
35 |
36 | var w = M.ceil( w()/Const.UI_SCALE );
37 | var h = M.ceil( h()/Const.UI_SCALE );
38 | win.x = Std.int( w*0.5 - win.outerWidth*0.5 );
39 | win.y = Std.int( h*0.5 - win.outerHeight*0.5 );
40 | }
41 |
42 | function onClose() {}
43 | public function close() {
44 | if( !destroyed ) {
45 | destroy();
46 | onClose();
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/swf.hxml:
--------------------------------------------------------------------------------
1 | base.hxml
2 | -swf bin/client.swf
3 | -swf-header 1400:700:60:000000
4 | -swf-version 24.0
5 |
--------------------------------------------------------------------------------