]> nyquistdev.net Git - clonemon.git/commitdiff
first commit main
authorA-Larsen <austin.larsen@mailfence.com>
Wed, 14 Oct 2026 20:01:32 +0000 (16:01 -0400)
committerA-Larsen <austin.larsen@mailfence.com>
Wed, 14 Oct 2026 20:01:32 +0000 (16:01 -0400)
240 files changed:
LICENSE.txt [new file with mode: 0644]
README.adoc [new file with mode: 0644]
docinfo.conf [new file with mode: 0644]
docs/map_chunk_loader.adoc [new file with mode: 0644]
docs/notes.adoc [new file with mode: 0644]
docs/todo.adoc [new file with mode: 0644]
extensions/audio/init.lua [new file with mode: 0644]
extensions/config/init.lua [new file with mode: 0644]
extensions/config/mappings/default_gamepad.lua [new file with mode: 0644]
extensions/config/mappings/default_keyboard.lua [new file with mode: 0644]
extensions/config/mappings/init.lua [new file with mode: 0644]
extensions/database/init.lua [new file with mode: 0644]
extensions/database/schema.lua [new file with mode: 0644]
extensions/images/init.lua [new file with mode: 0644]
extensions/init.lua [new file with mode: 0644]
extensions/loops/init.lua [new file with mode: 0644]
extensions/metatables/ui.lua [new file with mode: 0644]
extensions/sprites/init.lua [new file with mode: 0644]
extensions/terminal/commands.lua [new file with mode: 0644]
extensions/terminal/init.lua [new file with mode: 0644]
extensions/text/init.lua [new file with mode: 0644]
init.lua [new file with mode: 0644]
map_configs/controls/controls.lua [new file with mode: 0644]
map_configs/crops/indoor.lua [new file with mode: 0644]
map_configs/crops/outdoor.lua [new file with mode: 0644]
map_configs/indoor1.lua [new file with mode: 0644]
map_configs/outdoor1.lua [new file with mode: 0644]
mapeditor [new file with mode: 0755]
modules/ai.lua [new file with mode: 0644]
modules/clock.lua [new file with mode: 0644]
modules/collection.lua [new file with mode: 0644]
modules/copy.lua [new file with mode: 0644]
modules/find.lua [new file with mode: 0644]
modules/hashTable.lua [new file with mode: 0644]
modules/metatables/entity.lua [new file with mode: 0644]
modules/player.lua [new file with mode: 0644]
modules/state.lua [new file with mode: 0644]
modules/string.lua [new file with mode: 0644]
modules/table.lua [new file with mode: 0644]
modules/uuid.lua [new file with mode: 0644]
modules/world.lua [new file with mode: 0644]
old/world.lua [new file with mode: 0644]
old/world/main.lua [new file with mode: 0644]
rendered.html [new file with mode: 0644]
resources/data/test/map1.dat [new file with mode: 0644]
resources/data/test/map1.hcd [new file with mode: 0644]
resources/data/test/map4.dat [new file with mode: 0644]
resources/data/test/map5.dat [new file with mode: 0644]
resources/data/test/map6.dat [new file with mode: 0644]
resources/data/test/objects1.dat [new file with mode: 0644]
resources/data/test/objects4.dat [new file with mode: 0644]
resources/data/test/objects5.dat [new file with mode: 0644]
resources/data/test/objects6.dat [new file with mode: 0644]
resources/fonts/NotoSansMono-Regular.ttf [new file with mode: 0644]
resources/images/Route_111.png [new file with mode: 0644]
resources/images/Untitled.xcf [new file with mode: 0644]
resources/images/axolotl.png [new file with mode: 0644]
resources/images/bag.png [new file with mode: 0644]
resources/images/battle_ui.png [new file with mode: 0644]
resources/images/berry_one.png [new file with mode: 0644]
resources/images/border1.png [new file with mode: 0644]
resources/images/border1_unselected.png [new file with mode: 0644]
resources/images/border2..png [new file with mode: 0644]
resources/images/border2.png [new file with mode: 0644]
resources/images/border2_unselected.png [new file with mode: 0644]
resources/images/capybara.png [new file with mode: 0644]
resources/images/character_spritesheet_1.png [new file with mode: 0644]
resources/images/choice_select_test_one.png [new file with mode: 0644]
resources/images/choice_select_test_two.png [new file with mode: 0644]
resources/images/clonemon.png [new file with mode: 0644]
resources/images/clonemon_battle_grass.png [new file with mode: 0644]
resources/images/clonemon_battle_ui.png [new file with mode: 0644]
resources/images/clonemon_battle_ui_grass.png [new file with mode: 0644]
resources/images/clonemon_party.png [new file with mode: 0644]
resources/images/generic_house_one.png [new file with mode: 0644]
resources/images/gradient.png [new file with mode: 0644]
resources/images/house_two.png [new file with mode: 0644]
resources/images/keyboard_lower.png [new file with mode: 0644]
resources/images/keyboard_upper.png [new file with mode: 0644]
resources/images/lion_back.png [new file with mode: 0644]
resources/images/loadsave.png [new file with mode: 0644]
resources/images/logo.png [new file with mode: 0644]
resources/images/map_indoor_1.png [new file with mode: 0644]
resources/images/map_indoor_2.png [new file with mode: 0644]
resources/images/map_outdoor1.png [new file with mode: 0644]
resources/images/map_outdoor_1.png [new file with mode: 0644]
resources/images/map_outdoor_10.png [new file with mode: 0644]
resources/images/map_outdoor_2.png [new file with mode: 0644]
resources/images/map_outdoor_3.png [new file with mode: 0644]
resources/images/map_outdoor_4.png [new file with mode: 0644]
resources/images/map_outdoor_5.png [new file with mode: 0644]
resources/images/map_outdoor_6.png [new file with mode: 0644]
resources/images/map_outdoor_7.png [new file with mode: 0644]
resources/images/map_outdoor_8.png [new file with mode: 0644]
resources/images/map_outdoor_9.png [new file with mode: 0644]
resources/images/menu_items.png [new file with mode: 0644]
resources/images/nyquist.png [new file with mode: 0644]
resources/images/nyquist.xcf [new file with mode: 0644]
resources/images/nyquist2.png [new file with mode: 0644]
resources/images/nyquist_spritesheet.png [new file with mode: 0644]
resources/images/nyquist_spritesheet3.png [new file with mode: 0644]
resources/images/outdoors_backgorund_one.png [new file with mode: 0644]
resources/images/owl.png [new file with mode: 0644]
resources/images/pause.png [new file with mode: 0644]
resources/images/potion_one.png [new file with mode: 0644]
resources/images/potion_two.png [new file with mode: 0644]
resources/images/spritesheet_indoors_1.backup.png [new file with mode: 0644]
resources/images/spritesheet_indoors_1.png [new file with mode: 0644]
resources/images/spritesheet_indoors_1.xcf [new file with mode: 0644]
resources/images/spritesheet_indoors_1_backup.png [new file with mode: 0644]
resources/images/spritesheet_indoors_1_backup.xcf [new file with mode: 0644]
resources/images/spritesheet_outdoor_1.png [new file with mode: 0644]
resources/images/spritesheet_partybox.png [new file with mode: 0644]
resources/images/tileset_indoors_1.png [new file with mode: 0644]
resources/images/tileset_outside_1.png [new file with mode: 0644]
resources/images/town4.png [new file with mode: 0644]
resources/images/tree_one.png [new file with mode: 0644]
resources/images/tree_two.png [new file with mode: 0644]
resources/images/vs.png [new file with mode: 0644]
resources/images/vs2.png [new file with mode: 0644]
resources/images/vs3.png [new file with mode: 0644]
resources/images/well.png [new file with mode: 0644]
resources/startup.ini [new file with mode: 0644]
resources/test.db [new file with mode: 0644]
resources/wavs/TOD.mp3 [new file with mode: 0644]
resources/wavs/battle1.wav [new file with mode: 0644]
resources/wavs/battle1.wav.asd [new file with mode: 0644]
resources/wavs/breakdown1.wav [new file with mode: 0644]
resources/wavs/breakdown1.wav.asd [new file with mode: 0644]
resources/wavs/chipped.wav [new file with mode: 0644]
resources/wavs/chipped.wav.asd [new file with mode: 0644]
resources/wavs/chipped_dip.wav [new file with mode: 0644]
resources/wavs/chipped_dip.wav.asd [new file with mode: 0644]
resources/wavs/clonks.wav [new file with mode: 0644]
resources/wavs/destructo.wav [new file with mode: 0644]
resources/wavs/good.wav [new file with mode: 0644]
resources/wavs/good.wav.asd [new file with mode: 0644]
resources/wavs/hihat.wav [new file with mode: 0644]
resources/wavs/intro.wav [new file with mode: 0644]
resources/wavs/kick.wav [new file with mode: 0644]
resources/wavs/melody.mp3 [new file with mode: 0644]
resources/wavs/meta19.wav [new file with mode: 0644]
resources/wavs/meta19.wav.asd [new file with mode: 0644]
resources/wavs/mutate.wav [new file with mode: 0644]
resources/wavs/mutate.wav.asd [new file with mode: 0644]
resources/wavs/pianer1.wav [new file with mode: 0644]
resources/wavs/pianer1.wav.asd [new file with mode: 0644]
resources/wavs/rise.wav [new file with mode: 0644]
resources/wavs/rise.wav.asd [new file with mode: 0644]
resources/wavs/rise2.wav [new file with mode: 0644]
resources/wavs/rise3.wav [new file with mode: 0644]
resources/wavs/snare.wav [new file with mode: 0644]
resources/wavs/um_intro.wav [new file with mode: 0644]
resources/wavs/um_main.wav [new file with mode: 0644]
resources/wavs/you_are_gay.mp3 [new file with mode: 0644]
scripts/bplate [new file with mode: 0755]
scripts/build [new file with mode: 0755]
scripts/clear_depot_prep [new file with mode: 0755]
scripts/database [new file with mode: 0755]
scripts/db_clonemon_test [new file with mode: 0755]
scripts/db_players_test [new file with mode: 0755]
scripts/dbconfig [new file with mode: 0755]
scripts/init [new file with mode: 0755]
scripts/man/bplate.1 [new file with mode: 0644]
scripts/mydefaults [new file with mode: 0755]
scripts/pipeline [new file with mode: 0755]
scripts/prepare_for_depot [new file with mode: 0755]
scripts/resetdb [new file with mode: 0755]
scripts/search_lua_files [new file with mode: 0755]
scripts/sourceme [new file with mode: 0755]
scripts/windows_sourceme [new file with mode: 0644]
states/bag/init.lua [new file with mode: 0644]
states/bag/main.lua [new file with mode: 0644]
states/battle/doSelect.lua [new file with mode: 0644]
states/battle/enterBattle.lua [new file with mode: 0644]
states/battle/init.lua [new file with mode: 0644]
states/battle/moveSelect.lua [new file with mode: 0644]
states/choice_select/init.lua [new file with mode: 0644]
states/choice_select/main.lua [new file with mode: 0644]
states/enter_text/init.lua [new file with mode: 0644]
states/enter_text/main.lua [new file with mode: 0644]
states/init.lua [new file with mode: 0644]
states/loadsave/init.lua [new file with mode: 0644]
states/loadsave/main.lua [new file with mode: 0644]
states/mapping/init.lua [new file with mode: 0644]
states/mapping/main.lua [new file with mode: 0644]
states/party/doWhat.lua [new file with mode: 0644]
states/party/init.lua [new file with mode: 0644]
states/party/main.lua [new file with mode: 0644]
states/party/switch.lua [new file with mode: 0644]
states/partybox/init.lua [new file with mode: 0644]
states/partybox/main.lua [new file with mode: 0644]
states/settings/init.lua [new file with mode: 0644]
states/settings/main.lua [new file with mode: 0644]
states/start/init.lua [new file with mode: 0644]
states/start/main.lua [new file with mode: 0644]
states/start_menu/init.lua [new file with mode: 0644]
states/start_menu/main.lua [new file with mode: 0644]
states/world/init.lua [new file with mode: 0644]
states/world/main.lua [new file with mode: 0644]
states/world/option.lua [new file with mode: 0644]
states/world/pause.lua [new file with mode: 0644]
states/world/text.lua [new file with mode: 0644]
steam/ContentBuilder/builder_linux/linux32/crashhandler.so [new file with mode: 0644]
steam/ContentBuilder/builder_linux/linux32/libstdc++.so.6 [new file with mode: 0644]
steam/ContentBuilder/builder_linux/linux32/steamcmd [new file with mode: 0644]
steam/ContentBuilder/builder_linux/linux32/steamerrorreporter [new file with mode: 0644]
steam/ContentBuilder/builder_linux/steamcmd.sh [new file with mode: 0644]
steam/ContentBuilder/builder_osx/crashhandler.dylib [new file with mode: 0644]
steam/ContentBuilder/builder_osx/steamcmd [new file with mode: 0644]
steam/ContentBuilder/builder_osx/steamcmd.sh [new file with mode: 0644]
steam/ContentBuilder/output/2762581_preview.manifest.txt [new file with mode: 0755]
steam/ContentBuilder/output/app_build_2762580.log [new file with mode: 0755]
steam/ContentBuilder/output/depot_build_2762581.log [new file with mode: 0755]
steam/ContentBuilder/output/depot_build_2762581.vdf [new file with mode: 0755]
steam/ContentBuilder/output/depot_build_2762582.log [new file with mode: 0755]
steam/ContentBuilder/output/depot_build_2762582.vdf [new file with mode: 0755]
steam/ContentBuilder/output/depot_build_2762583.log [new file with mode: 0755]
steam/ContentBuilder/output/for build logs and intermediate files.txt [new file with mode: 0644]
steam/ContentBuilder/readme.txt [new file with mode: 0644]
steam/ContentBuilder/run_build.bat [new file with mode: 0644]
steam/ContentBuilder/scripts/app_build_2762580.vdf [new file with mode: 0644]
steam/ContentBuilder/scripts/depot_build_1002.vdf [new file with mode: 0644]
steam/ContentBuilder/scripts/depot_build_2762581.vdf [new file with mode: 0644]
steam/ContentBuilder/scripts/depot_build_2762582.vdf [new file with mode: 0644]
steam/ContentBuilder/scripts/simple_app_build.vdf [new file with mode: 0644]
tests/chunkloader/tst.lua [new file with mode: 0644]
uis/bag.lua [new file with mode: 0644]
uis/battle.lua [new file with mode: 0644]
uis/choice_select.lua [new file with mode: 0644]
uis/enter_text.lua [new file with mode: 0644]
uis/init.lua [new file with mode: 0644]
uis/loadsave.lua [new file with mode: 0644]
uis/mapping.lua [new file with mode: 0644]
uis/party.lua [new file with mode: 0644]
uis/partybox.lua [new file with mode: 0644]
uis/settings.lua [new file with mode: 0644]
uis/start.lua [new file with mode: 0644]
uis/start_menu.lua [new file with mode: 0644]
uis/world.lua [new file with mode: 0644]

diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644 (file)
index 0000000..d159169
--- /dev/null
@@ -0,0 +1,339 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/README.adoc b/README.adoc
new file mode 100644 (file)
index 0000000..de4bf80
--- /dev/null
@@ -0,0 +1,88 @@
+= CLONEMON
+
+Clonemon is a game I am working on that uses my custom game engine called the
+nyquist2DEngine. The source code for the game engine is not included in this
+repository.
+
+== Controls
+
+[%header, cols="1,1"]
+|===
+| key / keycombo  | control
+
+| enter/j         | select
+| cntrl + ~       | enter terminal
+| w               | move up
+| a               | move left
+| s               | move down
+| d               | move right
+| k               | select up
+| h               | select left
+| j               | select down
+| l               | select right
+| esc             | pause
+|===
+
+== Terminal commands
+
+[%header, cols="1,1"]
+|===
+| command              | action
+
+| c.bag()                | change to bag global state
+| c.world()              | chanage to world global state
+| c.enter_text()         | chanage to enter text global state
+| c.start()              | chanage to start global state
+| c.choice_select()      | chanage to choice select global state
+| c.loadsave()           | chanage to loadsave global state
+| c.party()              | chanage to party gobal state
+| c.battle()             | chanage to party gobal state
+| c.setState()           | change to a substate ex. setState(states.battle.moveSelect)
+| lua <command>        | enter custom lua
+|===
+
+== Terminal substates
+
+Every substate only works while running in the correct global state. For
+example any `states.battle` state only works in the battle global state.
+
+[%header, cols="1,4"]
+|===
+| substate                         | action
+
+| states.battle.moveSelect         | pick from your clonemons available moves
+| states.battle.doSelect           | decide what your clonemon will do in battle
+| states.battle.enterBattle        | starts the battle intro
+| states.party.doWhat              | decide what you want to do with choosen clonemon
+| states.party.switch              | switch clonemon to a different party slot
+|===
+
+
+== Installation
+
+Put the binaries create from building the nyquist2DEnine engine or mapeditor in
+the root directory. The "*.so" or ".dll" files created from building the
+nyquist2DEngine extensions in the root of the extensions folder.
+
+
+== Running
+run these commands to initialize the game
+
+----
+./scripts/init
+./scripts/sourceme
+----
+
+you can do 
+
+----
+./n2de_dev
+----
+
+or
+
+----
+./n2de
+----
+
+run run the game
diff --git a/docinfo.conf b/docinfo.conf
new file mode 100644 (file)
index 0000000..57fa5b9
--- /dev/null
@@ -0,0 +1,3 @@
+#!/usr/bin/env bash
+HOSTNAME=nyquistdev.net
+DOCINFODIR=/usr/local/share/readme-to-html
diff --git a/docs/map_chunk_loader.adoc b/docs/map_chunk_loader.adoc
new file mode 100644 (file)
index 0000000..0e7d053
--- /dev/null
@@ -0,0 +1,98 @@
+= Map  Chunk loader
+:docinfo: shared
+:toc: left
+:source-highlighter: pygments
+:incons: font
+:stem:
+
+each outdoor map should be loaded in chunks. The chunks should have a top,
+right, left or bottom attribute that points to another map. The width and height
+should be a square of 480 by 320, that's double the screen size.
+
+map.x > 0::
+    load left map
+
+-map_pos.x > screen width::
+    load right map
+
+map.y > 0::
+    load top map
+
+-map_pos.y > screen height::
+    load bottom map
+
+In order to test this I can make maps that are one solid color but all different
+colors and see if the get loaded
+
+only load the collision for the map you are currently in
+
+once you are within a map, you should load the chunks for that map. make sure
+those chunks include visability for the chunk you were previously in, if you
+would be able to see it
+
+== Map Generation
+
+An array of map ids is called a `map_spec`. Each `map_spec` has specific map ids
+to met a specific criteria for the world. A random map id from a `map_spec` is
+chosen. This id along with position of the next map (`next_pos`) is stored into
+the `maps` array. `next_pos` could have a position above, to the right, below or
+to the left of the current map as long as a map or border does not exist in that
+position. If there is a map or border on the top, left, bottom and right then
+`next_pos` will be nil and the map will be stored in the `blocked` array. The
+`maps` array has elements stored at the index of the position of the map. The
+first map created has a position of zero, if it is not the first map than the
+position is the position of `next_pos` of the previous element in `maps` as long
+as it is not nil, if it is a different position is chosen that is not in the
+`maps` or `blocked` array. This is done a number of times for each `map_spec`.
+The number of times this is done is specified by the `map_spec`'s limit.
+
+
+== Map Position
+The world is an 4x4 grid. Even though this is two demensional each map in the
+world is stored in a one demensional array like so:
+
+[ditaa]
+----
++---+---+---+---+
+|13 |14 |15 |16 |
++---+---+---+---+
+| 9 |10 |11 |12 |
++---+---+---+---+
+| 5 | 6 | 7 | 8 |
++---+---+---+---+
+| 1 | 2 | 3 | 4 |
++---+---+---+---+
+----
+
+So you can find the top element by doing `n + 8`, the bottom element by doing 
+`n - 8`, right element by doing `n + 1` and left element by doing `n - 1`
+
+[ditaa]
+----
+      n + 8
+      +---+
+n - 1 | n | n + 1
+      +---+
+      n - 8
+----
+
+kindof...
+
+This doesn't really work because of the borders of the 8x4 grid. If x was 9 then
+according to this logic the element to the left would be (x - 1), and that is
+incorrect. So you can use a function like this to check borders
+
+[source lua]
+----
+function getSurronding(n, grid)
+    local x = ((n - 1) % grid) + 1
+    local y = math.floor((n - 1) / grid) + 1
+
+    return  {
+        left = x > 1 and n - 1 or nil,
+        right = x < grid and n + 1 or nil,
+        top = n + grid <= grid * grid and n + grid or nil,
+        bottom = n - grid > 0 and n - grid or nil,
+    }
+end
+----
diff --git a/docs/notes.adoc b/docs/notes.adoc
new file mode 100644 (file)
index 0000000..f55e913
--- /dev/null
@@ -0,0 +1,5 @@
+== Run in Linux without steam
+
+----
+wine n2de.exe
+----
diff --git a/docs/todo.adoc b/docs/todo.adoc
new file mode 100644 (file)
index 0000000..da5655d
--- /dev/null
@@ -0,0 +1,42 @@
+== TODO
+
+- [ ] Make private section of ui_mt.lua
+
+    * you can create getter and setter functions to aid with this
+
+    * use const keyword `local a <const> = 12` (need to upgrade to lua5.4)
+
+    * make an https://stackoverflow.com/questions/46977997/lua-metatables-first-parameter-in-index-function#51693548[index function] instead of a table and make tab be the local const
+      variables instead of the _ui.lua_ find
+
+
+- [ ] Make it so you don't need an if else statements when changing states
+
+- [ ] Change option select so it is initialized in the start function
+
+- [x] Set Controlls from database instead
+
+- [ ] Make Party box ui
+
+- [ ] Finish setting up ./resources/images/spritesheet_indoors_1.png
+
+- [ ] Create a better way to change maps
+
+- [ ] Create a path follow for characters. This will automate characters to move
+      along a certain path
+
+- [ ] make map load chunks as you get close to the edge of the map
+
+- [ ] make collision work bettween the current map and the map you are about to
+      enter
+
+- [ ] Make `rng` in layout an array of objects
+
+- [ ] Create a save state for the map layout, maybe in __./resources/data/saves_
+
+== terminal
+
+- [ ] Add command to see hitboxes
+
+- [ ] Add command for no cliping
+
diff --git a/extensions/audio/init.lua b/extensions/audio/init.lua
new file mode 100644 (file)
index 0000000..3457c22
--- /dev/null
@@ -0,0 +1,2 @@
+local libaudio = require("extensions.libaudio")
+return libaudio
diff --git a/extensions/config/init.lua b/extensions/config/init.lua
new file mode 100644 (file)
index 0000000..8446666
--- /dev/null
@@ -0,0 +1,118 @@
+local config = {}
+
+local db_config = Ex.Database.getAll("config")
+
+-- this is the configuration for what is in the database
+config.db = {
+    fullscreen = true;
+    controller = "none";
+    resolution_scale = 5;
+    speed = 4;
+}
+
+-- this is the configuration for what is active and may not be in the database
+-- yet
+config.fullscreen = true
+config.controller = "none"
+config.resolution_scale = 5
+config.speed = 4
+
+if #db_config == 0 then
+    print("creating settings config")
+    if nyq.getGamepads() and (nyq.getGamepads()[1]) then
+        config.controller = nyq.getGamepads()[1]
+        config.db.controller  = config.controller
+    end
+    Ex.Database.insert("config", {
+        controller = config.controller,
+        fullscreen = config.fullscreen and 1 or 0,
+        resolution_scale = config.resolution_scale,
+        speed = config.speed,
+    })
+else
+    for k1, v1 in pairs(db_config) do
+        if k1 == 1 then
+            for k2, v2 in pairs(v1) do
+                if k2 == "fullscreen" then
+                    config[k2] = v2 > 0
+                    config.db[k2] = config[k2]
+                elseif k2 == "resolution_scale" then
+                    config[k2] = math.floor(v2)
+                    config.db[k2] = config[k2]
+                elseif k2 == "controller" then
+                    if nyq.getGamepads() and (not #nyq.getGamepads()[1]) then
+                        config.controller = "none"
+                    else
+                        config[k2] = v2
+                    end
+                    config.db[k2] = v2
+                else
+                    config[k2] = v2
+                    config.db[k2] = v2
+                end
+            end
+        end
+    end
+end
+
+-- config.mappings = {}
+config.mappings = require("extensions.config.mappings")
+local db_gamepad_mappings = Ex.Database.getAll("gamepad_mappings")
+
+if #db_gamepad_mappings == 0 then
+
+    -- database key value pairs NEED to be in the correct order thats why I cannot itterate
+    local mappings = config.mappings.gamepad
+    Ex.Database.insert("gamepad_mappings", {
+        move_north = mappings.move_north.key,
+        move_east = mappings.move_east.key,
+        move_south = mappings.move_south.key,
+        move_west = mappings.move_west.key,
+        move_up = mappings.move_up.key,
+        move_right = mappings.move_right.key,
+        move_down = mappings.move_down.key,
+        move_left = mappings.move_left.key,
+        _select = mappings.select.key,
+        back = mappings.back.key,
+        pause = mappings.pause.key,
+        hotkey = mappings.hotkey.key,
+    })
+else
+    for k, v in pairs(db_gamepad_mappings[1]) do
+        if k == "_select" then
+            k = "select"
+        end
+        config.mappings.gamepad[k].key = v
+    end
+end
+
+local db_keyboard_mappings = Ex.Database.getAll("keyboard_mappings")
+if #db_keyboard_mappings == 0 then
+
+    -- database key value pairs NEED to be in the correct order thats why I cannot itterate
+    local mappings = config.mappings.keyboard
+    Ex.Database.insert("keyboard_mappings", {
+        move_north = mappings.move_north.key,
+        move_east = mappings.move_east.key,
+        move_south = mappings.move_south.key,
+        move_west = mappings.move_west.key,
+        move_up = mappings.move_up.key,
+        move_right = mappings.move_right.key,
+        move_down = mappings.move_down.key,
+        move_left = mappings.move_left.key,
+        _select = mappings.select.key,
+        back = mappings.back.key,
+        pause = mappings.pause.key,
+        hotkey = mappings.hotkey.key,
+    })
+else
+    for k, v in pairs(db_keyboard_mappings[1]) do
+        if k == "_select" then
+            k = "select"
+        end
+        config.mappings.keyboard[k].key = v
+    end
+end
+
+
+return config
diff --git a/extensions/config/mappings/default_gamepad.lua b/extensions/config/mappings/default_gamepad.lua
new file mode 100644 (file)
index 0000000..f2f7d76
--- /dev/null
@@ -0,0 +1,62 @@
+return {
+    move_north =  {
+        key = "dpup";
+        trigger = false;
+        keyrepeat = false;
+    },
+    move_east =  {
+        key = "dpright";
+        trigger = false;
+        keyrepeat = false;
+    },
+    move_south =  {
+        key = "dpdown";
+        trigger = false;
+        keyrepeat = false;
+    },
+    move_west = {
+        key = "dpleft";
+        trigger = false;
+        keyrepeat = false;
+    },
+    move_up =  {
+        key = "dpup";
+        trigger = true;
+        keyrepeat = false;
+    },
+    move_right = {
+        key = "dpright";
+        trigger = true;
+        keyrepeat = false;
+    },
+    move_down = {
+        key = "dpdown";
+        trigger = true;
+        keyrepeat = false;
+    },
+    move_left = {
+        key = "dpleft";
+        trigger = true;
+        keyrepeat = false;
+    },
+    select = {
+        key = "a";
+        trigger = false;
+        keyrepeat = false;
+    },
+    back = {
+        key = "b";
+        trigger = true;
+        keyrepeat = false;
+    },
+    pause = {
+        key = "start";
+        trigger = true;
+        keyrepeat = false;
+    },
+    hotkey = {
+        key = "x";
+        trigger = true;
+        keyrepeat = false;
+    },
+}
diff --git a/extensions/config/mappings/default_keyboard.lua b/extensions/config/mappings/default_keyboard.lua
new file mode 100644 (file)
index 0000000..b80f002
--- /dev/null
@@ -0,0 +1,62 @@
+return {
+    move_north =  {
+        key = "W";
+        trigger = false;
+        keyrepeat = true;
+    },
+    move_east =  {
+        key = "D";
+        trigger = false;
+        keyrepeat = true;
+    },
+    move_south =  {
+        key = "S";
+        trigger = false;
+        keyrepeat = true;
+    },
+    move_west = {
+        key = "A";
+        trigger = false;
+        keyrepeat = true;
+    },
+    move_up =  {
+        key = "Up";
+        trigger = true;
+        keyrepeat = true;
+    },
+    move_right =  {
+        key = "Right";
+        trigger = true;
+        keyrepeat = true;
+    },
+    move_down =  {
+        key = "Down";
+        trigger = true;
+        keyrepeat = true;
+    },
+    move_left = {
+        key = "Left";
+        trigger = true;
+        keyrepeat = true;
+    },
+    select = {
+        key = "Return";
+        trigger = true;
+        keyrepeat = false;
+    },
+    pause = {
+        key = "Escape";
+        trigger = true;
+        keyrepeat = false;
+    },
+    back = {
+        key = "Backspace";
+        trigger = true;
+        keyrepeat = false;
+    },
+    hotkey = {
+        key = "X";
+        trigger = true;
+        keyrepeat = false;
+    },
+}
diff --git a/extensions/config/mappings/init.lua b/extensions/config/mappings/init.lua
new file mode 100644 (file)
index 0000000..58e75a6
--- /dev/null
@@ -0,0 +1,4 @@
+return {
+    gamepad = require("extensions.config.mappings.default_gamepad");
+    keyboard = require("extensions.config.mappings.default_keyboard");
+}
diff --git a/extensions/database/init.lua b/extensions/database/init.lua
new file mode 100644 (file)
index 0000000..e597e62
--- /dev/null
@@ -0,0 +1,9 @@
+local libdatabase = require("extensions.libdatabase")
+libdatabase.schema = require("extensions.database.schema")
+
+libdatabase.init("test.db", libdatabase.schema)
+World = {
+    clonemon_types = libdatabase.getAll("clonemon_types"),
+    clonemon = libdatabase.getAll("clonemon")
+}
+return libdatabase
diff --git a/extensions/database/schema.lua b/extensions/database/schema.lua
new file mode 100644 (file)
index 0000000..0f6e79d
--- /dev/null
@@ -0,0 +1,115 @@
+return {
+    biomes = {
+        name = DB_TEXT_UNIQUE;
+        map_id = DB_INTEGER_UNIQUE;
+        effects = DB_TEXT_UNIQUE;
+    },
+    clonemon_types = {
+        name = DB_TEXT_UNIQUE;
+        ability = DB_TEXT;
+        base_attack = DB_INTEGER;
+        base_hp = DB_INTEGER;
+        base_speed = DB_INTEGER;
+        base_defense = DB_INTEGER;
+        base_special_defense = DB_INTEGER;
+        base_special_attack = DB_INTEGER;
+        image = DB_TEXT;
+    },
+    move_types = {
+        move_id = "moves";
+        name = DB_TEXT_UNIQUE;
+        base_power = DB_INTEGER;
+        base_accuracy = DB_INTEGER;
+        base_pp = DB_INTEGER;
+        base_speed = DB_INTEGER;
+        status_effect = DB_TEXT;
+        image = DB_TEXT;
+    },
+    moves = {
+        move_type_id = "move_types";
+        pp = DB_INTEGER;
+        power = DB_INTEGER;
+        accuracy = DB_INTEGER;
+        speed = DB_INTEGER;
+    },
+    move_types_compare = {
+        move_types = "move_types";
+        weak_id = "move_types";
+        strong_id = "move_types";
+        resistant_id = "move_types";
+    },
+    clonemon_biomes = {
+        clonemon_id = "clonemon",
+        biome_id = "biomes"
+    },
+    clonemon_moves = {
+        clonemon_id = "clonemon";
+        move_id = "moves"
+    },
+    clonemon = {
+        type_id = "clonemon_types";
+        name = DB_TEXT;
+        gender = DB_INTEGER;
+        level = DB_INTEGER;
+        attack = DB_INTEGER;
+        max_hp = DB_INTEGER;
+        remaining_hp = DB_INTEGER;
+        speed = DB_INTEGER;
+        defense = DB_INTEGER;
+        accuracy = DB_INTEGER;
+        special_defense = DB_INTEGER;
+        special_attack = DB_INTEGER;
+        box_number = DB_INTEGER;
+        box_position = DB_INTEGER;
+        spritesheet = DB_TEXT_UNIQUE;
+    },
+    people = {
+        age = DB_INTEGER;
+        name = DB_TEXT;
+        level = DB_INTEGER;
+        spritesheet = DB_TEXT;
+    },
+    clonemon_party = {
+        person_id = "people";
+        clonemon = "clonemon";
+    },
+    players = {
+        uuid = DB_TEXT_UNIQUE;
+        person_id = "people";
+    },
+    config = {
+        controller = DB_TEXT;
+        fullscreen = DB_INTEGER;
+        resolution_scale = DB_INTEGER;
+        speed = DB_INTEGER;
+    },
+    gamepad_mappings = {
+        move_north = DB_TEXT;
+        move_east = DB_TEXT;
+        move_south = DB_TEXT;
+        move_west = DB_TEXT;
+        move_up = DB_TEXT;
+        move_right = DB_TEXT;
+        move_down = DB_TEXT;
+        move_left = DB_TEXT;
+        _select = DB_TEXT;
+        back = DB_TEXT;
+        pause = DB_TEXT;
+        hotkey = DB_TEXT;
+
+    },
+    keyboard_mappings = {
+        move_north = DB_TEXT;
+        move_east = DB_TEXT;
+        move_south = DB_TEXT;
+        move_west = DB_TEXT;
+        move_up = DB_TEXT;
+        move_right = DB_TEXT;
+        move_down = DB_TEXT;
+        move_left = DB_TEXT;
+        _select = DB_TEXT;
+        back = DB_TEXT;
+        pause = DB_TEXT;
+        hotkey = DB_TEXT;
+    }
+}
diff --git a/extensions/images/init.lua b/extensions/images/init.lua
new file mode 100644 (file)
index 0000000..d6f8336
--- /dev/null
@@ -0,0 +1,2 @@
+local libimages = require("extensions.libimages")
+return libimages
diff --git a/extensions/init.lua b/extensions/init.lua
new file mode 100644 (file)
index 0000000..f3a2a14
--- /dev/null
@@ -0,0 +1,13 @@
+Ex = {}
+Ex.Database = require("extensions.database")
+Ex.Audio = require("extensions.audio")
+Ex.Sprites = require("extensions.sprites")
+Ex.Loops = require("extensions.loops")
+Ex.Images = require("extensions.images")
+Ex.Text = require("extensions.text")
+if PRODUCTION then
+    terminal = { commands = require("extensions.terminal.commands") } 
+else
+    Ex.Terminal = require("extensions.terminal")
+end
+Ex.Config = require("extensions.config") -- must be required last
diff --git a/extensions/loops/init.lua b/extensions/loops/init.lua
new file mode 100644 (file)
index 0000000..9a2bb40
--- /dev/null
@@ -0,0 +1,2 @@
+local libloops = require("extensions.libloops")
+return libloops
diff --git a/extensions/metatables/ui.lua b/extensions/metatables/ui.lua
new file mode 100644 (file)
index 0000000..5db1c2d
--- /dev/null
@@ -0,0 +1,658 @@
+-- TODO
+-- make getter and setter functions
+--
+local ui_mt = {}
+ui_mt.scale = 1
+ui_mt.window_size = {w = 0, h = 0}
+ui_mt.background = {
+    position = {x = 0, y = 0},
+    size = {w = 0, h = 0},
+    images = {},
+}
+ui_mt.font_size = nil
+ui_mt.spritesheet = nil
+ui_mt.lines = {}
+
+local menu_items_id = nil
+local background_image = nil
+local select_options = nil
+local select_max = nil
+local option_rect_id = nil
+local spritesheet_id = 0
+local ttf_file = nil
+local sprite_ids = {}
+local image_ids = {}
+local crops = {}
+local animation = {}
+local text = {}
+local notify = {
+    isNotifying = false,
+    start = 0,
+    type = "change",
+    str = "hey",
+    colors = {
+        change = {
+            fg = {r = 255, g = 255, b = 255, a = 255},
+            bg = {r = 0, g = 0, b = 0, a = 255}
+        },
+        warning = {
+            fg = {r = 255, g = 0, b = 0, a = 255},
+            bg = {r = 0, g = 0, b = 0, a = 255}
+        },
+        fg = {r = 255, g = 255, b = 255, a = 255},
+        bg = {r = 0, g = 0, b = 0, a = 255}
+    }
+}
+local optionSelect = {
+    options = nil
+}
+
+function ui_mt:setSize(size)
+    local s = {
+        w = size.w * self.scale,
+        h = size.h * self.scale
+    }
+    return s
+end
+
+function ui_mt:setPosition(pos)
+    local p = {
+        x = pos.x * self.scale,
+        y = pos.y * self.scale,
+    }
+    return p
+end
+
+function ui_mt:scaleRect(rect)
+local r = {
+        x = rect.x * self.scale,
+        y = rect.y * self.scale,
+        w = rect.w * self.scale,
+        h = rect.h * self.scale,
+    }
+    return r
+end
+
+function ui_mt:addCrop(name, crop, size, spritesheet)
+    if not crops[name] then
+        crops[name] = {}
+    end
+    crops[name].crop = crop
+    crops[name].size = size
+    if spritesheet then
+        Ex.Sprites.addCrops(spritesheet, name, 0, {crops[name].crop})
+    else
+        Ex.Sprites.addCrops(spritesheet_id, name, 0, {crops[name].crop})
+    end
+end
+
+function ui_mt:addAnimation(name, id, crops, size)
+    if (not animation[name]) then
+        animation[name] = {}
+    end
+    if (not animation[name]["crops"]) then
+        animation[name]["crops"] = {}
+    end
+    if (not animation[name]["crops"][id]) and crops then
+        animation[name]["crops"][id] = crops
+    end
+    Ex.Sprites.addCrops(spritesheet_id, id, 1, animation[name]["crops"][id])
+    animation[name].size = size
+end
+
+function ui_mt:updateAnimation(name, id, speed, pos)
+    local s = self:setSize(animation[name].size)
+    local s = self:setSize(animation[name].size)
+    local p = self:setPosition(pos)
+    animation[name].frame_number = 
+        Ex.Sprites.animate(spritesheet_id, id, speed, p, s)
+end
+
+function ui_mt:updateCrop(name, pos)
+    local s = self:setSize(crops[name].size)
+    local p = self:setPosition(pos)
+    crops[name].position = pos
+    Ex.Sprites.updateCrop(spritesheet_id, name, 1, p, {size = s})
+end
+
+function ui_mt:updateCrop2(name, id, pos)
+    local s = self:setSize(crops[name].size)
+    local p = {
+        x = pos.x,
+        y = pos.y
+    }
+    crops[name].frame_number = 
+        Ex.Sprites.updateCrop(spritesheet_id, id, 1, p, {size = s})
+end
+
+function ui_mt:addBackgroundImage(name, path)
+    self.background.images[name] = Ex.Images.create(path, 0)
+    table.insert(image_ids, self.background.images[name])
+end
+
+function ui_mt:setBackgroundImage(image)
+    if self.background.images[image] then
+        background_image = self.background.images[image]
+        return true
+    end
+
+    return false
+end
+
+function ui_mt:updateBackground()
+    local s = self:setSize(self.background.size)
+    local p = self:setPosition(self.background.position)
+    Ex.Images.update(background_image, p, s)
+end
+
+function ui_mt:setFont(file, size)
+    ttf_file = file
+    self.font_size = size
+end
+
+function ui_mt:addText(name, id, string, zIndex, fg_color, bg_color)
+    if not text[name] then
+        text[name] = {}
+    end
+
+    text[name].string = string
+
+    if not text[name][id]  then
+        text[name][id] = Ex.Text.create(
+            ttf_file,
+            self.font_size * self.scale,
+            text[name].string,
+            zIndex,
+            fg_color,
+            bg_color
+        )
+    else
+        Ex.Text.change(
+            text[name][id],
+            text[name].string,
+            fg_color,
+            bg_color
+        )
+    end
+    table.insert(self._free_me, {name, id})
+end
+
+function ui_mt:clearText(name, id)
+    if not name then return end
+    text[name][id] = nil
+end
+
+function ui_mt:clearText2(o, id)
+    if not o then return end
+    o[id] = nil
+end
+
+function ui_mt:addText2(o, id, string, zIndex, fg_color, bg_color)
+    if not o[id] then
+        o[id] = Ex.Text.create(
+            ttf_file,
+            self.font_size * self.scale,
+            string,
+            zIndex,
+            fg_color,
+            bg_color
+        )
+    else
+        Ex.Text.change(
+            o[id],
+            string,
+            fg_color,
+            bg_color
+        )
+    end
+    table.insert(self._free_me, {o, id})
+end
+
+function ui_mt:free()
+    for _, v in pairs(self._free_me) do
+        if type(v[1]) == "string" then
+            text[ v[1] ][ v[2] ] = nil
+        elseif type(v[1]) == "table" then
+            -- k[v] = nil
+            v[1][ v[2] ] = nil
+        end
+    end
+
+    Ex.Text.clear()
+
+    if self.freeCallback then
+        self.freeCallback()
+    end
+
+    Ex.Sprites.quit()
+    Ex.Images.free()
+    nyq.world.free(0)
+    nyq.rects.free()
+
+end
+
+function ui_mt:textChange(name, id, str, forground_color, background_color)
+    Ex.Text.change(
+        text[name][id],
+        str,
+        forground_color,
+        background_color
+    )
+end
+
+function ui_mt:textChange2(o, id, str, forground_color, background_color)
+    Ex.Text.change(
+        o[id],
+        str,
+        forground_color,
+        background_color
+    )
+end
+
+function ui_mt:updateText2(o, id, position, offsets)
+    if (not o) then return end
+    if (not o[id]) then return end
+
+    if position.x == "center" then
+        local size = ui:getTextSize(name, id)
+        position.x = (self.window_size.w / 2) - (size.w / 2)
+
+    elseif position.x == "right" then
+        local size = ui:getTextSize(name, id)
+        position.x = self.window_size.w - size.w
+    end
+
+    if position.y == "bottom" then
+        position.y = self.window_size.h - self.font_size
+    end
+
+    if offsets then
+        if (offsets.x) then
+            position.x = position.x + offsets.x
+        end
+        if (offsets.y) then
+            position.y = position.y + offsets.y
+        end
+    end
+
+    local p = self:setPosition(position)
+    Ex.Text.update(o[id], p)
+end
+
+function ui_mt:updateText(name, id, position, offsets)
+    if (not text[name]) then return end
+    if (not text[name][id]) then return end
+
+    if position.x == "center" then
+        local size = ui:getTextSize(name, id)
+        position.x = (self.window_size.w / 2) - (size.w / 2)
+
+    elseif position.x == "right" then
+        local size = ui:getTextSize(name, id)
+        position.x = self.window_size.w - size.w
+    end
+
+    if position.y == "center" then
+        -- TODO
+        -- finish this if :p
+    elseif position.y == "bottom" then
+        position.y = self.window_size.h - self.font_size
+    end
+
+    if offsets then
+        if (offsets.x) then
+            position.x = position.x + offsets.x
+        end
+        if (offsets.y) then
+            position.y = position.y + offsets.y
+        end
+    end
+
+    local p = ui:setPosition(position)
+
+    if (text[name].string) then
+        Ex.Text.update(text[name][id], p)
+    end
+end
+
+function ui_mt:getTextSize(name, id)
+    if (not text[name]) then return end
+    if (not text[name][id]) then return end
+    local size = Ex.Text.getSize(text[name][id])
+    return {
+        w = size.w / self.scale,
+        h = size.h / self.scale,
+    }
+end
+
+function ui_mt:getTextSize2(o, id)
+    if (not o) then return end
+    if (not o[id]) then return end
+    local size = Ex.Text.getSize(o[id])
+    return {
+        w = size.w / self.scale,
+        h = size.h / self.scale,
+    }
+end
+
+function ui_mt:newSprite(file)
+    local id = Ex.Sprites.new(file)
+    table.insert(sprite_ids, id)
+    return id
+end
+
+function ui_mt:spriteAddCrops(id, id2, zIndex, frames)
+    Ex.Sprites.addCrops(id, id2, zIndex, frames)
+end
+
+function ui_mt:spriteUpdateCrop(id, id2, idx, pos, scale)
+    local p = self:setPosition(pos)
+    if scale then
+        local s = self:setSize(scale)
+        Ex.Sprites.updateCrop(id, id2, idx, p, {size = s})
+    else
+        Ex.Sprites.updateCrop(id, id2, idx, p, {
+            scale = {
+                w = self.scale,
+                h = self.scale
+            }
+        })
+    end
+end
+
+function ui_mt:imageCreate(file, zIndex)
+    local id = 0
+    id = Ex.Images.create(file, zIndex)
+    table.insert(image_ids, id)
+    return id
+end
+
+function ui_mt:imageUpdate(id, pos, size)
+    local p = self:setPosition(pos)
+    local s = self:setSize(size)
+    Ex.Images.update(id, p, s)
+end
+
+function ui_mt:_init(spritesheet, window_size, file, font_size, options, 
+                     callback)
+
+    if spritesheet then
+        self.spritesheet = spritesheet
+    end
+
+    if options then
+        if options.scale then
+            self.scale = options.scale
+        end
+        if options.pos then
+            self.pos = options.pos
+        end
+        if options.background_position then
+            self.background.position = options.background_position
+        end
+    end
+
+
+    self:setFont(file, font_size)
+    self.isChangeingInput = false
+    local window_size = {w = 240, h = 160}
+    self.window_size = window_size
+    self.scaled_window_size = {w = window_size.w * self.scale,
+                               h = window_size.h * self.scale}
+    self.background.size = window_size 
+    self._free_me = {}
+    local p = self:setPosition(self.background.position)
+    callback()
+end
+
+function ui_mt:createRect(color, fill, zIndex)
+    return nyq.rects.create(color, fill, zIndex)
+end
+
+function ui_mt:rectUpdate(id, pos, size)
+    local p = self:setPosition(pos)
+    local s = self:setSize(size)
+    nyq.rects.update(id, p, s)
+end
+
+function ui_mt:start()
+    self:addText("notification", "change", "nothing", 5,
+        notify.colors.change.fg,
+        notify.colors.change.bg
+    )
+    self:addText("notification", "warning", "nothing", 5,
+        notify.colors.warning.fg,
+        notify.colors.warning.bg
+    )
+
+    if self.spritesheet then
+        spritesheet_id = Ex.Sprites.new(self.spritesheet)
+    end
+
+    for i = 1, 6 do
+        self:addText("options", i , "yes", 5,
+            {r = 0, g = 0, b = 0, a = 255},
+            {r = 0, g = 0, b = 0, a = 0}
+        )
+    end
+    option_rect_id  = self:createRect({r = 225, g = 255, b = 255, a = 200}, true, 4)
+    menu_items_id = self:newSprite("menu_items.png")
+    self:spriteAddCrops(menu_items_id, "selection arrow", 6, {
+        {
+            x = 7,
+            y = 0,
+            w = 7,
+            h = 7
+        }
+    })
+    self:spriteAddCrops(menu_items_id, "transparent_arrow_left", 6, {
+        {
+            x = 14,
+            y = 0,
+            w = 7,
+            h = 7
+        }
+    })
+    self:spriteAddCrops(menu_items_id, "transparent_arrow_right", 6, {
+        {
+            x = 21,
+            y = 0,
+            w = 7,
+            h = 7
+        }
+    })
+    self:spriteAddCrops(menu_items_id, "up arrow", 0, {
+        {
+            x = 28,
+            y = 0,
+            w = 15,
+            h = 15
+        }
+    })
+    self:spriteAddCrops(menu_items_id, "down arrow", 0, {
+        {
+            x = 43,
+            y = 0,
+            w = 15,
+            h = 15
+        }
+    })
+    if self.startCallback then
+        self:startCallback()
+    end
+end
+
+function ui_mt:linesCreate(name, count, fg_color, bg_color)
+    self.lines[name] = {}
+    self.lines[name].line_count = count
+    self.lines[name].line_ids = {}
+    self.lines[name].page_idx = 0
+    self.lines[name].pages = 0
+    self.lines[name].fg_color = fg_color
+    self.lines[name].bg_color = bg_color
+
+    for i = 1, count do
+        self:addText2(
+            self.lines[name].line_ids,
+            i,
+            "lines", -- cannot leave blank
+            5,
+            self.lines[name].fg_color,
+            self.lines[name].bg_color
+        )
+    end
+end
+
+function ui_mt:optionSelectInit(options)
+    optionSelect.options = options
+    selection_max = #optionSelect.options
+    select_options = {}
+
+    local rev = table.Reverse(optionSelect.options)
+
+    for i, option in pairs(rev) do
+        self:textChange("options", option.id, option.text,
+            {r = 0, g = 0, b = 0, a = 255},
+            {r = 0, g = 0, b = 0, a = 0}
+        )
+    end
+    return selection_max
+end
+
+function ui_mt:optionSelectUpdate(start_pos, selected)
+    local height = 1
+    local font_offset = self.font_size + 1
+    local max_width = {
+        len = 0,
+        id = 0
+    }
+
+    for i, option in pairs(optionSelect.options) do
+        select_options[option] = i;
+        local len = string.len(option)
+        if len > max_width.len then
+            max_width.len = len
+            max_width.id = i
+        end
+    end
+
+    local size = self:getTextSize("options", max_width.id)
+    local rect_pos = {x = start_pos.x - size.w - 12, y = start_pos.y + 8}
+    local rev = table.Reverse(optionSelect.options)
+
+    for i, option in pairs(rev) do
+        local y_offset = (i - 1) * font_offset
+        height = height + font_offset
+        rect_pos.y = rect_pos.y - font_offset
+        self:updateText("options", option.id,  {
+            -- x = 238 - size.w,
+            x = start_pos.x- size.w,
+            y = start_pos.y - y_offset
+        })
+    end
+
+    self:rectUpdate(option_rect_id,
+    rect_pos,
+    {
+        w = size.w + 14,
+        h = height + 2
+    })
+    self:spriteUpdateCrop(menu_items_id, "selection arrow", 1, {
+        x = start_pos.x - size.w - 10,
+        y = (start_pos.y + 3 + font_offset - height) + 
+            (font_offset * (selected - 1))
+    })
+end
+
+function ui_mt:getSelectOptions()
+    return select_options
+end
+
+function ui_mt:updateMenuItem(id2, idx, pos, scale)
+    self:spriteUpdateCrop(menu_items_id, id2, idx, pos, scale)
+end
+
+function ui_mt:linesDraw(name, text, len, position)
+    local lines = string.WordWrap(text, len)
+    self.lines[name].pages = math.ceil(#lines / self.lines[name].line_count)
+    local max = #lines
+    if max > self.lines[name].line_count then max = self.lines[name].line_count end
+    for i = 1, max do
+        if not self.lines[i + (self.lines[name].page_idx * self.lines[name].line_count)] then
+            return true
+        end
+        local y = position.y + ((i - 1) * (self.font_size + 1))
+        self:textChange2(self.lines[name].line_ids, i, 
+                        self.lines[i + (self.lines[name].page_idx * 
+                        self.lines[name].line_count)], self.lines[name].fg_color,
+                        self.lines[name].bg_color)
+
+        self:updateText2(self.lines[name].line_ids, i, {
+            x = position.x,
+            y = y
+        })
+    end
+    return false
+end
+
+function ui_mt:notifySet(type, str)
+    self:textChange("notification", type, str, notify.colors[type].fg,
+                    notify.colors[type].bg)
+    notify.start = nyq.getTicks()
+    notify.str = str
+    notify.type = type
+    notify.fg = Copy.shallow_copy(notify.colors[type].fg)
+    notify.bg = Copy.shallow_copy(notify.colors[type].bg)
+    self.isNotifying = true
+
+end
+
+function ui_mt:notifyUpdate()
+    if not self.isNotifying then return end
+
+    if (nyq.getTicks() - notify.start >= 3000) then
+        notify.isNotifying = false
+        return
+    end
+
+    local size = assert(self:getTextSize("notification", notify.type))
+    if notify.bg.a >= 0 then
+        notify.bg.a = notify.bg.a - 1.3
+    end
+    if notify.fg.a >= 0 then
+        notify.fg.a = notify.fg.a - 1.3
+    end
+    self:textChange("notification", notify.type, notify.str,
+                    notify.fg, notify.bg)
+
+    local pos = {
+        x = "right",
+        y = "bottom"
+    }
+
+    self:updateText("notification", notify.type, pos, {x = -2, y = -2})
+end
+
+function assign(name, t1)
+    local mt <const> = Copy.deepcopy(ui_mt)
+    for k,v in pairs(t1) do
+        if mt[k] then
+            print(string.format("%s ui: '%s' is already assigned", name,  k))
+            os.exit(1)
+        end
+    end
+    return setmetatable(t1, {
+        __index = function(table, key)
+            return mt[key]
+        end,
+        __newindex = function(table, key, value)
+            if mt[key] then
+                print(string.format("%s ui: '%s' is private", name, key))
+                os.exit(2)
+            end
+            mt[key] = value
+        end
+    }), mt
+end
+
+return assign
diff --git a/extensions/sprites/init.lua b/extensions/sprites/init.lua
new file mode 100644 (file)
index 0000000..5b0ee78
--- /dev/null
@@ -0,0 +1,2 @@
+local libsprites = require("extensions.libsprites")
+return libsprites
diff --git a/extensions/terminal/commands.lua b/extensions/terminal/commands.lua
new file mode 100644 (file)
index 0000000..5afedab
--- /dev/null
@@ -0,0 +1,173 @@
+return {
+    setState = function(s)
+        local found = false
+        for k1, v1 in pairs(states) do
+            for k2, v2 in pairs(v1) do
+                if states[k1][k2] == state then
+                    state = states[k1][s]
+                    found = true
+                end
+            end
+        end
+        if s or found then
+            Ex.Terminal.message("setting state")
+        else
+            Ex.Terminal.error("could not set state")
+        end
+    end,
+    start = function()
+        states.start.main:reset()
+        -- temps.state = states.start.main
+        state = states.start.main
+        temps.ui = uis.start
+        -- nyq.audio.play("intro")
+    end,
+    world = function(world_id)
+        states.world.main:reset()
+        local menu_items = {
+            [1] = { name = "Map", },
+            [2] = { name = "Clonemon", },
+            [3] = { name = "bag", },
+            [4] = { name = "Player", },
+            [5] = { name = "Save", },
+            [6] = { name = "Settings", },
+            [7] = { name = "Quit", }
+        }
+        params = {
+            menu_items = menu_items,
+            world_id = world_id
+        }
+        temps.state = states.world
+        temps.ui = uis.world
+    end,
+    battle = function()
+        -- states.battle.intro:reset()
+        params = {
+            -- entry = "test",
+            -- moves = moves.charzard,
+            rivals_pokemon = {
+                [1] = {
+                    name = "meowth",
+                },
+            },
+            my_pokemon = {
+                name = "charzard",
+                moves = moves.charzard,
+                level = 100,
+            },
+            player = {
+                name = "nyquist"
+            }
+        }
+        uis.world.paused = false
+        state = states.battle.enterBattle
+        temps.ui = uis.battle
+    end,
+    enter_text = function()
+        params = {
+            character_limit = 18,
+            title = "enter name: ",
+            sprite = "axolotl.png"
+        }
+        states.enter_text.main:reset()
+        -- temps.state = states.enter_text.main
+        state = states.enter_text.main
+        temps.ui = uis.enter_text
+    end,
+    choice_select = function()
+        params = {
+            sprite = "choice_select_test_one.png",
+            count = 2
+            -- sprite = "choice_select_test_two.png",
+            -- count = 3
+        }
+        states.choice_select.main:reset()
+        -- temps.state = states.choice_select.main
+        state = states.choice_select.main
+        temps.ui = uis.choice_select
+    end,
+    bag = function()
+        states.bag.main:reset()
+        state = states.bag.main
+        temps.ui = uis.bag
+        params = {
+            items = {
+                [1] = {
+                    name = "book",
+                    description = "can read it",
+                    image = "",
+                    quantity = 1
+                },
+                [2] = {
+                    name = "cup",
+                    description = "drink things",
+                    image = "",
+                    quantity = 2
+                },
+                [3] = {
+                    name = "pencil",
+                    description = "write things",
+                    image = "",
+                    quantity = 3
+                }
+            },
+            berries = {
+                [1] = {
+                    name = "blueberry",
+                    description = "improves stats",
+                    image = "",
+                    quantity = 1
+                },
+                [2] = {
+                    name = "raseberry",
+                    description = "raises defense stat",
+                    image = "",
+                    quantity = 2
+                },
+                [3] = {
+                    name = "blackberry",
+                    description = "clears status effects",
+                    image = "",
+                    quantity = 3
+                }
+            },
+            cloneballs = {
+                [1] = {
+                    name = "ULTRA BALL",
+                    description = "A better Ball with a higher catch rate than a Great Ball",
+                    image = "",
+                    quantity = 1
+                },
+                [2] = {
+                    name = "NET BALL",
+                    description = "A BALL that works on WATER- and BUG- type Clonemon",
+                    image = "",
+                    quantity = 2
+                },
+            }
+        }
+    end,
+    party = function()
+        states.party.main:reset()
+        params = {
+            my_clonemon = my_clonemon
+        }
+        state = states.party.main
+        temps.ui = uis.party
+    end,
+    start_menu = function()
+        states.start_menu.main:reset()
+        state = states.start_menu.main
+        temps.ui = uis.start_menu
+    end,
+    settings = function()
+        states.settings.main:reset()
+        state = states.settings.main
+        temps.ui = uis.settings
+    end,
+    partybox = function()
+        states.partybox.main:reset()
+        state = states.partybox.main
+        temps.ui = uis.partybox
+    end
+}
diff --git a/extensions/terminal/init.lua b/extensions/terminal/init.lua
new file mode 100644 (file)
index 0000000..bd1a527
--- /dev/null
@@ -0,0 +1,2 @@
+local libterminal = require("extensions.libterminal")
+return libterminal
diff --git a/extensions/text/init.lua b/extensions/text/init.lua
new file mode 100644 (file)
index 0000000..ef9ed9c
--- /dev/null
@@ -0,0 +1,2 @@
+local libtext = require("extensions.libtext")
+return libtext
diff --git a/init.lua b/init.lua
new file mode 100644 (file)
index 0000000..8fd2b1c
--- /dev/null
+++ b/init.lua
@@ -0,0 +1,254 @@
+Copy = require("modules/copy")
+Find = require("modules/find")
+State = require("modules/state")
+Collection = require("modules/collection")
+world = require("modules.world")
+require("modules/string")
+require("modules/table")
+require("extensions")
+require("./uis")
+require("./states")
+
+state_collection = Collection:new()
+ui_collection = Collection:new()
+params_collection = Collection:new()
+params = {}
+
+function Push_state()
+    state_collection:push(state)
+    ui_collection:push(ui)
+    params_collection:push(params)
+end
+
+function Pop_state()
+    if not (state_collection.size > 0) then return end
+    state = state_collection:pop()
+    temps.ui = ui_collection:pop()
+    params = params_collection:pop()
+end
+
+
+unscaled_window_size = {w = 240, h = 160}
+window_size = {w = unscaled_window_size.w * Ex.Config.resolution_scale, h = unscaled_window_size.h * Ex.Config.resolution_scale}
+
+Speed_options = {
+        [1] = .25,
+        [2] = .5,
+        [3] = .75,
+        [4] =  1,
+        [5] = 1.25,
+        [6] = 1.5,
+        [7] = 1.75,
+        [8] = 2,
+        [9] = 2.5,
+        [10] = 2.75,
+        [11] = 3,
+}
+
+nyq.init(
+    "clonemon",
+    {x = 400, y = 100},
+    window_size,
+    {
+        -- frame_rate = 60 * (1 / Ex.Config.db.speed),
+        -- frame_rate = 60 * (1 / Speed_options[Ex.Config.db.speed]),
+        frame_rate = 60  / Speed_options[Ex.Config.db.speed],
+        controls = {
+            [1] = Ex.Config.mappings
+        },
+        fullscreen = Ex.Config.fullscreen,
+        assign_controllers = {
+            [1] = {controller = Ex.Config.controller, id = 0},
+        }
+    }
+)
+
+uis.start:init(unscaled_window_size, {scale = Ex.Config.resolution_scale})
+uis.world:init("test", "spritesheet_indoors_1.png", unscaled_window_size, {scale = Ex.Config.resolution_scale})
+uis.battle:init("clonemon_battle_ui.png", unscaled_window_size, {scale = Ex.Config.resolution_scale})
+uis.loadsave:init("loadsave.png", unscaled_window_size, {scale = Ex.Config.resolution_scale})
+uis.enter_text:init(unscaled_window_size, {scale = Ex.Config.resolution_scale})
+uis.choice_select:init(unscaled_window_size, {scale = Ex.Config.resolution_scale})
+uis.bag:init(unscaled_window_size, {scale = Ex.Config.resolution_scale})
+uis.party:init(unscaled_window_size, {scale = Ex.Config.resolution_scale})
+uis.start_menu:init(unscaled_window_size, {scale = Ex.Config.resolution_scale})
+uis.settings:init(unscaled_window_size, {scale = Ex.Config.resolution_scale})
+uis.mapping:init(unscaled_window_size, {scale = Ex.Config.resolution_scale})
+uis.partybox:init("spritesheet_partybox.png", unscaled_window_size, {scale = Ex.Config.resolution_scale})
+
+-- selected = 1
+
+temps = {
+    ui = nil
+}
+moves = {
+    charzard = {
+        [1] = {name = "kick", pp = {remaining = 12, total = 50}, type = "fire"},
+        [2] = {name= "punch", pp = {remaining = 15, total = 20}, type = "physical"},
+        [3] = {name= "slash", pp = {remaining = 15, total = 40}, type = "metal"},
+        [4] = {name= "fly", pp = {remaining = 15, total = 10}, type = "flying"},
+    },
+    pikachu = {
+        [1] = {name = "sleep", pp = {remaining = 12, total = 50},
+
+               type = "psychic"},
+        [2] = {name= "static", pp = {remaining = 15, total = 20},
+               type = "electric"},
+        [3] = {name= "jump", pp = {remaining = 15, total = 40},
+               type = "flying"},
+        [4] = {name= "kick", pp = {remaining = 15, total = 10},
+                   type = "physical"},
+    }
+}
+
+my_clonemon = {
+    [1] = {
+        name = "Charzard",
+        moves = moves.charzard,
+        max_hp = 100,
+        hp = 50,
+        level = 100,
+    },
+    [2] = {
+        name = "Pikachu",
+        moves = moves.charzard,
+        max_hp = 50,
+        hp = 10,
+        level = 30,
+    },
+    [3] = {
+        name = "um",
+        moves = moves.charzard,
+        max_hp = 50,
+        hp = 10,
+        level = 30,
+    },
+    [4] = {
+        name = "Meowth",
+        moves = moves.charzard,
+        max_hp = 90,
+        hp = 50,
+        level = 30,
+    },
+    [5] = {
+        name = "Thing",
+        moves = moves.charzard,
+        max_hp = 90,
+        hp = 50,
+        level = 30,
+    },
+    [6] = {
+        name = "not thing",
+        moves = moves.charzard,
+        max_hp = 90,
+        hp = 50,
+        level = 30,
+    },
+}
+
+
+temps.ui = uis.start
+
+uis.world.ai:setPlayerPosition({x = 0 , y = 0})
+state = states.start.main
+
+local padding = 11
+local padding_top_and_bottom = 8
+Ex.Loops.init()
+local start = true
+
+local loop_id = Ex.Loops.add(60)
+local test_text = [[hello there! this is just a lot of text just for the heck of it I hope it doesn't annoy you at all, it is just what happens when you have a lot of text. Isn't this game really cool! Can't believe that everything seems to be working so smoothly. What is your name? oh cool. that is a nice name. hope that you can continue your adventure. What in the world is this? That is not normal though. ahahahah.]]
+ c = require("extensions.terminal.commands")
+while not nyq.quit do
+    Ex.Loops.loopStart(loop_id)
+
+    if temps.ui then
+
+        if ui and ui.free then
+            ui:free()
+        end
+
+        temps.ui:start(params)
+
+        ui = temps.ui
+
+        temps.ui = nil
+    end
+    if state then
+        state()
+    end
+    if not start then
+        if ((nyq.getGamepads() == nil) or (nyq.getGamepads()[1] == nil)) and (Ex.Config.db.controller ~= "none") then
+            Ex.Config.controller = "none"
+            nyq.controllerChange(0, "none");
+        end
+
+        if
+            (Ex.Config.controller == "none") and
+            (Ex.Config.db.controller ~= "none") and
+            (nyq.getGamepads() ~= nil) and
+            (nyq.getGamepads()[1] ~= nil)
+        then
+            Ex.Config.controller = Ex.Config.db.controller
+            nyq.controllerChange(0, Ex.Config.db.controller);
+        end
+
+        if
+            (Ex.Config.controller ~= "none") and
+            (Ex.Config.db.controller == "none")
+        then
+            Ex.Config.controller = "none"
+            nyq.controllerChange(0, "none");
+        end
+
+        if not ui.isChangeingInput then
+            nyq.controlsUpdate(0)
+        end
+    end
+    nyq.clear({r = 0, g = 0, b = 0, a = 255})
+    if ui == uis.battle then
+            ui:updateBackground()
+            ui:updateMyHealth()
+
+        if (state == states.battle.enterBattle) then
+            ui:updateNarration("enter_battle")
+        elseif (state == states.battle.doSelect) then
+            -- ui:updateDo(selected)
+            ui:updateDo()
+        elseif (state == states.battle.moveSelect) then
+            -- ui:updateMoveSelect(selected)
+            ui:updateMoveSelect()
+        end
+
+    elseif ui == uis.world then
+        ui:worldUpdate()
+
+        if state == states.world.option then
+            ui:textUpdate(test_text)
+            ui:selectUpdate({"yes", "no"})
+        end
+        if state == states.world.pause then
+            ui:pauseUpdate()
+        elseif state == states.world.text then
+            ui:textUpdate(test_text)
+        end
+
+    elseif ui == uis.start then
+        start = uis.start:update()
+    elseif ui == uis.party then
+        if state == states.party.main then
+            ui:partyUpdate()
+        elseif state == states.party.doWhat then
+            ui:doWhatUpdate()
+        elseif state == states.party.switch then
+            ui:switchUpdate()
+        end
+    else
+        ui:update()
+    end
+
+    nyq.draw()
+    Ex.Loops.loopEnd(loop_id)
+ end
+
diff --git a/map_configs/controls/controls.lua b/map_configs/controls/controls.lua
new file mode 100644 (file)
index 0000000..16ab3a0
--- /dev/null
@@ -0,0 +1,21 @@
+return {
+    zoom_in = "I",
+    zoom_out = "O",
+    move_left = "A",
+    move_right = "D",
+    move_up = "W",
+    move_down = "S",
+    save = "LCTRL S",
+    toggle_info = "C",
+    add_object = "LALT O",
+    toggle_object_select = "LSHIFT Tab",
+    next = "N",
+    previous = "P",
+    -- any popup can be toggled to fullscreen
+    delete = "Delete",
+    toggle_fullscreen = "LSHIFT Return",
+    position_reset = "R",
+    mode_place = "1",
+    mode_select = "2",
+    mode_move = "3"
+}
diff --git a/map_configs/crops/indoor.lua b/map_configs/crops/indoor.lua
new file mode 100644 (file)
index 0000000..fa0156f
--- /dev/null
@@ -0,0 +1,175 @@
+return {
+    chest = {
+        crops = {
+            [1] = {x = 5, y = 4, w = 24, h = 18},
+        },
+        -- z and y of hit box are reltitive to crop x and y
+        hitbox = {x = 0, y = 6, w = 24, h = 8},
+        is_collidable = true,
+        is_visable = true,
+    },
+    nightstand = {
+        crops = {
+            [1] = {x = 102, y = 145, w = 16, h = 26},
+        },
+        -- z and y of hit box are reltitive to crop x and y
+        hitbox = {x = 0, y = 0, w = 16, h = 24},
+        is_collidable = true,
+        is_visable = true,
+    },
+    recliner = {
+        crops = {
+            [1] = {x = 35, y = 2, w = 24, h = 25},
+        },
+        -- z and y of hit box are reltitive to crop x and y
+        hitbox = {x = 0, y = 0, w = 24, h = 16},
+        is_collidable = true,
+        is_visable = true,
+    },
+    couch_forward = {
+        crops = {
+            [1] = {x = 62, y = 2, w = 32, h = 25},
+        },
+        -- z and y of hit box are reltitive to crop x and y
+        hitbox = {x = 0, y = 12, w = 28, h = 9},
+        is_collidable = true,
+        is_visable = true,
+    },
+    wood_flooring = {
+        crops = {
+            [1] = {x = 87, y = 107, w = 32, h = 16},
+        },
+        -- z and y of hit boIdead ks TF2 x are reltitive to crop x and y
+        hitbox = {x = 0, y = 0, w = 0, h = 0},
+        is_collidable = false,
+        is_visable = true,
+    },
+    rug = {
+        crops = {
+            [1] = {x = 0, y = 197, w = 48, h = 9},
+        },
+        -- z and y of hit box are reltitive to crop x and y
+        hitbox = {x = 0, y = 0, w = 48, h = 9},
+        is_collidable = false,
+        is_visable = true,
+    },
+    fridge = {
+        crops = {
+            [1] = {x = 0, y = 206, w = 32, h = 50},
+        },
+        -- z and y of hit box are reltitive to crop x and y
+        hitbox = {x = 0, y = 0, w = 32, h = 40},
+        is_collidable = true,
+        is_visable = true,
+    },
+    couch_side = {
+        crops = {
+            [1] = {x = 105, y = 23, w = 16, h = 49},
+        },
+        -- z and y of hit box are reltitive to crop x and y
+        hitbox = {x = 0, y = 14, w = 16, h = 22},
+        is_collidable = true,
+        is_visable = true,
+    },
+    flower_pot = {
+        crops = {
+            [1] = {x = 107, y = 4, w = 8, h = 17},
+        },
+        -- z and y of hit box are reltitive to crop x and y
+        -- hitbox = {x = 0, y =0, w = 8, h = 17},
+        hitbox = {x = 0, y = 12, w = 8, h = 5},
+        is_collidable = true,
+        is_visable = true,
+    },
+    oven = {
+        crops = {
+            [1] = {x = 3, y = 25, w = 24, h = 34},
+        },
+        -- z and y of hit box are reltitive to crop x and y
+        hitbox = {x = 0, y = 0, w = 24, h = 32},
+        is_collidable = true,
+        is_visable = true,
+    },
+    microwave = {
+        crops = {
+            [1] = {x = 43, y = 38, w = 32, h = 18},
+        },
+        -- z and y of hit box are reltitive to crop x and y
+        hitbox = {x = 0, y = 0, w = 32, h = 16},
+        is_collidable = true,
+        is_visable = true,
+    },
+    kitchen_table = {
+        crops = {
+            [1] = {x = 4, y = 75, w = 56, h = 26},
+        },
+        -- z and y of hit box are reltitive to crop x and y
+        -- hitbox = {x = 0, y = 8, w = 56, h = 12},
+        hitbox = {x = 0, y = 4, w = 56, h = 14},
+        is_collidable = true,
+        is_visable = true,
+    },
+    kitchen_chair = {
+        crops = {
+            [1] = {x = 68, y = 56, w = 16, h = 42},
+        },
+        -- z and y of hit box are reltitive to crop x and y
+        hitbox = {x = 0, y = 23, w = 18, h = 8},
+        is_collidable = true,
+        is_visable = true,
+    },
+    pillow = {
+        crops = {
+            [1] = {x = 92, y = 79, w = 32, h = 18},
+        },
+        -- z and y of hit box are reltitive to crop x and y
+        hitbox = {x = 0, y = 0, w = 0, h = 0},
+        is_collidable = false,
+        is_visable = true,
+    },
+    pc = {
+        crops = {
+            [1] = {x = 5, y = 109, w = 32, h = 32},
+        },
+        -- z and y of hit box are reltitive to crop x and y
+        hitbox = {x = 0, y = 0, w = 32, h = 32},
+        is_collidable = false,
+        is_visable = true,
+    },
+    framed_photo = {
+        crops = {
+            [1] = {x = 50, y = 109, w = 32, h = 20},
+        },
+        -- z and y of hit box are reltitive to crop x and y
+        hitbox = {x = 0, y = 0, w = 0, h = 0},
+        is_collidable = false,
+        is_visable = true,
+    },
+    bed = {
+        crops = {
+            [1] = {x = 0, y = 146, w = 24, h = 51},
+        },
+        -- z and y of hit box are reltitive to crop x and y
+        hitbox = {x = 0, y = 10, w = 24, h = 32},
+        is_collidable = true,
+        is_visable = true,
+    },
+    bookshelf = {
+        crops = {
+            [1] = {x = 24, y = 146, w = 40, h = 33},
+        },
+        -- z and y of hit box are reltitive to crop x and y
+        hitbox = {x = 0, y = 8, w = 40, h = 20},
+        is_collidable = true,
+        is_visable = true,
+    },
+    desk = {
+        crops = {
+            [1] = {x = 43, y = 225, w = 48, h = 26},
+        },
+        -- z and y of hit box are reltitive to crop x and y
+        hitbox = {x = 0, y = 0, w = 32, h = 12},
+        is_collidable = true,
+        is_visable = true,
+    },
+}
diff --git a/map_configs/crops/outdoor.lua b/map_configs/crops/outdoor.lua
new file mode 100644 (file)
index 0000000..d76d45b
--- /dev/null
@@ -0,0 +1,82 @@
+return {
+    house1 = {
+        crops = {
+            [1] = {x = 0, y = 2, w = 98, h = 111},
+        },
+        -- z and y of hit box are reltitive to crop x and y
+        hitbox = {x = 0, y = 43, w = 98, h = 37},
+        is_collidable = true,
+        is_visable = true,
+    },
+    house2 = {
+        crops = {
+            [1] = {x = 100, y = 0, w = 115, h = 98},
+        },
+        -- z and y of hit box are reltitive to crop x and y
+        hitbox = {x = 0, y = 35, w = 115, h = 45},
+        is_collidable = true,
+        is_visable = true,
+    },
+    house3 = {
+        crops = {
+            [1] = {x = 172, y = 99, w = 140, h = 108},
+        },
+        -- z and y of hit box are reltitive to crop x and y
+        hitbox = {x = 3, y = 11, w = 134, h = 72},
+        is_collidable = true,
+        is_visable = true,
+    },
+    house4 = {
+        crops = {
+            [1] = {x = 0, y = 113, w = 150, h = 103},
+        },
+        -- z and y of hit box are reltitive to crop x and y
+        hitbox = {x = 0, y = 30, w = 150, h = 57},
+        is_collidable = true,
+        is_visable = true,
+    },
+    shack = {
+        crops = {
+            [1] = {x = 150, y = 149, w = 22, h = 36},
+        },
+        -- z and y of hit box are reltitive to crop x and y
+        hitbox = {x = 0, y = 2, w = 22, h = 14},
+        is_collidable = true,
+        is_visable = true,
+    },
+    well = {
+        crops = {
+            [1] = {x = 320, y = 0, w = 67, h = 48},
+        },
+        -- z and y of hit box are reltitive to crop x and y
+        hitbox = {x = 0, y = 20, w = 67, h = 15},
+        is_collidable = true,
+        is_visable = true,
+    },
+    tree_1 = {
+        crops = {
+            [1] = {x = 393, y = 0, w = 61, h = 106},
+        },
+        -- z and y of hit box are reltitive to crop x and y
+        hitbox = {x = 16, y = 90, w = 23, h = 12},
+        is_collidable = true,
+        is_visable = true,
+    },
+    tree_2 = {
+        crops = {
+            [1] = {x = 463, y = 0, w = 106, h = 121},
+        },
+        -- z and y of hit box are reltitive to crop x and y
+        hitbox = {x = 42, y = 96, w = 31, h = 10},
+        is_collidable = true,
+        is_visable = true,
+    },
+    rng_hospital = {
+        crops = {
+            [1] = {x = 319, y = 106, w = 119, h = 113}
+        },
+        hitbox = {x = 0, y = 0, w = 119, h = 113},
+        is_collidable = true,
+        is_visable = false
+    }
+}
diff --git a/map_configs/indoor1.lua b/map_configs/indoor1.lua
new file mode 100644 (file)
index 0000000..58a4a79
--- /dev/null
@@ -0,0 +1,5 @@
+spritesheet = "spritesheet_indoors_1.png"
+world_name = "test"
+keys = require("map_configs.controls.controls")
+map = { grid = 8, width = 240 * 2, height = 88 * 2 }
+objects = require("map_configs.crops.indoor")
diff --git a/map_configs/outdoor1.lua b/map_configs/outdoor1.lua
new file mode 100644 (file)
index 0000000..69fe49f
--- /dev/null
@@ -0,0 +1,5 @@
+spritesheet = "spritesheet_outdoor_1.png"
+world_name = "test"
+keys = require("map_configs.controls.controls")
+map = {grid = 8, width = 480 * 2, height = 320 * 2}
+objects = require("map_configs.crops.outdoor")
diff --git a/mapeditor b/mapeditor
new file mode 100755 (executable)
index 0000000..cf69278
Binary files /dev/null and b/mapeditor differ
diff --git a/modules/ai.lua b/modules/ai.lua
new file mode 100644 (file)
index 0000000..c8fbf94
--- /dev/null
@@ -0,0 +1,132 @@
+local ai_mt = {}
+local objectCollision = nil
+local colliding_id = nil
+local noClip = false
+
+function ai_mt:travel(direction)
+    if not objectCollision then return end
+    self.entity.idle = "idle_" .. direction
+    self.entity.move = "walk_" .. direction
+
+    local checkCollision = nil
+    local distance = (self.entity.speed * nyq.deltaTime)
+
+    local a, b = 0, 0
+    local t = nil
+    if direction == "north" then
+        collisionCheck = objectCollision.hit_bottom
+        a = distance 
+        b = distance
+        t = "y"
+    elseif direction == "south" then
+        collisionCheck = objectCollision.hit_top
+        a = -distance 
+        b = -distance
+        t = "y"
+    elseif direction == "east" then
+        collisionCheck = objectCollision.hit_left
+        a = distance 
+        b = -distance
+        t = "x"
+    elseif direction == "west" then
+        collisionCheck = objectCollision.hit_right
+        a = -distance 
+        b = distance
+        t = "x"
+    end
+
+    if 
+        objectCollision.is_collidable and 
+        collisionCheck and
+        (not noClip) and
+        (not objectCollision.type:find("^rng_"))
+    then
+        return
+    end
+
+    self.entity.position[t] = self.entity.position[t] + a
+    self.world.position[t] = self.world.position[t] + b
+end
+
+function ai_mt:getPlayerPosition()
+    return {
+        x = -((self.world.position.x)  / (1 / self.world.scaler)) +
+               self.entity.screen_position.x,
+        y = -((self.world.position.y) /  (1 / self.world.scaler)) +
+               self.entity.screen_position.y
+    }
+end
+
+function ai_mt:setPlayerPosition(position)
+    self.world.position.x = -(position.x - self.entity.screen_position.x) * 
+                         (1 / self.world.scaler)
+    self.world.position.y = -(position.y - self.entity.screen_position.y) * 
+                         (1 / self.world.scaler)
+end
+
+function ai_mt:movePathSet(paths)
+    self.paths = Copy.deepcopy(paths)
+    for i, path in pairs(paths) do
+        self.paths[i].first_update = true
+    end
+end
+
+function ai_mt:movePathUpdate()
+    if not self.paths then return false end
+
+    for i, path in pairs(self.paths) do
+        if path.first_update then
+            path.start_pos = self:getPlayerPosition()
+            path.moving_pos = Copy.shallow_copy(self.paths[i].start_pos)
+            path.first_update = false
+        end
+        if 
+            (path.direction == "north" and
+            path.start_pos.y - path.moving_pos.y >= path.distance)
+            or
+            (path.direction == "east" and
+            path.moving_pos.x - path.start_pos.x >= path.distance)
+            or
+            (path.direction == "south" and
+            -(path.start_pos.y - path.moving_pos.y) >= path.distance)
+            or
+            (path.direction == "west" and
+            path.start_pos.x - path.moving_pos.x >= path.distance)
+        then
+            self.path = nil
+            return true
+        end
+        path.moving_pos = self:getPlayerPosition()
+        self:travel(path.direction)
+        self:collisionUpdate()
+    end
+
+    return false
+end
+
+function ai_mt:init(world, entity, scale, window_size)
+    self.paths = nil
+    self.paths_callback = nil
+    self.entity = entity
+    self.world = world
+    self.scale = scale
+    self.loop_id = Ex.Loops.add(60)
+end
+
+function ai_mt:setNoClip(value)
+    noClip = value
+end
+
+function ai_mt:start()
+    colliding_id = nyq.world.addCollisionCheck( 0, {
+        x = self.entity.screen_position.x * self.scale + (self.scale * 1),
+        y = self.entity.screen_position.y * self.scale + (self.scale * 7)
+    }, self.entity.hitbox)
+end
+
+function ai_mt:collisionUpdate()
+    objectCollision = nyq.world.checkCollision(0, colliding_id)
+    -- print(objectCollision.type);
+end
+
+return ai_mt
diff --git a/modules/clock.lua b/modules/clock.lua
new file mode 100644 (file)
index 0000000..1003bb5
--- /dev/null
@@ -0,0 +1,11 @@
+local time = {}
+
+function time.start()
+    time.start = os.clock()
+end
+
+function time.get()
+    time.start = os.clock()
+end
+
+return time
diff --git a/modules/collection.lua b/modules/collection.lua
new file mode 100644 (file)
index 0000000..f7755e0
--- /dev/null
@@ -0,0 +1,35 @@
+local Collection = {}
+
+function Collection:new()
+    local o = {}
+    o.metatable = {
+        __index = {
+
+            collection = {},
+            elapsed_time = 0,
+            addedNew = false,
+            size = 0,
+
+            push = function(self, st)
+                self.collection[#self.collection + 1] = st
+                self.addedNew = true
+                self.size = self.size + 1
+            end,
+
+            pop = function(self)
+                local state = table.remove(self.collection, self.size)
+                if state then 
+                    -- state.first_call = true
+                    self.first_call = true
+                    self.addedNew = false
+                    self.size = self.size - 1
+                end
+                return state
+            end
+        },
+    }
+    setmetatable(o, o.metatable)
+    return o
+end
+
+return Collection
diff --git a/modules/copy.lua b/modules/copy.lua
new file mode 100644 (file)
index 0000000..ec09852
--- /dev/null
@@ -0,0 +1,33 @@
+local copy = {}
+
+function copy.shallow_copy(t)
+  local t2 = {}
+  for k,v in pairs(t) do
+    t2[k] = v
+  end
+  return t2
+end
+
+
+function copy.deepcopy(orig, copies)
+    copies = copies or {}
+    local orig_type = type(orig)
+    local c
+    if orig_type == 'table' then
+        if copies[orig] then
+            c = copies[orig]
+        else
+            c = {}
+            copies[orig] = c
+            for orig_key, orig_value in next, orig, nil do
+                c[copy.deepcopy(orig_key, copies)] = copy.deepcopy(orig_value, copies)
+            end
+            setmetatable(c, copy.deepcopy(getmetatable(orig), copies))
+        end
+    else -- number, string, boolean, etc
+        c = orig
+    end
+    return c
+end
+
+return copy
diff --git a/modules/find.lua b/modules/find.lua
new file mode 100644 (file)
index 0000000..b323231
--- /dev/null
@@ -0,0 +1,14 @@
+local find = {}
+
+function find.reverse(str, pattern)
+    local reversed = string.reverse(str)
+    local match = table.pack(string.find(reversed, pattern))
+    if match[1] and match[2] then
+        match[1] = string.len(str) - match[1] + 1
+        match[2] = string.len(str) - match[2] + 1
+        return match
+    end
+    return nil
+end
+
+return find
diff --git a/modules/hashTable.lua b/modules/hashTable.lua
new file mode 100644 (file)
index 0000000..6879063
--- /dev/null
@@ -0,0 +1,18 @@
+local hashTable = {}
+hashTable.key_values = {}
+
+function hashTable:insert(t, v)
+    local hexstring = hashTable:getString(t)
+    hashTable.key_values[hexstring] = v
+end
+
+function hashTable:getString(t)
+    local hexout = tostring(t)
+    return hexout:sub(hexout:find("0x.*"))
+end
+function hashTable:getValue(t)
+    local hexstring = hashTable:getString(t)
+    return hashTable.key_values[hexstring]
+end
+
+return hashTable
diff --git a/modules/metatables/entity.lua b/modules/metatables/entity.lua
new file mode 100644 (file)
index 0000000..056d9be
--- /dev/null
@@ -0,0 +1,111 @@
+local entity = {}
+
+local crop_size = nil
+entity.name = nil
+
+function entity:Entityinit(ui, name, spritesheet, scale, scaler, window_size)
+    self.position = {}
+    self.position.x = 0
+    self.position.y = 0
+    self.speed = 600
+    self.idle = "idle_south"
+    self.scaler = scaler
+    self.move = nil
+    self.start_position = {x = 0, y = 0}
+    self.screen_position = {
+        x = window_size.w / 2,
+        y = window_size.h / 2 
+        -- x = 0,
+        -- y = 0
+    }
+    self.crop_size = {w = 44 * .35, h = 57 * .35}
+    self.size = {w = 44 * .35, h = self.crop_size.h + 2}
+    self.hitbox = { w = 13 * scale, h = 14 * scale}
+    self.objectCollision = nil
+    self.spritesheet = spritesheet
+    self.name = name
+
+end
+
+function entity:EntityStart(ui)
+
+    ui:addAnimation(self.name, "walk_north", {
+        {x = 0, y = 0, w = 44, h = 57},
+        {x = 0, y = 58, w = 44, h = 57},
+        {x = 0, y = 0, w = 44, h = 57},
+        {x = 0, y = 116, w = 44, h = 57},
+    }, self.crop_size)
+
+    ui:addAnimation(self.name, "idle_north", {
+        {x = 0, y = 0, w = 44, h = 57},
+    }, self.crop_size)
+
+    ui:addAnimation(self.name, "walk_east", {
+        {x = 44, y = 0, w = 44, h = 57},
+        {x = 44, y = 57, w = 44, h = 57},
+        {x = 44, y = 116, w = 44, h = 57},
+    }, self.crop_size)
+
+    ui:addAnimation(self.name, "idle_east", {
+        {x = 44, y = 0, w = 44, h = 57},
+    }, self.crop_size)
+
+    ui:addAnimation(self.name, "walk_south", {
+        {x = 88, y = 0, w = 44, h = 57},
+        {x = 88, y = 58, w = 44, h = 57},
+        {x = 88, y = 0, w = 44, h = 57},
+        {x = 88, y = 116, w = 44, h = 57},
+    }, self.crop_size)
+
+    ui:addAnimation(self.name, "idle_south", {
+        {x = 88, y = 0, w = 44, h = 57},
+    }, self.crop_size)
+
+    ui:addAnimation(self.name, "walk_west", {
+        {x = 132, y = 0, w = 44, h = 57},
+        {x = 132, y = 58, w = 44, h = 57},
+        {x = 132, y = 116, w = 44, h = 57},
+    }, self.crop_size)
+
+    ui:addAnimation(self.name, "idle_west", {
+        {x = 132, y = 0, w = 44, h = 57},
+    }, self.crop_size)
+end
+
+function entity:getPosition()
+    return {
+        x = (self.position.x * self.scaler) , 
+        y = (self.position.y * self.scaler) 
+    }
+end
+
+function entity:setPosition(id, position)
+    self.position = {
+        x = (position.x) * (1 / self.scaler),
+        y = (position.y) * (1 / self.scaler),
+    }
+end
+
+function entity:EntityMoveUpdate(ui)
+
+    if self.move then
+        local speed = 20
+        if 
+            self.move == "walk_north" or 
+            self.move == "nnwalk_south"
+        then
+            speed = 27
+        end
+        ui:updateAnimation(self.name, 
+                           self.move,
+                           speed,  self.screen_position)
+    else
+        ui:updateAnimation(self.name, self.idle, 
+                           1, self.screen_position)
+    end
+
+
+    self.move = nil
+end
+
+return entity 
diff --git a/modules/player.lua b/modules/player.lua
new file mode 100644 (file)
index 0000000..8d34762
--- /dev/null
@@ -0,0 +1,34 @@
+local player = {}
+local entity = require("modules.metatables.entity")
+
+local face_sprite_id = nil
+
+function player:init(ui, name, spritesheet, scale, scaler, window_size)
+    entity:Entityinit(ui, name, spritesheet, scale, scaler, window_size)
+    setmetatable(player, {__index = entity })
+end
+
+function player:start(ui)
+    player:EntityStart(ui)
+    face_sprite_id = ui:newSprite(self.spritesheet)
+    ui:spriteAddCrops(face_sprite_id, "face", 5, {
+        {
+            x = 0,
+            y = 173,
+            w = 50,
+            h = 30
+        }
+    })
+end
+
+function player:faceUpdate(ui)
+    ui:spriteUpdateCrop(face_sprite_id, "face", 1, {
+        x = 0, y = 130
+    })
+end
+
+function player:moveUpdate(ui)
+    player:EntityMoveUpdate(ui)
+end
+
+return player
diff --git a/modules/state.lua b/modules/state.lua
new file mode 100644 (file)
index 0000000..9a67be5
--- /dev/null
@@ -0,0 +1,32 @@
+local State = {}
+
+function State:new(call)
+    local o = {}
+    o.metatable = {
+        __index = {
+            first_call = true,
+            elapsed_time = 0,
+            start_time = 0,
+        },
+        __call = function(table, key)
+            if table.first_call then
+                table.start_time = nyq.getTicks()
+                table.first_call = false
+            end
+            call()
+            -- table.elapsed_time = os.clock() - table.start_time
+            table.elapsed_time = nyq.getTicks() - table.start_time
+        end
+
+    }
+    o.reset = function()
+        o.start_time = nyq.getTicks()
+        o.first_call = true
+        o.elapsed_time = 0
+
+    end
+    setmetatable(o, o.metatable)
+    return o
+end
+
+return State
diff --git a/modules/string.lua b/modules/string.lua
new file mode 100644 (file)
index 0000000..25ee840
--- /dev/null
@@ -0,0 +1,48 @@
+string.WordWrap = function (text, character_length)
+    local str = text
+    local spaces = {}
+    local i = 1
+    local lines = {}
+
+    local found =  nil
+    local total = 0
+    repeat
+        found = string.find(str, '%s')
+        if found then
+            total = total + found
+            spaces[i] = total
+            str = string.sub(str, found + 1)
+        end
+        i = i + 1
+    until not found
+
+    local start = 1
+    found = 0
+    i = 1
+    for k, v in pairs(spaces) do
+        if v > start + character_length then
+            found = spaces[k - 1]
+            local line = string.sub(text, start, found)
+            if string.len(line) > 0 then
+                lines[i] = line
+                i = i + 1
+            end
+            start =  found + 1
+        end
+    end
+    local line = string.sub(text, start)
+    if string.len(line) > 0 then
+        local match = Find.reverse(line, '%s')
+        if string.len(line) > character_length then
+            if match then
+                lines[i] = string.sub(line, 1, match[1])
+                lines[i + 1] = string.sub(line, match[1] + 1)
+            end
+        else
+            lines[i] = line
+        end
+    end
+    -- if not lines then return {text} end
+
+    return lines
+end
diff --git a/modules/table.lua b/modules/table.lua
new file mode 100644 (file)
index 0000000..86f8bbe
--- /dev/null
@@ -0,0 +1,10 @@
+table.Reverse = function(a)
+    local b = {}
+    for i = 1, #a do
+        local j = #a - (i - 1)
+        b[j] = {}
+        b[j].id = i
+        b[j].text = a[i]
+    end
+    return b
+end
diff --git a/modules/uuid.lua b/modules/uuid.lua
new file mode 100644 (file)
index 0000000..b397c67
--- /dev/null
@@ -0,0 +1,12 @@
+local uuid = {}
+local random = math.random
+math.randomseed(os.time())
+
+function uuid:create()
+    local template ='xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
+    return string.gsub(template, '[xy]', function (c)
+        local v = (c == 'x') and random(0, 0xf) or random(8, 0xb)
+        return string.format('%x', v)
+    end)
+end
+return uuid
diff --git a/modules/world.lua b/modules/world.lua
new file mode 100644 (file)
index 0000000..0110478
--- /dev/null
@@ -0,0 +1,409 @@
+local outdoor_crops = require("map_configs.crops.outdoor")
+local world = {}
+local map_spec = {}
+local locations = {}
+world.current_pos = 1
+world.entity = nil
+world.position = {x = 0, y = 0}
+world.scaler = .100
+world.zIndex = 0
+local grid = 4
+local grid_size = grid * grid
+world.layout = {}
+local world_size = 0
+local world_offset = {x = 0, y = 0}
+local maps = {}
+local window_size = nil
+local spritesheet_id = nil
+
+-- local LN <const> = 0
+local N  <const> = 2
+local S  <const> = 3
+local E  <const> = 4
+local W  <const> = 5
+
+local map_specs = nil
+
+local update = {}
+update[N] = false
+update[E] = false
+update[S] = false
+update[W] = false
+
+local first = {}
+first[N] = true
+first[E] = true
+first[S] = true
+first[W] = true
+first[N << E] = true
+first[S << E] = true
+first[N << W] = true
+first[S << W] = true
+
+local spritesheet = nil
+local name = nil
+
+-- map_specs example
+-- local map_specs = {
+--     [1] = {spec = {1, 2, 3}, limit = 30}, 
+--     [2] = {spec = {4, 5, 6}, limit = 14},
+-- }
+
+local function getCardinal(n)
+    return  {
+        [N] = ((n + grid) <= grid_size) and (n + grid) or -1,
+        [E] = ((n % grid) < (grid - 1)) and (n + 1) or -1,
+        [S] = ((n - grid) > 0) and (n - grid) or -1,
+        [W] = (((n - 1) % grid) > 0) and (n - 1) or -1,
+    }
+end
+
+local function getOrdinal(n)
+    local x = ((n - 1) % grid) + 1
+
+    return  {
+        [N << E] =
+            ((x < grid) and (n + grid <= grid_size)) and 
+             (n + grid + 1) or -1,
+
+        [S << E] =
+            ((n + grid) > (grid * 2) and (x <= 3)) and 
+             (n - grid + 1)  or -1,
+
+        [S << W] =
+            ((n + grid > grid * 2) and (x > 1)) and 
+             (n - grid - 1) or -1,
+
+        [N << W] =
+            ((x > 1) and (n + grid <= grid_size)) and 
+             (n + grid - 1) or -1,
+    }
+end
+
+function world:init(g, e, specs, ws, s, n)
+    grid = g
+    grid_size = g * g
+    map_specs = specs
+    window_size = ws
+    spritesheet = s
+    name = n
+    self.current_pos = 1
+    self.entity = e
+    nyq.world.init(0, spritesheet, name);
+end
+
+function world:read(map_ip, pos, zIndex)
+    nyq.world.read(map_ip, self.layout[pos].id, zIndex)
+
+    local rng = self.layout[pos].rng
+    if rng ~= nil then
+        nyq.world.newObject(map_ip, rng)
+    end
+end
+
+function world:mapStart(ui)
+    if not self.layout[self.current_pos] then 
+        print("could not load map")
+        os.exit()
+    end
+    nyq.world.free(0)
+    for i = 0, 8 do
+        nyq.world.init(i, spritesheet, name);
+    end
+
+    spritesheet_id = ui:newSprite("spritesheet_outdoor_1.png")
+    self:read(0, self.current_pos, 0)
+end
+
+function world:getPosition()
+    return {
+        x = (self.position.x * self.scaler) , 
+        y = (self.position.y * self.scaler) 
+    }
+end
+
+
+function world:setPosition(id, position)
+    nyq.map.set(id, {
+        x = (position.x) * (1 / self.scaler),
+        y = (position.y) * (1 / self.scaler),
+    })
+end
+
+
+local function getOpposite(d)
+    return (d == N) and S or
+           (d == S) and N or
+           (d == W) and E or
+           (d == E) and W
+end
+
+function world:createRNGObject(ui, id, variations)
+    local world_pos = self:getPosition()
+    local start_x = ((self.current_pos - 1) % grid ) * 480
+    local start_y = (math.floor((self.current_pos - 1) / grid)) * 320
+    local update_pos = {x = world_pos.x + start_x, y = world_pos.y - start_y}
+    nyq.world.read(0, id, 0)
+
+    for i, object in pairs(nyq.world.getObjects(0)) do
+        for type, variation in pairs(variations) do
+            if object.type == "rng_" .. type then
+                local v = math.floor((math.random() * #variation) + 1)
+                local a = Copy.deepcopy(outdoor_crops[variation[v]])
+                a.size = {
+                    w = a.crops[1].w  * (1 / self.scaler),
+                    h = a.crops[1].h * (1 / self.scaler)
+                }
+                a.hitbox = {
+                    x = a.hitbox.x  * (1 / self.scaler),
+                    y = a.hitbox.y * (1 / self.scaler),
+                    w = a.hitbox.w  * (1 / self.scaler),
+                    h = a.hitbox.h * (1 / self.scaler)
+                }
+                a.type = variation[v]
+                a.position = object.position
+                return a
+            end
+        end
+    end
+    return nil
+end
+
+function world:mapUpdate(ui, args)
+::MAP_CHANGE::
+    local world_pos = self:getPosition()
+    local cardinal = getCardinal(self.current_pos)
+    local ordinal = getOrdinal(self.current_pos)
+    local entity_pos = self.entity:getPosition()
+    local start_x = ((self.current_pos - 1) % grid ) * 480
+    local start_y = (math.floor((self.current_pos - 1) / grid)) * 320
+    local update_pos = {x = world_pos.x + start_x, y = world_pos.y - start_y}
+
+    update[N] = update_pos.y  > 0
+    update[S] = -update_pos.y > window_size.h
+    update[E] = -update_pos.x > window_size.w
+    update[W] = update_pos.x  > 0
+
+    if (update[N] and update[E]) then
+        ordinal_map_ip = 5
+    elseif (update[S] and update[E]) then
+        ordinal_map_ip = 6
+    elseif (update[N] and update[W]) then
+        ordinal_map_ip = 7
+    elseif (update[S] and update[W]) then
+        ordinal_map_ip = 8
+    end
+
+   for k, v in pairs(update) do
+        if not update[k] then
+            first[k] = true
+        end
+   end
+
+    for i = N, S do for j = E, W do
+        if (not update[i]) and (not update[j]) then
+            first[i << j] = true
+        end
+    end end
+
+    for d1 = N, S do
+        for d2 = E, W do
+            local offset = {x = 0, y = 0}
+            if update[d1] and update[d2] and self.layout[ordinal[d1 << d2]] then
+                if d1 == N and d2 == E then
+                    offset.x = 480
+                    offset.y = -320
+                elseif d1 == S and d2 == E then
+                    offset.x = 480
+                    offset.y = 320
+                elseif d1 == S and d2 == W then
+                    offset.x = -480
+                    offset.y = 320
+                elseif d1 == N and d2 == W then
+                    offset.x = -480
+                    offset.y = -320
+                end
+
+                if first[d1 << d2] then
+                    -- nyq.world.read(ordinal_map_ip, self.layout[ordinal[d1 << d2]].id, 0)
+                    self:read(ordinal_map_ip, ordinal[d1 << d2], 0)
+                    first[d1 << d2] = false
+                end
+                -- local rng = self.layout[ordinal[d1 << d2]].rng
+                -- if rng then
+                --     ui:spriteUpdateCrop(spritesheet_id, rng.name, 1, {
+                --         x = update_pos.x + rng.position.x + offset.x,
+                --         y = update_pos.y + rng.position.y + offset.y,
+                --     })
+                -- end
+                world:setPosition(ordinal_map_ip, {
+                    x = update_pos.x + offset.x,
+                    y = update_pos.y + offset.y,
+                })
+                nyq.world.update(ordinal_map_ip, args.scale * self.scaler)
+            end
+        end
+    end
+
+
+    for d = N, W do
+        local cardinal_map_ip = d - 1
+        if update[d] and self.layout[cardinal[d]] then
+            local offset = { x = 0, y = 0 }
+            local pass = false
+
+            if d == N then
+                offset.y = -320
+                pass = -entity_pos.y + start_y  + self.entity.size.h  < 0
+            elseif d == E then
+                offset.x = 480
+                pass = entity_pos.x - start_x > 480
+            elseif d == S then
+                offset.y = 320
+                pass = -entity_pos.y + start_y > 320
+            elseif d == W then
+                offset.x = -480
+                pass = entity_pos.x - start_x + self.entity.size.h < 0
+            end
+
+            if pass then
+                -- nyq.world.read(0, self.layout[cardinal[d]].id, 0)
+                self:read(0, cardinal[d], 0)
+                for i = N, W do 
+                    first[i] = true 
+                    first[i << W] = true 
+                    first[i << E] = true 
+                end
+                self.current_pos = cardinal[d]
+                world:print()
+                print("\n")
+                goto MAP_CHANGE
+            end
+
+            if first[d] then
+                print('first')
+                -- nyq.world.read(cardinal_map_ip, self.layout[cardinal[d]].id, 0)
+                self:read(cardinal_map_ip, cardinal[d], 0)
+                first[d] = false
+            end
+
+            -- local rng = self.layout[cardinal[d]].rng
+            -- if rng then
+            --     ui:spriteUpdateCrop(spritesheet_id, rng.name, 1, {
+            --         x = update_pos.x + rng.position.x + offset.x,
+            --         y = update_pos.y + rng.position.y + offset.y,
+            --     })
+            -- end
+
+            world:setPosition(cardinal_map_ip, {
+                x = update_pos.x + offset.x,
+                y = update_pos.y + offset.y,
+            })
+            nyq.world.update(cardinal_map_ip, args.scale * self.scaler)
+        end
+    end
+
+    world:setPosition(0, update_pos)
+    nyq.world.update(0, args.scale * self.scaler)
+
+
+end
+
+function world:generate(ui, variations)
+    math.randomseed()
+
+    local done = 1
+    local pos = self.current_pos
+
+    for k, v in pairs(map_specs) do
+        done = done + v.limit
+    end
+
+    if done > grid_size then done = grid_size end
+
+    while(world_size < done - 1) do
+
+::CONTINUE::
+
+        for k, v in pairs(map_specs) do
+
+            if v.limit <= 0 then 
+                table.remove(map_specs, k)
+                goto CONTINUE
+            end
+
+            local s = getCardinal(pos)
+
+            local map_id = v.spec[math.floor(math.random() * (#v.spec - 1) + .5) + 1]
+
+            local check = {}
+            for _, dir in pairs(s) do
+                if dir > 0 then
+                    table.insert(check, dir)
+                end
+            end
+
+            local check_count = 0
+            local n = 0
+
+
+::CHECKAGAIN::
+
+            local r = math.floor(math.random() * (#check - 1) + .5) + 1
+
+            if  check_count >= grid_size * 10 then
+                return
+            else
+                for k, _ in pairs(self.layout) do
+                    if k == check[r] then
+                        check_count = check_count + 1
+                        goto CHECKAGAIN
+                    end
+                end
+            end
+            local object = self:createRNGObject(ui, map_id, variations)
+
+            -- TODO:
+            -- make rng an array of possible random objects
+            self.layout[pos] = {id = map_id, next_pos = check[r], rng = object}
+            pos = check[r]
+            v.limit = v.limit - 1
+            world_size = world_size + 1
+        end
+    end
+end
+
+function world:print()
+
+    local start = grid_size - grid + 1
+
+    for i = start, 1, -grid do
+        for j = i, i + grid - 1 do
+            if self.layout[j] then
+                if j == self.current_pos then
+                    io.write(string.format(" [%.2d] ", self.layout[j].id))
+                else
+                    io.write(" [==] ")
+                end
+            else
+                io.write(" [  ] ")
+            end
+        end
+        print("")
+    end
+
+
+end
+
+function world:free()
+    for i = 0, 8 do 
+        nyq.world.free(i);
+    end
+end
+
+return world
+-- world:init(4, {
+--     [1] = {spec = {4, 5, 9}, limit = 4}
+-- })
+-- world:generate()
+-- world:print()
diff --git a/old/world.lua b/old/world.lua
new file mode 100644 (file)
index 0000000..a8010f1
--- /dev/null
@@ -0,0 +1,311 @@
+local player_spritesheet <const> = "nyquist_spritesheet.png"
+local ai <const> = require("modules.ai")
+local map <const> = require("modules.map")
+local vars <const> = {}
+local assign = require("extensions.metatables.ui")
+local ui, ui_mt = assign("world", {vars = vars, ai = ai})
+
+function ui:init(world_name, world_spritesheet,
+                 window_size, options)
+    ui_mt:_init(player_spritesheet, window_size, "NotoSansMono-Regular.ttf", 8,
+             options, function()
+        vars.world_spritesheet = world_spritesheet
+        vars.world_name = world_name
+        vars.selection_max = 0
+        vars.start_menu = {}
+        local pos = { x = ui.window_size.w - 55, y = 4 }
+        vars.start_menu.position = pos
+        vars.start_menu.selection = {}
+        vars.start_menu.size = {w = 0, h = 0}
+        vars.go_outside = false
+        vars.traverse_stairs = false
+        vars.in_door = false
+        vars.in_stairs = false
+    end)
+    ai:init(map, options.scale, window_size)
+    world:init(2, {
+        [1] = {spec = {3, 4, 5}, limit = 3}, 
+    })
+    world:generate()
+    print("world layout:\n")
+    world:print()
+    print()
+end
+
+function ui:startCallback()
+    nyq.hasFrameCap(true)
+    vars.selected = 1
+    vars.selection_rect = ui:createRect({r = 100, g = 0, b = 0, a = 50}, true, 6)
+    vars.text_rect_id  = ui:createRect({r = 0, g = 0, b = 0, a = 200}, true, 4)
+    vars.text_pos = 0
+    vars.text_max = 0
+    vars.text_done = false
+    vars.text_end = false
+
+
+    for i = 1, 3 do
+        local id = string.format("%d", i)
+        ui:addText("text", id, " ", 5,
+            {r = 255, g = 255, b = 255, a = 255},
+            {r = 0, g = 0, b = 0, a = 0}
+        )
+    end
+
+    nyq.world.init(0, vars.world_spritesheet, vars.world_name);
+    nyq.world.read(0, params.world_id, ai.map.zIndex)
+
+    vars.face_sprite_id = ui:newSprite(ui.spritesheet)
+    ui:spriteAddCrops(vars.face_sprite_id, "face", 5, {
+        {
+            x = 0,
+            y = 173,
+            w = 50,
+            h = 30
+        }
+    })
+    ai:start()
+    if params.world_id == 1 then
+        vars.rect_id = ui:createRect({r = 0, g = 0, b = 0, a = 180}, true, 0)
+    end
+
+    ui:addAnimation("player", "walk_north", {
+        {x = 0, y = 0, w = 44, h = 57},
+        {x = 0, y = 58, w = 44, h = 57},
+        {x = 0, y = 0, w = 44, h = 57},
+        {x = 0, y = 116, w = 44, h = 57},
+    }, ai.player.crop_size)
+
+    ui:addAnimation("player", "idle_north", {
+        {x = 0, y = 0, w = 44, h = 57},
+    }, ai.player.crop_size)
+
+    ui:addAnimation("player", "walk_east", {
+        {x = 44, y = 0, w = 44, h = 57},
+        {x = 44, y = 57, w = 44, h = 57},
+        {x = 44, y = 116, w = 44, h = 57},
+    }, ai.player.crop_size)
+
+    ui:addAnimation("player", "idle_east", {
+        {x = 44, y = 0, w = 44, h = 57},
+    }, ai.player.crop_size)
+
+    ui:addAnimation("player", "walk_south", {
+        {x = 88, y = 0, w = 44, h = 57},
+        {x = 88, y = 58, w = 44, h = 57},
+        {x = 88, y = 0, w = 44, h = 57},
+        {x = 88, y = 116, w = 44, h = 57},
+    }, ai.player.crop_size)
+
+    ui:addAnimation("player", "idle_south", {
+        {x = 88, y = 0, w = 44, h = 57},
+    }, ai.player.crop_size)
+
+    ui:addAnimation("player", "walk_west", {
+        {x = 132, y = 0, w = 44, h = 57},
+        {x = 132, y = 58, w = 44, h = 57},
+        {x = 132, y = 116, w = 44, h = 57},
+    }, ai.player.crop_size)
+
+    ui:addAnimation("player", "idle_west", {
+        {x = 132, y = 0, w = 44, h = 57},
+    }, ai.player.crop_size)
+
+
+    vars.menu_size = #params.menu_items
+    vars.start_menu.id = ui:imageCreate("pause.png", 5)
+
+    local padding = 11
+    local padding_top_and_bottom = 8
+    local fg_color = {r = 0, g = 0, b = 0, a = 0}
+    local bg_color = {r = 255, g = 255, b = 255, a = 0}
+
+    for i, item in ipairs(params.menu_items) do
+        vars.start_menu.selection[i] = {}
+        vars.start_menu.selection[i].position = {x = vars.start_menu.position.x + 8, y = padding_top_and_bottom  + padding * (i - 1)}
+        vars.start_menu.selection[i].id = nil
+        ui:addText2(vars.start_menu.selection[i], "id", item.name, 5, fg_color, bg_color)
+    end
+    local text_size = ui:getTextSize2(vars.start_menu.selection[1], "id")
+    vars.start_menu.size = {
+                w = 53, h = ((padding * (vars.menu_size - 1)) +
+                (padding_top_and_bottom)) + text_size.h
+    }
+end
+
+-- function ui:changeMap(id, spritesheet)
+function ui:changeMap(chunk)
+    nyq.clear({r = 0, g = 0, b = 0, a = 255})
+    nyq.draw()
+    states.world.main:reset()
+    ui:free()
+    ui:init(chunk.world, chunk.spritesheet, 
+    unscaled_window_size, 
+    {scale = Ex.Config.resolution_scale})
+    local menu_items = {
+        [1] = { name = "Map", },
+        [2] = { name = "Clonemon", },
+        [3] = { name = "bag", },
+        [4] = { name = "Player", },
+        [5] = { name = "Save", },
+        [6] = { name = "Settings", },
+        [7] = { name = "Quit", }
+    }
+    params = {
+        menu_items = menu_items,
+        world_id = chunk.id,
+        idle = "idle_south",
+    }
+    ui:start()
+    ai:setNoClip(true)
+
+    local start_pos = {
+        x = 24 - ai.player.size.w / 2 , 
+        y = -(ai.player.size.h / 2) - 20
+    }
+    ai:setPlayerPosition(start_pos)
+    ai:movePathSet(
+    {
+        [0] = { 
+            direction  = "south",
+            distance = 50
+        }
+    })
+    local loop_id = Ex.Loops.add(60)
+    repeat
+        Ex.Loops.loopStart(loop_id)
+        nyq.clear({r = 0, g = 0, b = 0, a = 255})
+        local noPath = ai:movePathUpdate()
+        ui:worldUpdate()
+        nyq.draw()
+        Ex.Loops.loopEnd(loop_id)
+    until noPath
+    ai:setNoClip(false)
+end
+
+function ui:worldUpdate()
+    -- do NOT load anything fram a group in here!
+    -- it will confilict with other uis
+    if ai.player.move then
+        local speed = 20
+        if 
+            ai.player.move == "walk_north" or 
+            ai.player.move == "walk_south"
+        then
+            speed = 27
+        end
+        ui:updateAnimation("player", 
+                           ai.player.move,
+                           speed,  ai.player.screen_position)
+    else
+        ui:updateAnimation("player", ai.player.idle, 
+                           1, ai.player.screen_position)
+    end
+    local player_pos = ai:getPlayerPosition()
+    local map_pos = map:getPosition()
+    if params.world_id == 1 then
+        ui:rectUpdate(vars.rect_id, 
+        {x = map_pos.x + 112, y = map_pos.y + 72},
+        {w = 32, h = 16})
+
+        vars.in_door = 
+            (player_pos.x + ai.player.size.w - 4 > 112 and player_pos.x < 144) and
+            (player_pos.y + ai.player.size.h > 72 )
+
+    end
+    vars.in_stairs = (player_pos.x < 48) and (player_pos.y < 18)
+    ui:updateMenuItem("up arrow", 1, {
+        x = map_pos.x + 17, y = map_pos.y + 5
+    })
+
+
+    nyq.map.set(0, ai.map.position)
+    nyq.world.update(0, ui.scale * ai.map.scaler)
+    ai.player.move = nil
+
+    -- map:update()
+    if vars.traverse_stairs then
+        if params.world_id == 1 then
+            print("going to world 2")
+            -- ui:changeMap(2, "spritesheet_indoors_1.png")
+            ui:changeMap{
+                id = 2, 
+                world = "test",
+                spritesheet  = "spritesheet_indoors_1.png"
+            }
+        elseif params.world_id == 2 then
+            print("going to world 1")
+            ui:changeMap{
+                id = 1, 
+                world = "test",
+                spritesheet = "spritesheet_indoors_1.png",
+            }
+        end
+    end
+    if vars.go_outside then
+        ui:changeMap{
+            id = 3, 
+            world = "test",
+            spritesheet = "spritesheet_outdoor_1.png",
+            outdoor = true,
+        }
+    end
+end
+
+function ui:pauseUpdate()
+    ui:imageUpdate(vars.start_menu.id, 
+                   vars.start_menu.position, vars.start_menu.size)
+    local size = ui:getTextSize2(vars.start_menu.selection[vars.selected], "id")
+    local text_pos = vars.start_menu.selection[vars.selected].position
+    ui:rectUpdate(vars.selection_rect,
+                    {x = (vars.start_menu.position.x) + (4),
+                     y = (text_pos.y)},
+                     {w = (vars.start_menu.size.w) - (9),
+                     h = size.h})
+    for i, selection in ipairs(vars.start_menu.selection) do
+        ui:updateText2(selection, "id", selection.position)
+    end
+end
+
+function ui:selectUpdate(options)
+    vars.selection_max = ui:optionSelectInit(options)
+    ui:optionSelectUpdate({x = 238, y = 118}, vars.selected)
+end
+
+function ui:textUpdate(text)
+    if vars.text_end then
+        vars.text_end = false
+        return
+    end
+
+    local lines = string.WordWrap(text, 38)
+    vars.text_max = math.ceil(#lines / 3)
+
+    for i = 1, 3 do
+        if not lines[i + (vars.text_pos * 3)] then
+            vars.text_done = true
+            break
+        end
+        local id = string.format("%d", i)
+        local y = 130 + ((i - 1) * (ui.font_size + 1))
+        ui:textChange("text", id, lines[i + (vars.text_pos * 3)],
+            {r = 255, g = 255, b = 255, a = 255},
+            {r = 0, g = 0, b = 0, a = 0}
+        )
+        ui:updateText("text", id, {x = 54,  y = y})
+    end
+
+    ui:spriteUpdateCrop(vars.face_sprite_id, "face", 1, {
+        x = 0, y = 130
+    })
+    ui:rectUpdate(vars.text_rect_id,
+    {
+        x = 50,
+        y = 130
+    },
+    {
+        w = 190,
+        h = 30
+    })
+end
+
+return ui
diff --git a/old/world/main.lua b/old/world/main.lua
new file mode 100644 (file)
index 0000000..c5f93be
--- /dev/null
@@ -0,0 +1,33 @@
+return State:new(
+    function()
+        nyq.keypress.trigger = false;
+        if ui.vars.in_door then
+            if nyq.keypress.select then
+                ui.vars.go_outside = true
+                ui.vars.in_door = false
+            end
+        end
+        if ui.vars.in_stairs then
+            if nyq.keypress.select then
+                ui.vars.traverse_stairs = true
+                ui.vars.in_stairs = false
+            end
+        end
+
+        if (nyq.keypress.pause) then
+            state = states.world.pause
+            -- uis.world.paused = true
+        end
+        ui.ai:collisionUpdate()
+
+        if nyq.keypress.move_north then
+            ui.ai:travel("north")
+        elseif nyq.keypress.move_east then
+            ui.ai:travel("east")
+        elseif nyq.keypress.move_south then
+            ui.ai:travel("south")
+        elseif nyq.keypress.move_west then
+            ui.ai:travel("west")
+        end
+    end
+)
diff --git a/rendered.html b/rendered.html
new file mode 100644 (file)
index 0000000..d5d8195
--- /dev/null
@@ -0,0 +1,1046 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta http-equiv="X-UA-Compatible" content="IE=edge">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<meta name="generator" content="Asciidoctor 2.0.20">
+<title>CLONEMON</title>
+<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700">
+<style>
+/*! Asciidoctor default stylesheet | MIT License | https://asciidoctor.org */
+/* Uncomment the following line when using as a custom stylesheet */
+/* @import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700"; */
+html{font-family:sans-serif;-webkit-text-size-adjust:100%}
+a{background:none}
+a:focus{outline:thin dotted}
+a:active,a:hover{outline:0}
+h1{font-size:2em;margin:.67em 0}
+b,strong{font-weight:bold}
+abbr{font-size:.9em}
+abbr[title]{cursor:help;border-bottom:1px dotted #dddddf;text-decoration:none}
+dfn{font-style:italic}
+hr{height:0}
+mark{background:#ff0;color:#000}
+code,kbd,pre,samp{font-family:monospace;font-size:1em}
+pre{white-space:pre-wrap}
+q{quotes:"\201C" "\201D" "\2018" "\2019"}
+small{font-size:80%}
+sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
+sup{top:-.5em}
+sub{bottom:-.25em}
+img{border:0}
+svg:not(:root){overflow:hidden}
+figure{margin:0}
+audio,video{display:inline-block}
+audio:not([controls]){display:none;height:0}
+fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
+legend{border:0;padding:0}
+button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}
+button,input{line-height:normal}
+button,select{text-transform:none}
+button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}
+button[disabled],html input[disabled]{cursor:default}
+input[type=checkbox],input[type=radio]{padding:0}
+button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
+textarea{overflow:auto;vertical-align:top}
+table{border-collapse:collapse;border-spacing:0}
+*,::before,::after{box-sizing:border-box}
+html,body{font-size:100%}
+body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;line-height:1;position:relative;cursor:auto;-moz-tab-size:4;-o-tab-size:4;tab-size:4;word-wrap:anywhere;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}
+a:hover{cursor:pointer}
+img,object,embed{max-width:100%;height:auto}
+object,embed{height:100%}
+img{-ms-interpolation-mode:bicubic}
+.left{float:left!important}
+.right{float:right!important}
+.text-left{text-align:left!important}
+.text-right{text-align:right!important}
+.text-center{text-align:center!important}
+.text-justify{text-align:justify!important}
+.hide{display:none}
+img,object,svg{display:inline-block;vertical-align:middle}
+textarea{height:auto;min-height:50px}
+select{width:100%}
+.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
+div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0}
+a{color:#2156a5;text-decoration:underline;line-height:inherit}
+a:hover,a:focus{color:#1d4b8f}
+a img{border:0}
+p{line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}
+p aside{font-size:.875em;line-height:1.35;font-style:italic}
+h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}
+h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}
+h1{font-size:2.125em}
+h2{font-size:1.6875em}
+h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
+h4,h5{font-size:1.125em}
+h6{font-size:1em}
+hr{border:solid #dddddf;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em}
+em,i{font-style:italic;line-height:inherit}
+strong,b{font-weight:bold;line-height:inherit}
+small{font-size:60%;line-height:inherit}
+code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}
+ul,ol,dl{line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
+ul,ol{margin-left:1.5em}
+ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0}
+ul.circle{list-style-type:circle}
+ul.disc{list-style-type:disc}
+ul.square{list-style-type:square}
+ul.circle ul:not([class]),ul.disc ul:not([class]),ul.square ul:not([class]){list-style:inherit}
+ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
+dl dt{margin-bottom:.3125em;font-weight:bold}
+dl dd{margin-bottom:1.25em}
+blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
+blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
+@media screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
+h1{font-size:2.75em}
+h2{font-size:2.3125em}
+h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
+h4{font-size:1.4375em}}
+table{background:#fff;margin-bottom:1.25em;border:1px solid #dedede;word-wrap:normal}
+table thead,table tfoot{background:#f7f8f7}
+table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
+table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
+table tr.even,table tr.alt{background:#f8f8f7}
+table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{line-height:1.6}
+h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
+h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
+.center{margin-left:auto;margin-right:auto}
+.stretch{width:100%}
+.clearfix::before,.clearfix::after,.float-group::before,.float-group::after{content:" ";display:table}
+.clearfix::after,.float-group::after{clear:both}
+:not(pre).nobreak{word-wrap:normal}
+:not(pre).nowrap{white-space:nowrap}
+:not(pre).pre-wrap{white-space:pre-wrap}
+:not(pre):not([class^=L])>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background:#f7f7f8;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed}
+pre{color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;line-height:1.45;text-rendering:optimizeSpeed}
+pre code,pre pre{color:inherit;font-size:inherit;line-height:inherit}
+pre>code{display:block}
+pre.nowrap,pre.nowrap pre{white-space:pre;word-wrap:normal}
+em em{font-style:normal}
+strong strong{font-weight:400}
+.keyseq{color:rgba(51,51,51,.8)}
+kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background:#f7f7f7;border:1px solid #ccc;border-radius:3px;box-shadow:0 1px 0 rgba(0,0,0,.2),inset 0 0 0 .1em #fff;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
+.keyseq kbd:first-child{margin-left:0}
+.keyseq kbd:last-child{margin-right:0}
+.menuseq,.menuref{color:#000}
+.menuseq b:not(.caret),.menuref{font-weight:inherit}
+.menuseq{word-spacing:-.02em}
+.menuseq b.caret{font-size:1.25em;line-height:.8}
+.menuseq i.caret{font-weight:bold;text-align:center;width:.45em}
+b.button::before,b.button::after{position:relative;top:-1px;font-weight:400}
+b.button::before{content:"[";padding:0 3px 0 2px}
+b.button::after{content:"]";padding:0 2px 0 3px}
+p a>code:hover{color:rgba(0,0,0,.9)}
+#header,#content,#footnotes,#footer{width:100%;margin:0 auto;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}
+#header::before,#header::after,#content::before,#content::after,#footnotes::before,#footnotes::after,#footer::before,#footer::after{content:" ";display:table}
+#header::after,#content::after,#footnotes::after,#footer::after{clear:both}
+#content{margin-top:1.25em}
+#content::before{content:none}
+#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
+#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf}
+#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px}
+#header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:flex;flex-flow:row wrap}
+#header .details span:first-child{margin-left:-.125em}
+#header .details span.email a{color:rgba(0,0,0,.85)}
+#header .details br{display:none}
+#header .details br+span::before{content:"\00a0\2013\00a0"}
+#header .details br+span.author::before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
+#header .details br+span#revremark::before{content:"\00a0|\00a0"}
+#header #revnumber{text-transform:capitalize}
+#header #revnumber::after{content:"\00a0"}
+#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #dddddf;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}
+#toc{border-bottom:1px solid #e7e7e9;padding-bottom:.5em}
+#toc>ul{margin-left:.125em}
+#toc ul.sectlevel0>li>a{font-style:italic}
+#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
+#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
+#toc li{line-height:1.3334;margin-top:.3334em}
+#toc a{text-decoration:none}
+#toc a:active{text-decoration:underline}
+#toctitle{color:#7a2518;font-size:1.2em}
+@media screen and (min-width:768px){#toctitle{font-size:1.375em}
+body.toc2{padding-left:15em;padding-right:0}
+#toc.toc2{margin-top:0!important;background:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
+#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
+#toc.toc2>ul{font-size:.9em;margin-bottom:0}
+#toc.toc2 ul ul{margin-left:0;padding-left:1em}
+#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
+body.toc2.toc-right{padding-left:0;padding-right:15em}
+body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #e7e7e9;left:auto;right:0}}
+@media screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
+#toc.toc2{width:20em}
+#toc.toc2 #toctitle{font-size:1.375em}
+#toc.toc2>ul{font-size:.95em}
+#toc.toc2 ul ul{padding-left:1.25em}
+body.toc2.toc-right{padding-left:0;padding-right:20em}}
+#content #toc{border:1px solid #e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;border-radius:4px}
+#content #toc>:first-child{margin-top:0}
+#content #toc>:last-child{margin-bottom:0}
+#footer{max-width:none;background:rgba(0,0,0,.8);padding:1.25em}
+#footer-text{color:hsla(0,0%,100%,.8);line-height:1.44}
+#content{margin-bottom:.625em}
+.sect1{padding-bottom:.625em}
+@media screen and (min-width:768px){#content{margin-bottom:1.25em}
+.sect1{padding-bottom:1.25em}}
+.sect1:last-child{padding-bottom:0}
+.sect1+.sect1{border-top:1px solid #e7e7e9}
+#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
+#content h1>a.anchor::before,h2>a.anchor::before,h3>a.anchor::before,#toctitle>a.anchor::before,.sidebarblock>.content>.title>a.anchor::before,h4>a.anchor::before,h5>a.anchor::before,h6>a.anchor::before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
+#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
+#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}
+#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}
+details,.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
+details{margin-left:1.25rem}
+details>summary{cursor:pointer;display:block;position:relative;line-height:1.6;margin-bottom:.625rem;outline:none;-webkit-tap-highlight-color:transparent}
+details>summary::-webkit-details-marker{display:none}
+details>summary::before{content:"";border:solid transparent;border-left:solid;border-width:.3em 0 .3em .5em;position:absolute;top:.5em;left:-1.25rem;transform:translateX(15%)}
+details[open]>summary::before{border:solid transparent;border-top:solid;border-width:.5em .3em 0;transform:translateY(15%)}
+details>summary::after{content:"";width:1.25rem;height:1em;position:absolute;top:.3em;left:-1.25rem}
+.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}
+table.tableblock.fit-content>caption.title{white-space:nowrap;width:0}
+.paragraph.lead>p,#preamble>.sectionbody>[class=paragraph]:first-of-type p{font-size:1.21875em;line-height:1.6;color:rgba(0,0,0,.85)}
+.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
+.admonitionblock>table td.icon{text-align:center;width:80px}
+.admonitionblock>table td.icon img{max-width:none}
+.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
+.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #dddddf;color:rgba(0,0,0,.6);word-wrap:anywhere}
+.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
+.exampleblock>.content{border:1px solid #e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;border-radius:4px}
+.sidebarblock{border:1px solid #dbdbd6;margin-bottom:1.25em;padding:1.25em;background:#f3f3f2;border-radius:4px}
+.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
+.exampleblock>.content>:first-child,.sidebarblock>.content>:first-child{margin-top:0}
+.exampleblock>.content>:last-child,.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
+.literalblock pre,.listingblock>.content>pre{border-radius:4px;overflow-x:auto;padding:1em;font-size:.8125em}
+@media screen and (min-width:768px){.literalblock pre,.listingblock>.content>pre{font-size:.90625em}}
+@media screen and (min-width:1280px){.literalblock pre,.listingblock>.content>pre{font-size:1em}}
+.literalblock pre,.listingblock>.content>pre:not(.highlight),.listingblock>.content>pre[class=highlight],.listingblock>.content>pre[class^="highlight "]{background:#f7f7f8}
+.literalblock.output pre{color:#f7f7f8;background:rgba(0,0,0,.9)}
+.listingblock>.content{position:relative}
+.listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:inherit;opacity:.5}
+.listingblock:hover code[data-lang]::before{display:block}
+.listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:inherit;opacity:.5}
+.listingblock.terminal pre .command:not([data-prompt])::before{content:"$"}
+.listingblock pre.highlightjs{padding:0}
+.listingblock pre.highlightjs>code{padding:1em;border-radius:4px}
+.listingblock pre.prettyprint{border-width:0}
+.prettyprint{background:#f7f7f8}
+pre.prettyprint .linenums{line-height:1.45;margin-left:2em}
+pre.prettyprint li{background:none;list-style-type:inherit;padding-left:0}
+pre.prettyprint li code[data-lang]::before{opacity:1}
+pre.prettyprint li:not(:first-child) code[data-lang]::before{display:none}
+table.linenotable{border-collapse:separate;border:0;margin-bottom:0;background:none}
+table.linenotable td[class]{color:inherit;vertical-align:top;padding:0;line-height:inherit;white-space:normal}
+table.linenotable td.code{padding-left:.75em}
+table.linenotable td.linenos,pre.pygments .linenos{border-right:1px solid;opacity:.35;padding-right:.5em;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
+pre.pygments span.linenos{display:inline-block;margin-right:.75em}
+.quoteblock{margin:0 1em 1.25em 1.5em;display:table}
+.quoteblock:not(.excerpt)>.title{margin-left:-1.5em;margin-bottom:.75em}
+.quoteblock blockquote,.quoteblock p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}
+.quoteblock blockquote{margin:0;padding:0;border:0}
+.quoteblock blockquote::before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}
+.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
+.quoteblock .attribution{margin-top:.75em;margin-right:.5ex;text-align:right}
+.verseblock{margin:0 1em 1.25em}
+.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans-serif;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
+.verseblock pre strong{font-weight:400}
+.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
+.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
+.quoteblock .attribution br,.verseblock .attribution br{display:none}
+.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
+.quoteblock.abstract blockquote::before,.quoteblock.excerpt blockquote::before,.quoteblock .quoteblock blockquote::before{display:none}
+.quoteblock.abstract blockquote,.quoteblock.abstract p,.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{line-height:1.6;word-spacing:0}
+.quoteblock.abstract{margin:0 1em 1.25em;display:block}
+.quoteblock.abstract>.title{margin:0 0 .375em;font-size:1.15em;text-align:center}
+.quoteblock.excerpt>blockquote,.quoteblock .quoteblock{padding:0 0 .25em 1em;border-left:.25em solid #dddddf}
+.quoteblock.excerpt,.quoteblock .quoteblock{margin-left:0}
+.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{color:inherit;font-size:1.0625rem}
+.quoteblock.excerpt .attribution,.quoteblock .quoteblock .attribution{color:inherit;font-size:.85rem;text-align:left;margin-right:0}
+p.tableblock:last-child{margin-bottom:0}
+td.tableblock>.content{margin-bottom:1.25em;word-wrap:anywhere}
+td.tableblock>.content>:last-child{margin-bottom:-1.25em}
+table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
+table.grid-all>*>tr>*{border-width:1px}
+table.grid-cols>*>tr>*{border-width:0 1px}
+table.grid-rows>*>tr>*{border-width:1px 0}
+table.frame-all{border-width:1px}
+table.frame-ends{border-width:1px 0}
+table.frame-sides{border-width:0 1px}
+table.frame-none>colgroup+*>:first-child>*,table.frame-sides>colgroup+*>:first-child>*{border-top-width:0}
+table.frame-none>:last-child>:last-child>*,table.frame-sides>:last-child>:last-child>*{border-bottom-width:0}
+table.frame-none>*>tr>:first-child,table.frame-ends>*>tr>:first-child{border-left-width:0}
+table.frame-none>*>tr>:last-child,table.frame-ends>*>tr>:last-child{border-right-width:0}
+table.stripes-all>*>tr,table.stripes-odd>*>tr:nth-of-type(odd),table.stripes-even>*>tr:nth-of-type(even),table.stripes-hover>*>tr:hover{background:#f8f8f7}
+th.halign-left,td.halign-left{text-align:left}
+th.halign-right,td.halign-right{text-align:right}
+th.halign-center,td.halign-center{text-align:center}
+th.valign-top,td.valign-top{vertical-align:top}
+th.valign-bottom,td.valign-bottom{vertical-align:bottom}
+th.valign-middle,td.valign-middle{vertical-align:middle}
+table thead th,table tfoot th{font-weight:bold}
+tbody tr th{background:#f7f8f7}
+tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
+p.tableblock>code:only-child{background:none;padding:0}
+p.tableblock{font-size:1em}
+ol{margin-left:1.75em}
+ul li ol{margin-left:1.5em}
+dl dd{margin-left:1.125em}
+dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
+li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
+ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none}
+ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em}
+ul.unstyled,ol.unstyled{margin-left:0}
+li>p:empty:only-child::before{content:"";display:inline-block}
+ul.checklist>li>p:first-child{margin-left:-1em}
+ul.checklist>li>p:first-child>.fa-square-o:first-child,ul.checklist>li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em}
+ul.checklist>li>p:first-child>input[type=checkbox]:first-child{margin-right:.25em}
+ul.inline{display:flex;flex-flow:row wrap;list-style:none;margin:0 0 .625em -1.25em}
+ul.inline>li{margin-left:1.25em}
+.unstyled dl dt{font-weight:400;font-style:normal}
+ol.arabic{list-style-type:decimal}
+ol.decimal{list-style-type:decimal-leading-zero}
+ol.loweralpha{list-style-type:lower-alpha}
+ol.upperalpha{list-style-type:upper-alpha}
+ol.lowerroman{list-style-type:lower-roman}
+ol.upperroman{list-style-type:upper-roman}
+ol.lowergreek{list-style-type:lower-greek}
+.hdlist>table,.colist>table{border:0;background:none}
+.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
+td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
+td.hdlist1{font-weight:bold;padding-bottom:1.25em}
+td.hdlist2{word-wrap:anywhere}
+.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
+.colist td:not([class]):first-child{padding:.4em .75em 0;line-height:1;vertical-align:top}
+.colist td:not([class]):first-child img{max-width:none}
+.colist td:not([class]):last-child{padding:.25em 0}
+.thumb,.th{line-height:0;display:inline-block;border:4px solid #fff;box-shadow:0 0 0 1px #ddd}
+.imageblock.left{margin:.25em .625em 1.25em 0}
+.imageblock.right{margin:.25em 0 1.25em .625em}
+.imageblock>.title{margin-bottom:0}
+.imageblock.thumb,.imageblock.th{border-width:6px}
+.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
+.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
+.image.left{margin-right:.625em}
+.image.right{margin-left:.625em}
+a.image{text-decoration:none;display:inline-block}
+a.image object{pointer-events:none}
+sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
+sup.footnote a,sup.footnoteref a{text-decoration:none}
+sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
+#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
+#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0}
+#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em}
+#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none;margin-left:-1.05em}
+#footnotes .footnote:last-of-type{margin-bottom:0}
+#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
+div.unbreakable{page-break-inside:avoid}
+.big{font-size:larger}
+.small{font-size:smaller}
+.underline{text-decoration:underline}
+.overline{text-decoration:overline}
+.line-through{text-decoration:line-through}
+.aqua{color:#00bfbf}
+.aqua-background{background:#00fafa}
+.black{color:#000}
+.black-background{background:#000}
+.blue{color:#0000bf}
+.blue-background{background:#0000fa}
+.fuchsia{color:#bf00bf}
+.fuchsia-background{background:#fa00fa}
+.gray{color:#606060}
+.gray-background{background:#7d7d7d}
+.green{color:#006000}
+.green-background{background:#007d00}
+.lime{color:#00bf00}
+.lime-background{background:#00fa00}
+.maroon{color:#600000}
+.maroon-background{background:#7d0000}
+.navy{color:#000060}
+.navy-background{background:#00007d}
+.olive{color:#606000}
+.olive-background{background:#7d7d00}
+.purple{color:#600060}
+.purple-background{background:#7d007d}
+.red{color:#bf0000}
+.red-background{background:#fa0000}
+.silver{color:#909090}
+.silver-background{background:#bcbcbc}
+.teal{color:#006060}
+.teal-background{background:#007d7d}
+.white{color:#bfbfbf}
+.white-background{background:#fafafa}
+.yellow{color:#bfbf00}
+.yellow-background{background:#fafa00}
+span.icon>.fa{cursor:default}
+a span.icon>.fa{cursor:inherit}
+.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
+.admonitionblock td.icon .icon-note::before{content:"\f05a";color:#19407c}
+.admonitionblock td.icon .icon-tip::before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
+.admonitionblock td.icon .icon-warning::before{content:"\f071";color:#bf6900}
+.admonitionblock td.icon .icon-caution::before{content:"\f06d";color:#bf3400}
+.admonitionblock td.icon .icon-important::before{content:"\f06a";color:#bf0000}
+.conum[data-value]{display:inline-block;color:#fff!important;background:rgba(0,0,0,.8);border-radius:50%;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
+.conum[data-value] *{color:#fff!important}
+.conum[data-value]+b{display:none}
+.conum[data-value]::after{content:attr(data-value)}
+pre .conum[data-value]{position:relative;top:-.125em}
+b.conum *{color:inherit!important}
+.conum:not([data-value]):empty{display:none}
+dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
+h1,h2,p,td.content,span.alt,summary{letter-spacing:-.01em}
+p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
+p,blockquote,dt,td.content,td.hdlist1,span.alt,summary{font-size:1.0625rem}
+p{margin-bottom:1.25rem}
+.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
+.exampleblock>.content{background:#fffef7;border-color:#e0e0dc;box-shadow:0 1px 4px #e0e0dc}
+.print-only{display:none!important}
+@page{margin:1.25cm .75cm}
+@media print{*{box-shadow:none!important;text-shadow:none!important}
+html{font-size:80%}
+a{color:inherit!important;text-decoration:underline!important}
+a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
+a[href^="http:"]:not(.bare)::after,a[href^="https:"]:not(.bare)::after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
+abbr[title]{border-bottom:1px dotted}
+abbr[title]::after{content:" (" attr(title) ")"}
+pre,blockquote,tr,img,object,svg{page-break-inside:avoid}
+thead{display:table-header-group}
+svg{max-width:100%}
+p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
+h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
+#header,#content,#footnotes,#footer{max-width:none}
+#toc,.sidebarblock,.exampleblock>.content{background:none!important}
+#toc{border-bottom:1px solid #dddddf!important;padding-bottom:0!important}
+body.book #header{text-align:center}
+body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em}
+body.book #header .details{border:0!important;display:block;padding:0!important}
+body.book #header .details span:first-child{margin-left:0!important}
+body.book #header .details br{display:block}
+body.book #header .details br+span::before{content:none!important}
+body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
+body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}
+.listingblock code[data-lang]::before{display:block}
+#footer{padding:0 .9375em}
+.hide-on-print{display:none!important}
+.print-only{display:block!important}
+.hide-for-print{display:none!important}
+.show-for-print{display:inherit!important}}
+@media amzn-kf8,print{#header>h1:first-child{margin-top:1.25rem}
+.sect1{padding:0!important}
+.sect1+.sect1{border:0}
+#footer{background:none}
+#footer-text{color:rgba(0,0,0,.6);font-size:.9em}}
+@media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}}
+</style>
+<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
+<head>
+<!-- <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=DotGothic16"> -->
+<!-- <link rel="icon" type="image/x-icon" href="https://raw.githubusercontent.com/A-Larsen/math-notes/refs/heads/main/favicon.png"> -->
+<!-- <link rel="icon" type="image/png" href="N2DE_favicon.png"/> -->
+<!-- <link rel="preconnect" href="https://fonts.googleapis.com"> -->
+<!-- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> -->
+<!-- <link href="https://fonts.googleapis.com/css2?family=Abril+Fatface&display=swap" rel="stylesheet"> -->
+<style>
+
+/*--------------------------------------------------------------*/
+/*use '!important' to override default css used by asciidoctor*/
+/*--------------------------------------------------------------*/
+
+:root {
+    --gruvbox-black: #282828;
+    --gruvbox-black2: #1d2021;
+    --gruvbox-black3: #463f39;
+    --gruvbox-red: #fc7869;
+    --gruvbox-yellow: #fabd2f;
+    --gruvbox-white: #ebdbb2;
+    --gruvbox-white2: #a7a187;
+    --gruvbox-blue: #83a598;
+    --gruvbox-green: #b8bb26;
+    --gruvbox-bg1: #7c6f64;
+    --gruvbox-bg2: #665c54;
+
+}
+
+.title {
+  color: var(--gruvbox-red) !important;
+}
+
+blockquote {
+    color: var(--gruvbox-white) !important;
+}
+
+table {
+    margin: 0 auto !important;
+}
+
+.hdlist1 {
+  font-size: 1.3em;
+}
+
+cite {
+    color: var(--gruvbox-green) !important;
+}
+
+.tableblock {
+    background-color: inherit;
+    color: var(--gruvbox-white);
+    max-width: 95%;
+}
+
+.tableblock th {
+    background-color: var(--gruvbox-black3);
+    color: var(--gruvbox-white);
+    max-width: 97%;
+}
+
+code:not([data-lang]) {
+    background-color: var(--gruvbox-bg2) !important;
+    color: var(--gruvbox-white);
+    text-shadow: none;
+}
+
+.checklist {
+    text-align: left;
+    font-size: .8em;
+}
+
+.checklist li ul { margin-left: 3%;
+}
+
+#content, h1, pre {
+    border-radius: 8px !important;
+}
+
+#header, #content, #footnotes, #footer {
+  padding-left: 0 !important;
+  padding-right: 0 !important;
+}
+
+.api-type a:hover {
+    text-decoration: underline;
+}
+
+.api-type, .api-type a {
+    color: var(--gruvbox-green);
+    text-decoration: none;
+}
+
+pre {
+    border-style: solid !important;
+    border-color: white !important;
+    border-width: 2px !important;
+}
+
+h1 {
+   /* font-family: "DotGothic16", sans-serif !important;*/
+
+
+    background-color: var(--gruvbox-white2) !important;
+    color: var(--gruvbox-black) !important;
+}
+
+.admonitionblock > table td.content {
+    color: var(--gruvbox-white) !important;
+}
+
+/*
+html {
+    margin: 0;
+    height: 100%;
+    width: 100%;
+}
+
+
+*/
+/*html {*/
+
+body {
+    /*background: black url("background-image-space.jpeg") no-repeat fixed center;*/
+    /*background-color: black;*/
+    background-color: var(--gruvbox-black);
+    background-attachment: fixed;
+    background-size: cover;
+    overflow-y: scroll;
+    /*
+    margin: 0;
+    height: 100%;
+    width: 100%;
+    overflow: hidden;
+    */
+}
+
+
+/*
+body {
+    overflow-y: scroll;
+    background: rgba(0,0,0,0);
+    height: 100%;
+    margin: 2%;
+}
+*/
+
+#toc {
+    background-color: var(--gruvbox-black2) !important;
+    /*opacity: .9;*/
+}
+
+#toctitle {
+    color: var(--gruvbox-yellow);
+}
+
+a {
+    color: var(--gruvbox-bg1);
+}
+
+#content {
+    color: #ebdbb2;
+    background: var(--gruvbox-black);
+    /*opacity: .9;*/
+}
+
+#header > h1:nth-last-child(2) {
+    border-bottom: none !important;
+    background-color: rgba(0, 0, 0, .1);
+    padding-left: 2%;
+}
+
+.sect1 + .sect1 {
+  border-top: none !important;
+}
+
+.sect1 h2 {
+    background-size: cover;
+    background-attachment: fixed;
+    /*
+    border-bottom: 1px solid var(--gruvbox-white);
+    border-top: 1px solid var(--gruvbox-white);
+    */
+    padding: 10px;
+    text-align: left;
+    color: var(--gruvbox-red) !important;
+    /*
+    text-shadow: 1px 1px 1px var(--gruvbox-black);
+    text-shadow: 3px 3px 3px var(--gruvbox-black);
+    text-shadow: 5px 5px 5px var(--gruvbox-blue);
+    */
+}
+
+h3, h4, h5 {
+    /*
+    text-shadow: 1px 1px 1px var(--gruvbox-white);
+    */
+}
+
+h3 {
+  color: var(--gruvbox-red) !important;
+}
+
+h4 {
+  color: var(--gruvbox-yellow) !important;
+}
+
+h5 {
+  color: #83a598 !important;
+}
+
+h2 ~ *:not(h1) {
+  margin-left: .5em;
+}
+
+.pygments {
+    max-width: 97% !important;
+    white-space: pre;
+    overflow-x: scroll !important;
+}
+
+::before {
+    /*makes sure that the programming language that show up on hover is within
+      pre tag*/
+    padding-right: 3%;
+}
+
+@media screen and (max-width: 800px) {
+    .checklist li ul {
+        margin-left: 6% !important;
+    }
+    #toc {
+        padding-left: 10px;
+    }
+
+    footer {
+        margin-bottom: 10px !important;
+    }
+    html {
+        margin-bottom: 10px !important;
+    }
+}
+@media screen and (max-width: 535px) {
+    h3 ~ *:not(h2):not(h3) {
+      margin-left: 0 !important;
+    }
+
+    h4 ~ *:not(h2):not(h3):not(.h3):not(h4) {
+      margin-left: 0 !important;
+    }
+    h5 ~ *:not(h2):not(h3):not(.h3):not(h4):not(.h4):not(h5) {
+      margin-left: 0 !important;
+    }
+
+    footer {
+        margin-bottom: 10px !important;
+    }
+    html {
+        margin-bottom: 10px !important;
+    }
+}
+h3 ~ *:not(h2):not(h3) {
+  margin-left: 1.5em;
+}
+
+h4 ~ *:not(h2):not(h3):not(.h3):not(h4) {
+  margin-left: 2em;
+}
+h5 ~ *:not(h2):not(h3):not(.h3):not(h4):not(.h4):not(h5) {
+  margin-left: 2.5em;
+}
+
+
+.sect1 h2 {
+
+    /*
+    background: linear-gradient(
+        to bottom,
+        rgba(251, 189, 47, 0.2), /* yellow */
+        rgba(0, 0, 0, 0.4)       /* black */
+    );
+    */
+    /*opacity: .9;*/
+  }
+
+#preamble p{
+  padding-left: 10px;
+  color: var(--gruvbox-white) !important;
+}
+
+#footer {
+    max-width: 62.5em !important;
+    padding-left: 10px !important;
+    text-align: center;
+}
+
+.logo img {
+    display: block !important;
+    margin-left: auto !important;
+    margin-right: auto !important;
+}
+
+#header > h1:first-child {
+  margin-top: .3em !important;
+  padding-top: .2em !important;
+  text-align: center;
+}
+
+footer {
+    max-width: 62.5em;
+    margin-left: auto;
+    margin-right: auto;
+    display: block;
+
+}
+
+details[open] > summary::before {
+   /* display: none;*/
+    border-top: none;
+    content: "â–¼";
+    margin-top: -12px;
+}
+
+.example.stemblock {
+    border: solid;
+    font-size: 2vw;
+    max-width: 40%;
+    margin: auto;
+}
+
+.center {
+    max-width: 500px;
+    display: flex;
+    justify-content: center;
+}
+
+.highlight {
+    color: var(--gruvbox-yellow)
+}
+
+.border {
+    padding: 4px;
+    border: 2px solid rgba(255, 0, 0, .3);
+}
+
+.dull {
+    opacity: 40%;
+}
+
+.inline {
+    margin-right: 5%;
+    display: inline-block;
+}
+
+
+</style>
+
+</head>
+
+<script src="docinfo.js"></script>
+
+
+</head>
+<body class="article">
+<div id="header">
+<h1>CLONEMON</h1>
+</div>
+<div id="content">
+<div id="preamble">
+<div class="sectionbody">
+<div class="paragraph">
+<p>Clonemon is a game I am working on that uses my custom game engine called the
+nyquist2DEngine. The source code for the game engine is not included in this
+repository.</p>
+</div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_controls">Controls</h2>
+<div class="sectionbody">
+<table class="tableblock frame-all grid-all stretch">
+<colgroup>
+<col style="width: 50%;">
+<col style="width: 50%;">
+</colgroup>
+<thead>
+<tr>
+<th class="tableblock halign-left valign-top">key / keycombo</th>
+<th class="tableblock halign-left valign-top">control</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">enter/j</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">select</p></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">cntrl + ~</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">enter terminal</p></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">w</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">move up</p></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">a</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">move left</p></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">s</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">move down</p></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">d</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">move right</p></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">k</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">select up</p></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">h</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">select left</p></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">j</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">select down</p></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">l</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">select right</p></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">esc</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">pause</p></td>
+</tr>
+</tbody>
+</table>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_terminal_commands">Terminal commands</h2>
+<div class="sectionbody">
+<table class="tableblock frame-all grid-all stretch">
+<colgroup>
+<col style="width: 50%;">
+<col style="width: 50%;">
+</colgroup>
+<thead>
+<tr>
+<th class="tableblock halign-left valign-top">command</th>
+<th class="tableblock halign-left valign-top">action</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">c.bag()</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">change to bag global state</p></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">c.world()</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">chanage to world global state</p></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">c.enter_text()</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">chanage to enter text global state</p></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">c.start()</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">chanage to start global state</p></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">c.choice_select()</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">chanage to choice select global state</p></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">c.loadsave()</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">chanage to loadsave global state</p></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">c.party()</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">chanage to party gobal state</p></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">c.battle()</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">chanage to party gobal state</p></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">c.setState()</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">change to a substate ex. setState(states.battle.moveSelect)</p></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">lua &lt;command&gt;</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">enter custom lua</p></td>
+</tr>
+</tbody>
+</table>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_terminal_substates">Terminal substates</h2>
+<div class="sectionbody">
+<div class="paragraph">
+<p>Every substate only works while running in the correct global state. For
+example any <code>states.battle</code> state only works in the battle global state.</p>
+</div>
+<table class="tableblock frame-all grid-all stretch">
+<colgroup>
+<col style="width: 20%;">
+<col style="width: 80%;">
+</colgroup>
+<thead>
+<tr>
+<th class="tableblock halign-left valign-top">substate</th>
+<th class="tableblock halign-left valign-top">action</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">states.battle.moveSelect</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">pick from your clonemons available moves</p></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">states.battle.doSelect</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">decide what your clonemon will do in battle</p></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">states.battle.enterBattle</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">starts the battle intro</p></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">states.party.doWhat</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">decide what you want to do with choosen clonemon</p></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">states.party.switch</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">switch clonemon to a different party slot</p></td>
+</tr>
+</tbody>
+</table>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_installation">Installation</h2>
+<div class="sectionbody">
+<div class="paragraph">
+<p>Put the binaries create from building the nyquist2DEnine engine or mapeditor in
+the root directory. The "*.so" or ".dll" files created from building the
+nyquist2DEngine extensions in the root of the extensions folder.</p>
+</div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_running">Running</h2>
+<div class="sectionbody">
+<div class="paragraph">
+<p>run these commands to initialize the game</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre>./scripts/init
+./scripts/sourceme</pre>
+</div>
+</div>
+<div class="paragraph">
+<p>you can do</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre>./n2de_dev</pre>
+</div>
+</div>
+<div class="paragraph">
+<p>or</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre>./n2de</pre>
+</div>
+</div>
+<div class="paragraph">
+<p>run run the game</p>
+</div>
+</div>
+</div>
+</div>
+<script type="text/x-mathjax-config">
+MathJax.Hub.Config({
+  messageStyle: "none",
+  tex2jax: {
+    inlineMath: [["\\(", "\\)"]],
+    displayMath: [["\\[", "\\]"]],
+    ignoreClass: "nostem|nolatexmath"
+  },
+  asciimath2jax: {
+    delimiters: [["\\$", "\\$"]],
+    ignoreClass: "nostem|noasciimath"
+  },
+  TeX: { equationNumbers: { autoNumber: "none" } }
+})
+MathJax.Hub.Register.StartupHook("AsciiMath Jax Ready", function () {
+  MathJax.InputJax.AsciiMath.postfilterHooks.Add(function (data, node) {
+    if ((node = data.script.parentNode) && (node = node.parentNode) && node.classList.contains("stemblock")) {
+      data.math.root.display = "block"
+    }
+    return data
+  })
+})
+</script>
+<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.9/MathJax.js?config=TeX-MML-AM_HTMLorMML"></script>
+</body>
+</html>
\ No newline at end of file
diff --git a/resources/data/test/map1.dat b/resources/data/test/map1.dat
new file mode 100644 (file)
index 0000000..5e5d7af
Binary files /dev/null and b/resources/data/test/map1.dat differ
diff --git a/resources/data/test/map1.hcd b/resources/data/test/map1.hcd
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/resources/data/test/map4.dat b/resources/data/test/map4.dat
new file mode 100644 (file)
index 0000000..2aed4e6
Binary files /dev/null and b/resources/data/test/map4.dat differ
diff --git a/resources/data/test/map5.dat b/resources/data/test/map5.dat
new file mode 100644 (file)
index 0000000..660993c
Binary files /dev/null and b/resources/data/test/map5.dat differ
diff --git a/resources/data/test/map6.dat b/resources/data/test/map6.dat
new file mode 100644 (file)
index 0000000..8d9bc9b
Binary files /dev/null and b/resources/data/test/map6.dat differ
diff --git a/resources/data/test/objects1.dat b/resources/data/test/objects1.dat
new file mode 100644 (file)
index 0000000..20afe71
Binary files /dev/null and b/resources/data/test/objects1.dat differ
diff --git a/resources/data/test/objects4.dat b/resources/data/test/objects4.dat
new file mode 100644 (file)
index 0000000..cd078fb
Binary files /dev/null and b/resources/data/test/objects4.dat differ
diff --git a/resources/data/test/objects5.dat b/resources/data/test/objects5.dat
new file mode 100644 (file)
index 0000000..c77af7e
Binary files /dev/null and b/resources/data/test/objects5.dat differ
diff --git a/resources/data/test/objects6.dat b/resources/data/test/objects6.dat
new file mode 100644 (file)
index 0000000..4af888b
Binary files /dev/null and b/resources/data/test/objects6.dat differ
diff --git a/resources/fonts/NotoSansMono-Regular.ttf b/resources/fonts/NotoSansMono-Regular.ttf
new file mode 100644 (file)
index 0000000..dd3e6d0
Binary files /dev/null and b/resources/fonts/NotoSansMono-Regular.ttf differ
diff --git a/resources/images/Route_111.png b/resources/images/Route_111.png
new file mode 100644 (file)
index 0000000..1161c7a
Binary files /dev/null and b/resources/images/Route_111.png differ
diff --git a/resources/images/Untitled.xcf b/resources/images/Untitled.xcf
new file mode 100644 (file)
index 0000000..35cd2e4
Binary files /dev/null and b/resources/images/Untitled.xcf differ
diff --git a/resources/images/axolotl.png b/resources/images/axolotl.png
new file mode 100644 (file)
index 0000000..573dea6
Binary files /dev/null and b/resources/images/axolotl.png differ
diff --git a/resources/images/bag.png b/resources/images/bag.png
new file mode 100644 (file)
index 0000000..6237149
Binary files /dev/null and b/resources/images/bag.png differ
diff --git a/resources/images/battle_ui.png b/resources/images/battle_ui.png
new file mode 100644 (file)
index 0000000..6ac6eff
Binary files /dev/null and b/resources/images/battle_ui.png differ
diff --git a/resources/images/berry_one.png b/resources/images/berry_one.png
new file mode 100644 (file)
index 0000000..e10b1a0
Binary files /dev/null and b/resources/images/berry_one.png differ
diff --git a/resources/images/border1.png b/resources/images/border1.png
new file mode 100644 (file)
index 0000000..7bdd2f9
Binary files /dev/null and b/resources/images/border1.png differ
diff --git a/resources/images/border1_unselected.png b/resources/images/border1_unselected.png
new file mode 100644 (file)
index 0000000..39391cb
Binary files /dev/null and b/resources/images/border1_unselected.png differ
diff --git a/resources/images/border2..png b/resources/images/border2..png
new file mode 100644 (file)
index 0000000..239aa5f
Binary files /dev/null and b/resources/images/border2..png differ
diff --git a/resources/images/border2.png b/resources/images/border2.png
new file mode 100644 (file)
index 0000000..c7644d2
Binary files /dev/null and b/resources/images/border2.png differ
diff --git a/resources/images/border2_unselected.png b/resources/images/border2_unselected.png
new file mode 100644 (file)
index 0000000..63da96e
Binary files /dev/null and b/resources/images/border2_unselected.png differ
diff --git a/resources/images/capybara.png b/resources/images/capybara.png
new file mode 100644 (file)
index 0000000..8e3441e
Binary files /dev/null and b/resources/images/capybara.png differ
diff --git a/resources/images/character_spritesheet_1.png b/resources/images/character_spritesheet_1.png
new file mode 100644 (file)
index 0000000..a04ac13
Binary files /dev/null and b/resources/images/character_spritesheet_1.png differ
diff --git a/resources/images/choice_select_test_one.png b/resources/images/choice_select_test_one.png
new file mode 100644 (file)
index 0000000..a80a9e2
Binary files /dev/null and b/resources/images/choice_select_test_one.png differ
diff --git a/resources/images/choice_select_test_two.png b/resources/images/choice_select_test_two.png
new file mode 100644 (file)
index 0000000..c8a482d
Binary files /dev/null and b/resources/images/choice_select_test_two.png differ
diff --git a/resources/images/clonemon.png b/resources/images/clonemon.png
new file mode 100644 (file)
index 0000000..c7a8f40
Binary files /dev/null and b/resources/images/clonemon.png differ
diff --git a/resources/images/clonemon_battle_grass.png b/resources/images/clonemon_battle_grass.png
new file mode 100644 (file)
index 0000000..c6bd568
Binary files /dev/null and b/resources/images/clonemon_battle_grass.png differ
diff --git a/resources/images/clonemon_battle_ui.png b/resources/images/clonemon_battle_ui.png
new file mode 100644 (file)
index 0000000..aa051b4
Binary files /dev/null and b/resources/images/clonemon_battle_ui.png differ
diff --git a/resources/images/clonemon_battle_ui_grass.png b/resources/images/clonemon_battle_ui_grass.png
new file mode 100644 (file)
index 0000000..d5d01aa
Binary files /dev/null and b/resources/images/clonemon_battle_ui_grass.png differ
diff --git a/resources/images/clonemon_party.png b/resources/images/clonemon_party.png
new file mode 100644 (file)
index 0000000..81534b0
Binary files /dev/null and b/resources/images/clonemon_party.png differ
diff --git a/resources/images/generic_house_one.png b/resources/images/generic_house_one.png
new file mode 100644 (file)
index 0000000..4ff39c9
Binary files /dev/null and b/resources/images/generic_house_one.png differ
diff --git a/resources/images/gradient.png b/resources/images/gradient.png
new file mode 100644 (file)
index 0000000..a0d6de5
Binary files /dev/null and b/resources/images/gradient.png differ
diff --git a/resources/images/house_two.png b/resources/images/house_two.png
new file mode 100644 (file)
index 0000000..17afe6a
Binary files /dev/null and b/resources/images/house_two.png differ
diff --git a/resources/images/keyboard_lower.png b/resources/images/keyboard_lower.png
new file mode 100644 (file)
index 0000000..263bd46
Binary files /dev/null and b/resources/images/keyboard_lower.png differ
diff --git a/resources/images/keyboard_upper.png b/resources/images/keyboard_upper.png
new file mode 100644 (file)
index 0000000..509c96d
Binary files /dev/null and b/resources/images/keyboard_upper.png differ
diff --git a/resources/images/lion_back.png b/resources/images/lion_back.png
new file mode 100644 (file)
index 0000000..24fa4b7
Binary files /dev/null and b/resources/images/lion_back.png differ
diff --git a/resources/images/loadsave.png b/resources/images/loadsave.png
new file mode 100644 (file)
index 0000000..5b8d4db
Binary files /dev/null and b/resources/images/loadsave.png differ
diff --git a/resources/images/logo.png b/resources/images/logo.png
new file mode 100644 (file)
index 0000000..fbca230
Binary files /dev/null and b/resources/images/logo.png differ
diff --git a/resources/images/map_indoor_1.png b/resources/images/map_indoor_1.png
new file mode 100644 (file)
index 0000000..42efb5b
Binary files /dev/null and b/resources/images/map_indoor_1.png differ
diff --git a/resources/images/map_indoor_2.png b/resources/images/map_indoor_2.png
new file mode 100644 (file)
index 0000000..1839eed
Binary files /dev/null and b/resources/images/map_indoor_2.png differ
diff --git a/resources/images/map_outdoor1.png b/resources/images/map_outdoor1.png
new file mode 100644 (file)
index 0000000..e560cba
Binary files /dev/null and b/resources/images/map_outdoor1.png differ
diff --git a/resources/images/map_outdoor_1.png b/resources/images/map_outdoor_1.png
new file mode 100644 (file)
index 0000000..13386ae
Binary files /dev/null and b/resources/images/map_outdoor_1.png differ
diff --git a/resources/images/map_outdoor_10.png b/resources/images/map_outdoor_10.png
new file mode 100644 (file)
index 0000000..6f2d3e1
Binary files /dev/null and b/resources/images/map_outdoor_10.png differ
diff --git a/resources/images/map_outdoor_2.png b/resources/images/map_outdoor_2.png
new file mode 100644 (file)
index 0000000..d5248cc
Binary files /dev/null and b/resources/images/map_outdoor_2.png differ
diff --git a/resources/images/map_outdoor_3.png b/resources/images/map_outdoor_3.png
new file mode 100644 (file)
index 0000000..bcdeedb
Binary files /dev/null and b/resources/images/map_outdoor_3.png differ
diff --git a/resources/images/map_outdoor_4.png b/resources/images/map_outdoor_4.png
new file mode 100644 (file)
index 0000000..dbf5a7d
Binary files /dev/null and b/resources/images/map_outdoor_4.png differ
diff --git a/resources/images/map_outdoor_5.png b/resources/images/map_outdoor_5.png
new file mode 100644 (file)
index 0000000..417c5d4
Binary files /dev/null and b/resources/images/map_outdoor_5.png differ
diff --git a/resources/images/map_outdoor_6.png b/resources/images/map_outdoor_6.png
new file mode 100644 (file)
index 0000000..334664a
Binary files /dev/null and b/resources/images/map_outdoor_6.png differ
diff --git a/resources/images/map_outdoor_7.png b/resources/images/map_outdoor_7.png
new file mode 100644 (file)
index 0000000..4e8a0ab
Binary files /dev/null and b/resources/images/map_outdoor_7.png differ
diff --git a/resources/images/map_outdoor_8.png b/resources/images/map_outdoor_8.png
new file mode 100644 (file)
index 0000000..cbd5c77
Binary files /dev/null and b/resources/images/map_outdoor_8.png differ
diff --git a/resources/images/map_outdoor_9.png b/resources/images/map_outdoor_9.png
new file mode 100644 (file)
index 0000000..c0b88bf
Binary files /dev/null and b/resources/images/map_outdoor_9.png differ
diff --git a/resources/images/menu_items.png b/resources/images/menu_items.png
new file mode 100644 (file)
index 0000000..a936fda
Binary files /dev/null and b/resources/images/menu_items.png differ
diff --git a/resources/images/nyquist.png b/resources/images/nyquist.png
new file mode 100644 (file)
index 0000000..d6a3a54
Binary files /dev/null and b/resources/images/nyquist.png differ
diff --git a/resources/images/nyquist.xcf b/resources/images/nyquist.xcf
new file mode 100644 (file)
index 0000000..b87eac1
Binary files /dev/null and b/resources/images/nyquist.xcf differ
diff --git a/resources/images/nyquist2.png b/resources/images/nyquist2.png
new file mode 100644 (file)
index 0000000..e3467bd
Binary files /dev/null and b/resources/images/nyquist2.png differ
diff --git a/resources/images/nyquist_spritesheet.png b/resources/images/nyquist_spritesheet.png
new file mode 100644 (file)
index 0000000..76e7570
Binary files /dev/null and b/resources/images/nyquist_spritesheet.png differ
diff --git a/resources/images/nyquist_spritesheet3.png b/resources/images/nyquist_spritesheet3.png
new file mode 100644 (file)
index 0000000..7f92c14
Binary files /dev/null and b/resources/images/nyquist_spritesheet3.png differ
diff --git a/resources/images/outdoors_backgorund_one.png b/resources/images/outdoors_backgorund_one.png
new file mode 100644 (file)
index 0000000..f1ae161
Binary files /dev/null and b/resources/images/outdoors_backgorund_one.png differ
diff --git a/resources/images/owl.png b/resources/images/owl.png
new file mode 100644 (file)
index 0000000..abf88f4
Binary files /dev/null and b/resources/images/owl.png differ
diff --git a/resources/images/pause.png b/resources/images/pause.png
new file mode 100644 (file)
index 0000000..f1abe87
Binary files /dev/null and b/resources/images/pause.png differ
diff --git a/resources/images/potion_one.png b/resources/images/potion_one.png
new file mode 100644 (file)
index 0000000..630d5d9
Binary files /dev/null and b/resources/images/potion_one.png differ
diff --git a/resources/images/potion_two.png b/resources/images/potion_two.png
new file mode 100644 (file)
index 0000000..f128de8
Binary files /dev/null and b/resources/images/potion_two.png differ
diff --git a/resources/images/spritesheet_indoors_1.backup.png b/resources/images/spritesheet_indoors_1.backup.png
new file mode 100644 (file)
index 0000000..4888ad8
Binary files /dev/null and b/resources/images/spritesheet_indoors_1.backup.png differ
diff --git a/resources/images/spritesheet_indoors_1.png b/resources/images/spritesheet_indoors_1.png
new file mode 100644 (file)
index 0000000..5982238
Binary files /dev/null and b/resources/images/spritesheet_indoors_1.png differ
diff --git a/resources/images/spritesheet_indoors_1.xcf b/resources/images/spritesheet_indoors_1.xcf
new file mode 100644 (file)
index 0000000..964a05b
Binary files /dev/null and b/resources/images/spritesheet_indoors_1.xcf differ
diff --git a/resources/images/spritesheet_indoors_1_backup.png b/resources/images/spritesheet_indoors_1_backup.png
new file mode 100644 (file)
index 0000000..4850d18
Binary files /dev/null and b/resources/images/spritesheet_indoors_1_backup.png differ
diff --git a/resources/images/spritesheet_indoors_1_backup.xcf b/resources/images/spritesheet_indoors_1_backup.xcf
new file mode 100644 (file)
index 0000000..0d8740b
Binary files /dev/null and b/resources/images/spritesheet_indoors_1_backup.xcf differ
diff --git a/resources/images/spritesheet_outdoor_1.png b/resources/images/spritesheet_outdoor_1.png
new file mode 100644 (file)
index 0000000..93745fa
Binary files /dev/null and b/resources/images/spritesheet_outdoor_1.png differ
diff --git a/resources/images/spritesheet_partybox.png b/resources/images/spritesheet_partybox.png
new file mode 100644 (file)
index 0000000..a4eb7c8
Binary files /dev/null and b/resources/images/spritesheet_partybox.png differ
diff --git a/resources/images/tileset_indoors_1.png b/resources/images/tileset_indoors_1.png
new file mode 100644 (file)
index 0000000..50c0b5b
Binary files /dev/null and b/resources/images/tileset_indoors_1.png differ
diff --git a/resources/images/tileset_outside_1.png b/resources/images/tileset_outside_1.png
new file mode 100644 (file)
index 0000000..6d8ab84
Binary files /dev/null and b/resources/images/tileset_outside_1.png differ
diff --git a/resources/images/town4.png b/resources/images/town4.png
new file mode 100644 (file)
index 0000000..7ec2d7f
Binary files /dev/null and b/resources/images/town4.png differ
diff --git a/resources/images/tree_one.png b/resources/images/tree_one.png
new file mode 100644 (file)
index 0000000..6232e96
Binary files /dev/null and b/resources/images/tree_one.png differ
diff --git a/resources/images/tree_two.png b/resources/images/tree_two.png
new file mode 100644 (file)
index 0000000..42d12d7
Binary files /dev/null and b/resources/images/tree_two.png differ
diff --git a/resources/images/vs.png b/resources/images/vs.png
new file mode 100644 (file)
index 0000000..c0005c4
Binary files /dev/null and b/resources/images/vs.png differ
diff --git a/resources/images/vs2.png b/resources/images/vs2.png
new file mode 100644 (file)
index 0000000..86230a7
Binary files /dev/null and b/resources/images/vs2.png differ
diff --git a/resources/images/vs3.png b/resources/images/vs3.png
new file mode 100644 (file)
index 0000000..7a9e310
Binary files /dev/null and b/resources/images/vs3.png differ
diff --git a/resources/images/well.png b/resources/images/well.png
new file mode 100644 (file)
index 0000000..34a7665
Binary files /dev/null and b/resources/images/well.png differ
diff --git a/resources/startup.ini b/resources/startup.ini
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/resources/test.db b/resources/test.db
new file mode 100644 (file)
index 0000000..10dc719
Binary files /dev/null and b/resources/test.db differ
diff --git a/resources/wavs/TOD.mp3 b/resources/wavs/TOD.mp3
new file mode 100644 (file)
index 0000000..0f7f814
Binary files /dev/null and b/resources/wavs/TOD.mp3 differ
diff --git a/resources/wavs/battle1.wav b/resources/wavs/battle1.wav
new file mode 100644 (file)
index 0000000..a09a669
Binary files /dev/null and b/resources/wavs/battle1.wav differ
diff --git a/resources/wavs/battle1.wav.asd b/resources/wavs/battle1.wav.asd
new file mode 100644 (file)
index 0000000..bbe6b85
Binary files /dev/null and b/resources/wavs/battle1.wav.asd differ
diff --git a/resources/wavs/breakdown1.wav b/resources/wavs/breakdown1.wav
new file mode 100644 (file)
index 0000000..c12923d
Binary files /dev/null and b/resources/wavs/breakdown1.wav differ
diff --git a/resources/wavs/breakdown1.wav.asd b/resources/wavs/breakdown1.wav.asd
new file mode 100644 (file)
index 0000000..33d1a47
Binary files /dev/null and b/resources/wavs/breakdown1.wav.asd differ
diff --git a/resources/wavs/chipped.wav b/resources/wavs/chipped.wav
new file mode 100644 (file)
index 0000000..fabd395
Binary files /dev/null and b/resources/wavs/chipped.wav differ
diff --git a/resources/wavs/chipped.wav.asd b/resources/wavs/chipped.wav.asd
new file mode 100644 (file)
index 0000000..1d50801
Binary files /dev/null and b/resources/wavs/chipped.wav.asd differ
diff --git a/resources/wavs/chipped_dip.wav b/resources/wavs/chipped_dip.wav
new file mode 100644 (file)
index 0000000..db0e949
Binary files /dev/null and b/resources/wavs/chipped_dip.wav differ
diff --git a/resources/wavs/chipped_dip.wav.asd b/resources/wavs/chipped_dip.wav.asd
new file mode 100644 (file)
index 0000000..a31cf44
Binary files /dev/null and b/resources/wavs/chipped_dip.wav.asd differ
diff --git a/resources/wavs/clonks.wav b/resources/wavs/clonks.wav
new file mode 100644 (file)
index 0000000..8f22c6e
Binary files /dev/null and b/resources/wavs/clonks.wav differ
diff --git a/resources/wavs/destructo.wav b/resources/wavs/destructo.wav
new file mode 100644 (file)
index 0000000..10702f2
Binary files /dev/null and b/resources/wavs/destructo.wav differ
diff --git a/resources/wavs/good.wav b/resources/wavs/good.wav
new file mode 100644 (file)
index 0000000..6cf6b2f
Binary files /dev/null and b/resources/wavs/good.wav differ
diff --git a/resources/wavs/good.wav.asd b/resources/wavs/good.wav.asd
new file mode 100644 (file)
index 0000000..a6b5a82
Binary files /dev/null and b/resources/wavs/good.wav.asd differ
diff --git a/resources/wavs/hihat.wav b/resources/wavs/hihat.wav
new file mode 100644 (file)
index 0000000..6309281
Binary files /dev/null and b/resources/wavs/hihat.wav differ
diff --git a/resources/wavs/intro.wav b/resources/wavs/intro.wav
new file mode 100644 (file)
index 0000000..4bf6379
Binary files /dev/null and b/resources/wavs/intro.wav differ
diff --git a/resources/wavs/kick.wav b/resources/wavs/kick.wav
new file mode 100644 (file)
index 0000000..138b997
Binary files /dev/null and b/resources/wavs/kick.wav differ
diff --git a/resources/wavs/melody.mp3 b/resources/wavs/melody.mp3
new file mode 100644 (file)
index 0000000..769f0c6
Binary files /dev/null and b/resources/wavs/melody.mp3 differ
diff --git a/resources/wavs/meta19.wav b/resources/wavs/meta19.wav
new file mode 100644 (file)
index 0000000..6f513f9
Binary files /dev/null and b/resources/wavs/meta19.wav differ
diff --git a/resources/wavs/meta19.wav.asd b/resources/wavs/meta19.wav.asd
new file mode 100644 (file)
index 0000000..ead76ae
Binary files /dev/null and b/resources/wavs/meta19.wav.asd differ
diff --git a/resources/wavs/mutate.wav b/resources/wavs/mutate.wav
new file mode 100644 (file)
index 0000000..8a10dd8
Binary files /dev/null and b/resources/wavs/mutate.wav differ
diff --git a/resources/wavs/mutate.wav.asd b/resources/wavs/mutate.wav.asd
new file mode 100644 (file)
index 0000000..cd62a3d
Binary files /dev/null and b/resources/wavs/mutate.wav.asd differ
diff --git a/resources/wavs/pianer1.wav b/resources/wavs/pianer1.wav
new file mode 100644 (file)
index 0000000..9e978dc
Binary files /dev/null and b/resources/wavs/pianer1.wav differ
diff --git a/resources/wavs/pianer1.wav.asd b/resources/wavs/pianer1.wav.asd
new file mode 100644 (file)
index 0000000..1805d9c
Binary files /dev/null and b/resources/wavs/pianer1.wav.asd differ
diff --git a/resources/wavs/rise.wav b/resources/wavs/rise.wav
new file mode 100644 (file)
index 0000000..848081c
Binary files /dev/null and b/resources/wavs/rise.wav differ
diff --git a/resources/wavs/rise.wav.asd b/resources/wavs/rise.wav.asd
new file mode 100644 (file)
index 0000000..2b8e5bb
Binary files /dev/null and b/resources/wavs/rise.wav.asd differ
diff --git a/resources/wavs/rise2.wav b/resources/wavs/rise2.wav
new file mode 100644 (file)
index 0000000..0ac811a
Binary files /dev/null and b/resources/wavs/rise2.wav differ
diff --git a/resources/wavs/rise3.wav b/resources/wavs/rise3.wav
new file mode 100644 (file)
index 0000000..d603572
Binary files /dev/null and b/resources/wavs/rise3.wav differ
diff --git a/resources/wavs/snare.wav b/resources/wavs/snare.wav
new file mode 100644 (file)
index 0000000..00adbaf
Binary files /dev/null and b/resources/wavs/snare.wav differ
diff --git a/resources/wavs/um_intro.wav b/resources/wavs/um_intro.wav
new file mode 100644 (file)
index 0000000..3bbba00
Binary files /dev/null and b/resources/wavs/um_intro.wav differ
diff --git a/resources/wavs/um_main.wav b/resources/wavs/um_main.wav
new file mode 100644 (file)
index 0000000..82f12f1
Binary files /dev/null and b/resources/wavs/um_main.wav differ
diff --git a/resources/wavs/you_are_gay.mp3 b/resources/wavs/you_are_gay.mp3
new file mode 100644 (file)
index 0000000..1efb39c
Binary files /dev/null and b/resources/wavs/you_are_gay.mp3 differ
diff --git a/scripts/bplate b/scripts/bplate
new file mode 100755 (executable)
index 0000000..4f0f06f
--- /dev/null
@@ -0,0 +1,224 @@
+#!/usr/bin/env bash
+
+function usage() {
+    # https://stackoverflow.com/questions/1835943/how-to-determine-function-name-from-inside-a-function
+    man "${0%/*}/man/bplate.1"
+}
+
+function new-ui() {
+
+local uis=()
+declare -A spritesheets
+declare -A states
+# local state="main"
+
+local ns=0
+for arg in $@; do
+    (( $# <= 0 ))&& break;
+    case $1 in
+        --ns)
+            ns=1
+            shift
+        ;;
+        --spritesheet)
+            spritesheets["$ui"]="$2"
+            shift 2
+        ;;
+
+        --state)
+            states["$ui"]="$2"
+            shift 2
+        ;;
+
+        *)
+            local ui=$1
+            uis+=("$1")
+            if ((ns == 0)); then
+                states["$1"]="main"
+            fi
+            ns=0
+            shift
+        ;;
+    esac
+
+done
+
+for ui in ${uis[@]}; do
+    if [[ -f ./uis/"${ui}.lua" ]] || [[ -d ./states/"${ui}" ]]; then 
+        echo "ui ${ui} exists" >&2
+        echo "skipping this ui" >&2
+        continue
+    fi
+    local spritesheet="${spritesheets[$ui]}"
+    local state="${states[$ui]}"
+    [[ ! -v states[$ui] ]]; hasState=$?
+    if [[ -v spritesheets[$ui] ]]; then
+
+    cat > ./uis/"${ui}".lua << EOF
+local ui = {}
+
+function ui:init(spritesheet, window_size, options)
+    setmetatable(ui, require("extensions.metatables.ui"))
+    ui:_init(spritesheet, window_size, "NotoSansMono-Regular.ttf", 12, options, function()
+    end)
+end
+
+function ui:startCallback()
+end
+
+function ui:update()
+end
+
+return ui
+EOF
+else
+    cat > ./uis/"${ui}".lua << EOF
+local ui = {}
+
+function ui:init(window_size, options)
+    setmetatable(ui, require("extensions.metatables.ui"))
+    ui:_init(nil, window_size, "NotoSansMono-Regular.ttf", 12, options, function()
+    end)
+end
+
+function ui:startCallback()
+end
+
+function ui:update()
+end
+
+return ui
+EOF
+    fi
+    if ((hasState)); then
+        mkdir ./states/"${ui}"
+        cat > ./states/"${ui}"/init.lua << EOF
+return {
+    main = require("states.${ui}.${state}");
+}
+EOF
+        cat >> ./states/init.lua << EOF
+states.${ui} = require("states.${ui}")
+EOF
+
+        cat > ./states/"${ui}"/"${state}".lua << EOF
+return State:new(
+    function()
+        if nyq.keypress.back then
+            Pop_state()
+        end
+    end
+)
+EOF
+    fi
+
+    cat >> ./uis/init.lua << EOF
+uis.${ui} = require("uis.${ui}")
+EOF
+    matches=($(grep -nE "^uis.\w*:init(.*)" ./init.lua | cut -f1 -d:))
+    lastmatch="${matches[-1]}"
+
+    if [[ -v spritesheets[$ui] ]]; then
+        sed -i "${lastmatch}a\uis.${ui}:init(\"${spritesheet}\", unscaled_window_size, {scale = Ex.Config.resolution_scale})" ./init.lua
+    else
+        sed -i "${lastmatch}a\uis.${ui}:init(unscaled_window_size, {scale = Ex.Config.resolution_scale})" ./init.lua
+    fi
+done
+} # function end
+
+function new-state() {
+declare -A states
+
+for arg in $@; do
+    (( $# <= 0 )) && break;
+
+    case $1 in
+        --ui)
+            states["$2"]="$3"
+            shift 3
+        ;;
+    esac
+done
+
+for ui in ${!states[@]}; do
+    local state=${states[$ui]}
+    cat > ./states/"${ui}"/"${state}".lua << EOF
+return State:new(
+    function()
+        if nyq.keypress.back then
+            Pop_state()
+        end
+    end
+)
+EOF
+    matches=($(grep -nE "\s.*\w.*=" ./states/"${ui}"/init.lua | cut -f1 -d:))
+    lastmatch="${matches[-1]}"
+    sed -i "${lastmatch}a\    ${state} = require(\"states.${ui}.${state}\");" ./states/"${ui}"/init.lua
+done
+
+}
+
+function rm-state() {
+declare -A states
+
+for arg in $@; do
+    (( $# <= 0 )) && break;
+
+    case $1 in
+        --ui)
+            states["$2"]="$3"
+            shift 3
+        ;;
+    esac
+done
+
+for ui in ${!states[@]}; do
+    local state="${states[$ui]}"
+    sed -i "/${state} = require/d" ./states/${ui}/init.lua
+    rm -rf ./states/${ui}/${state}.lua
+done
+}
+
+function rm-ui() {
+local uis=()
+
+for arg in $@; do
+    uis+=("$arg")
+done
+
+for ui in ${uis[@]}; do
+    sed -i "/^uis.${ui}:init(.*)/d" ./init.lua
+    sed -i "/uis.${ui} = require(\"uis.${ui}\")/d" ./uis/init.lua
+    sed -i "/states.${ui} = require(\"states.${ui}\")/d" ./states/init.lua
+    rm -rf ./states/"${ui}" ./uis/"${ui}.lua"
+done
+}
+
+for args in $@; do
+    case $args in 
+        new-ui)
+            shift
+            new-ui $@
+            exit
+        ;;
+        new-state)
+            shift
+            new-state $@
+            exit
+        ;;
+        rm-ui)
+            shift
+            rm-ui $@
+            exit
+        ;;
+        rm-state)
+            shift
+            rm-state $@
+            exit
+        ;;
+        -h|--help)
+            usage
+            exit
+        ;;
+    esac
+done
diff --git a/scripts/build b/scripts/build
new file mode 100755 (executable)
index 0000000..f29c697
--- /dev/null
@@ -0,0 +1,4 @@
+#!/usr/bin/env bash
+for file in $(ls -1) do
+    echo $file
+end
diff --git a/scripts/clear_depot_prep b/scripts/clear_depot_prep
new file mode 100755 (executable)
index 0000000..53314a3
--- /dev/null
@@ -0,0 +1,10 @@
+#!/usr/bin/env bash
+
+steam_dir="./steam/ContentBuilder/content/windows"
+[[ ! -d "$steam_dir" ]] && mkdir -p "$steam_dir"
+cd "$steam_dir" || exit
+folders=$(find . -maxdepth 1 -type d -not -name '.' -not -name '..')
+files=$(find . -maxdepth 1 -type f)
+
+rm -rf $folders
+rm -rf $files
diff --git a/scripts/database b/scripts/database
new file mode 100755 (executable)
index 0000000..4bd24d4
--- /dev/null
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+
+if [[ "$1" == "schema" ]]; then
+    if [[ ! -z "$2" ]]; then
+        sqlite3 ./resources/test.db ".schema" | grep $2
+    else
+        sqlite3 ./resources/test.db ".schema"
+    fi
+fi
diff --git a/scripts/db_clonemon_test b/scripts/db_clonemon_test
new file mode 100755 (executable)
index 0000000..16b3310
--- /dev/null
@@ -0,0 +1,165 @@
+#!/usr/bin/env bash
+
+sqlite3 ./resources/test.db << EOF
+DELETE FROM clonemon_types;
+DELETE FROM clonemon;
+UPDATE sqlite_sequence SET seq = 0 WHERE name = "clonemon_types";
+UPDATE sqlite_sequence SET seq = 0 WHERE name = "clonemon";
+
+INSERT INTO clonemon_types (name, ability, base_attack, base_hp, base_speed, 
+                            base_defense, base_special_defense, 
+                            base_special_attack,
+                            image)
+VALUES (
+-- name
+"thorp",
+
+-- ability
+"spam",
+
+-- base_attack
+100,
+
+-- base_hp
+25,
+
+-- base_speed
+10,
+
+-- base_defense
+50,
+
+-- base_special_defense
+50,
+
+-- base_special_attack
+50,
+
+-- image
+"spritesheet_thorp.png"
+),
+(
+-- name
+"shela",
+
+-- ability
+"throw",
+
+-- base_attack
+100,
+
+-- base_hp
+25,
+
+-- base_speed
+10,
+
+-- base_defense
+50,
+
+-- base_special_defense
+50,
+
+-- base_special_attack
+50,
+
+-- image
+"spritesheet_shela.png"
+);
+
+INSERT INTO clonemon (type_id, name, gender, level, attack, max_hp,
+                      remaining_hp, speed, defense, accuracy, special_defense,
+                      special_attack, box_number, box_position, spritesheet)
+VALUES (
+-- type_id
+1,
+
+-- name
+"thorper",
+
+-- gender
+0,
+
+-- level
+20,
+
+-- attack
+0,
+
+-- max_hp
+10,
+
+-- remaining_hp
+10,
+
+-- speed
+20,
+
+-- defense
+20,
+
+-- accuracy
+20,
+
+-- special_defense
+20,
+
+
+-- special_attack
+20,
+
+-- box_number
+1,
+
+-- box_position
+1,
+
+-- spritesheet
+"spritesheet_1.png"
+),
+(
+-- type_id
+2,
+
+-- name
+"shela",
+
+-- gender
+1,
+
+-- level
+22,
+
+-- attack
+0,
+
+-- max_hp
+10,
+
+-- remaining_hp
+10,
+
+-- speed
+20,
+
+-- defense
+20,
+
+-- accuracy
+20,
+
+-- special_defense
+20,
+
+-- special_attack
+20,
+
+-- box_number
+1,
+
+-- box_position
+2,
+
+--spritesheet
+"spritesheet_2.png");
+EOF
diff --git a/scripts/db_players_test b/scripts/db_players_test
new file mode 100755 (executable)
index 0000000..e41533e
--- /dev/null
@@ -0,0 +1,24 @@
+#!/usr/bin/env bash
+#
+sqlite3 ./resources/test.db << EOF
+DELETE FROM people;
+DELETE FROM players;
+
+INSERT INTO people (age, name, level, spritesheet)
+VALUES (44, "joe", 18, "thing.png");
+
+INSERT INTO people (age, name, level, spritesheet)
+VALUES (100, "jim", 2, "something.png");
+
+INSERT INTO people (age, name, level, spritesheet)
+VALUES (1, "jam", 20, "nothing.png");
+
+INSERT INTO players(uuid, person_id)
+VALUES (1, 1);
+
+INSERT INTO players(uuid, person_id)
+VALUES (2, 2);
+
+INSERT INTO players(uuid, person_id)
+VALUES (3, 3);
+EOF
diff --git a/scripts/dbconfig b/scripts/dbconfig
new file mode 100755 (executable)
index 0000000..b474051
--- /dev/null
@@ -0,0 +1,3 @@
+#!wine ./n2de.exe
+local database = require("extensions.database")
+local config = require("config")
diff --git a/scripts/init b/scripts/init
new file mode 100755 (executable)
index 0000000..c1a5d43
--- /dev/null
@@ -0,0 +1,3 @@
+#!/usr/bin/env bash
+
+[[ ! -d .cache/formats/ ]] && mkdir -p .cache/formats/
diff --git a/scripts/man/bplate.1 b/scripts/man/bplate.1
new file mode 100644 (file)
index 0000000..3105b64
--- /dev/null
@@ -0,0 +1,96 @@
+.TH bplate "3" "January 2024" "Nyquist2DEngine 0.0.0.1" "User Commands"
+.SH NAME
+bplate \- helps create boilerplate for codebase
+.SH SYNOPSIS
+.B bplate
+.B rm-state
+.RB [ \--ui
+.IR ui 
+.IR state ] 
+\&...
+.PP
+.B bplate
+.B new-state
+.RB [ \--ui
+.IR ui 
+.IR state ] 
+\&...
+.PP
+.B bplate
+.B new-ui 
+.RB [ 
+.RB [ \-\-ns ]
+.IR ui 
+.RB [ \-\-spritesheet
+.IR spritesheet ] 
+.RB [ \-\-state
+.IR state ]]
+\&...
+.PP
+.B bplate
+.B rm-ui 
+.IR ui
+\&...
+.SH DESCRIPTION
+.TP
+.B new-ui
+.PP
+.in +3n
+create new ui(s) and and state for each ui called "main"
+you can also specify the state name with
+.B --state
+.in
+.TP
+.B rm-ui
+removes ui(s)
+.TP
+.B new-state
+creates new state(s)
+.TP
+.B rm-state
+removes state(s)
+.SH OPTIONS
+.NH  
+.B
+new-ui
+.RS
+.TP
+.BI \-\-spritesheet " spritesheet"
+spritesheet to use for the ui
+.TP
+.BI \-\-state " state"
+specific the name of the first state to be created
+.RE
+.NH  
+.B
+rm-state
+.NH
+.B
+new-state
+.RS
+.TP
+.BI \-\-ui " ui"
+specify ui to to add or remove a state from
+.RE
+.SH EXAMPLES
+create a ui "one" with spritesheet "sup", ui two with no spritesheet, ui three
+with spritesheet hey and then ui four with no spritesheet and no state
+.PP
+Ex.
+.in +5n
+.EX
+$ bplate new-ui one --spritesheet sup two three --spritesheet hey --ns four
+.EE
+.in
+.PP
+remove ui one two three and four and states that may be associated with them
+.PP
+Ex.
+.in +5n
+.EX
+$ bplate rm-ui one two three four
+.EE
+.in
+.SH AUTHOR
+.AU
+Written by Austin Michael Larsen to work with the nyquist2DEngine
diff --git a/scripts/mydefaults b/scripts/mydefaults
new file mode 100755 (executable)
index 0000000..f2e141f
--- /dev/null
@@ -0,0 +1,27 @@
+#!/usr/bin/env sh
+
+sqlite3 ./resources/test.db <<EOF
+UPDATE keyboard_mappings SET
+    move_north = "W",
+    move_east = "D",
+    move_south = "S",
+    move_west = "A",
+    move_up = "K",
+    move_right = "L",
+    move_down = "J",
+    move_left = "H",
+    _select = "Return",
+    back = "P",
+    pause = "Tab",
+    hotkey = "X"
+WHERE id = 1;
+
+UPDATE config SET
+    controller = "none",
+    fullscreen =  0,
+    resolution_scale = 5,
+    speed = 7
+WHERE id = 1;
+.print "finished"
+EOF
+
diff --git a/scripts/pipeline b/scripts/pipeline
new file mode 100755 (executable)
index 0000000..56396ba
--- /dev/null
@@ -0,0 +1,10 @@
+#!/usr/bin/env bash
+#
+cd ./steam/ContentBuilder/scripts/
+steamcmd +login "${1}" +quit
+sed -i "4s/.*/    \"Desc\" \"${2}\"/" ./app_build_2762580.vdf
+steamcmd +runscript << EOF
+login "$1"
+run_app_build $PWD/app_build_2762580.vdf
+quit
+EOF
diff --git a/scripts/prepare_for_depot b/scripts/prepare_for_depot
new file mode 100755 (executable)
index 0000000..ff23ba2
--- /dev/null
@@ -0,0 +1,54 @@
+#!/usr/bin/env bash
+
+rm -rf "./resources/test.db"
+
+windows_dir=./steam/ContentBuilder/content/windows
+steamdeck_dir=./steam/ContentBuilder/content/steamdeck
+
+folder_ignore=('steam' 'scripts' 'docs' '.git' 'old')
+file_ignore=('.gitignore' "n2de_dev.exe")
+
+folder_strings=()
+file_strings=()
+
+for a in ${folder_ignore[@]}; do
+    folder_strings+=("-not -name $a")
+done
+
+for b in ${file_ignore[@]}; do
+    file_strings+=("-not -name $b")
+done
+
+# folders=$(find . -maxdepth 1 -type d ${folder_strings[@]} -not -name '.' -not -name '..')
+# files=$(find . -maxdepth 1 -type f ${file_strings[@]} -not -name '.' -not -name '..')
+
+folders=($(find . -maxdepth 1 -type d ${folder_strings[@]} -not -name '.' -not -name '..'))
+files=($(find . -maxdepth 1 -type f ${file_strings[@]} -not -name '.' -not -name '..'))
+
+# cp -r $folders $files $steamdeck_dir
+
+# cp -r $folders $files $windows_dir
+
+for file in ${files[@]}; do
+    if [[ "$file" =~ .lua$ ]]; then
+        luac5.4 -o $windows_dir/$file $file
+    else
+        cp $file $windows_dir
+    fi
+done
+
+for folder in ${folders[@]}; do
+    # echo $folder
+    files=($(find $folder -type f))
+    for file in ${files[@]}; do
+        path="${windows_dir}$(echo ${file%/*} | cut -b 2-)"
+        if [[ $file =~ .lua$ ]]; then
+
+            [[ ! -d "$path" ]] && mkdir -p "$path"
+            luac5.4 -o "${path}/${file##*/}" "$file"
+        else
+            [[ ! -d "$path" ]] && mkdir -p "$path"
+            cp "$file" "$path"
+        fi
+    done
+done
diff --git a/scripts/resetdb b/scripts/resetdb
new file mode 100755 (executable)
index 0000000..13e1ef0
--- /dev/null
@@ -0,0 +1,3 @@
+#!wine ./n2de.exe
+os.remove("./resources/test.db")
+require("extensions")
diff --git a/scripts/search_lua_files b/scripts/search_lua_files
new file mode 100755 (executable)
index 0000000..c36d9fc
--- /dev/null
@@ -0,0 +1,2 @@
+#!/usr/bin/env bash
+grep -R --include "*.lua" "\<$1\>"
diff --git a/scripts/sourceme b/scripts/sourceme
new file mode 100755 (executable)
index 0000000..49db58d
--- /dev/null
@@ -0,0 +1,2 @@
+#!/usr/bin/env zsh
+export WINEDLLOVERRIDES="*d3d9,*d3d10,*d3d10_1,*d3d10core,*d3d11,*dxgi=b"
diff --git a/scripts/windows_sourceme b/scripts/windows_sourceme
new file mode 100644 (file)
index 0000000..5434b7d
--- /dev/null
@@ -0,0 +1,4 @@
+#!/usr/bin/env zsh
+alias git="git.exe"
+alias make="make.exe"
+alias gdb="gdb.exe"
diff --git a/states/bag/init.lua b/states/bag/init.lua
new file mode 100644 (file)
index 0000000..1656d94
--- /dev/null
@@ -0,0 +1,3 @@
+return {
+    main = require("states.bag.main");
+}
diff --git a/states/bag/main.lua b/states/bag/main.lua
new file mode 100644 (file)
index 0000000..b0fdd0f
--- /dev/null
@@ -0,0 +1,21 @@
+return State:new(
+    function()
+        if nyq.keypress.back then
+            Pop_state()
+        end
+        if nyq.keypress.move_right then
+            ui.vars.type_selected = (ui.vars.type_selected % ui.vars.type_section_max) + 1
+            ui.vars.selected = 1
+        elseif nyq.keypress.move_left then
+            ui.vars.type_selected = ((ui.vars.type_selected - 1) % ui.vars.type_section_max)
+            if ui.vars.type_selected == 0 then
+                ui.vars.type_selected = ui.vars.type_section_max
+            end
+            ui.vars.selected = 1
+        elseif nyq.keypress.move_down and ui.vars.selected < ui.vars.selection_max then
+            ui.vars.selected = ui.vars.selected + 1
+        elseif nyq.keypress.move_up and ui.vars.selected > 1 then
+            ui.vars.selected = ui.vars.selected - 1
+        end
+    end
+)
diff --git a/states/battle/doSelect.lua b/states/battle/doSelect.lua
new file mode 100644 (file)
index 0000000..8b6791b
--- /dev/null
@@ -0,0 +1,102 @@
+return State:new(
+    function()
+        if (nyq.keypress.select) then
+            -- terminal.commands.world()
+            -- Pop_state()
+                if ui.vars.selected == 1 then
+                    Push_state()
+                    state = states.battle.moveSelect
+                elseif ui.vars.selected == 2 then
+                    Push_state()
+                    states.bag.main:reset()
+                    state = states.bag.main
+                    temps.ui = uis.bag
+                    params = {
+                        items = {
+                            [1] = {
+                                name = "book",
+                                description = "can read it",
+                                image = "",
+                                quantity = 1
+                            },
+                            [2] = {
+                                name = "cup",
+                                description = "drink things",
+                                image = "",
+                                quantity = 2
+                            },
+                            [3] = {
+                                name = "pencil",
+                                description = "write things",
+                                image = "",
+                                quantity = 3
+                            }
+                        },
+                        berries = {
+                            [1] = {
+                                name = "blueberry",
+                                description = "improves stats",
+                                image = "",
+                                quantity = 1
+                            },
+                            [2] = {
+                                name = "raseberry",
+                                description = "raises defense stat",
+                                image = "",
+                                quantity = 2
+                            },
+                            [3] = {
+                                name = "blackberry",
+                                description = "clears status effects",
+                                image = "",
+                                quantity = 3
+                            }
+                        },
+                        cloneballs = {
+                            [1] = {
+                                name = "ULTRA BALL",
+                                description = "A better Ball with a higher catch rate than a Great Ball",
+                                image = "",
+                                quantity = 1
+                            },
+                            [2] = {
+                                name = "NET BALL",
+                                description = "A BALL that works on WATER- and BUG- type Clonemon",
+                                image = "",
+                                quantity = 2
+                            },
+                        }
+                    }
+                elseif ui.vars.selected == 3 then
+                    Push_state()
+                    states.party.main:reset()
+                    params = {
+                        my_clonemon = my_clonemon
+                    }
+                    state = states.party.main
+                    temps.ui = uis.party
+                end
+        elseif (nyq.keypress.back) then
+            -- terminal.commands.world()
+            Pop_state()
+        elseif (nyq.keypress.move_right) then
+            if (ui.vars.selected + 1 <= 4) then
+                ui.vars.selected = ui.vars.selected + 1
+            end
+        elseif (nyq.keypress.move_left) then
+            if (ui.vars.selected - 1 > 0) then
+                ui.vars.selected = ui.vars.selected - 1
+            end
+        elseif (nyq.keypress.move_down) then
+            if (ui.vars.selected + 2 <= 4) then
+                ui.vars.selected = ui.vars.selected + 2
+            end
+        elseif (nyq.keypress.move_up) then
+            if (ui.vars.selected - 2 > 0) then
+                ui.vars.selected = ui.vars.selected - 2
+            end
+        end
+
+    end
+
+)
diff --git a/states/battle/enterBattle.lua b/states/battle/enterBattle.lua
new file mode 100644 (file)
index 0000000..4db6dda
--- /dev/null
@@ -0,0 +1,11 @@
+return State:new(function()
+    if ui.lines.narration.pages > 1 then
+        if nyq.keypress.select and ui.lines.narration.page_idx < ui.lines.narration.pages then
+            ui.lines.narration.page_idx = ui.lines.narration.page_idx + 1
+        end
+    else
+        if nyq.keypress.select then
+            state = states.battle.doSelect
+        end
+    end
+end)
diff --git a/states/battle/init.lua b/states/battle/init.lua
new file mode 100644 (file)
index 0000000..c484f14
--- /dev/null
@@ -0,0 +1,5 @@
+return {
+    moveSelect = require("states.battle.moveSelect");
+    enterBattle = require("states.battle.enterBattle");
+    doSelect = require("states.battle.doSelect");
+}
diff --git a/states/battle/moveSelect.lua b/states/battle/moveSelect.lua
new file mode 100644 (file)
index 0000000..613de9f
--- /dev/null
@@ -0,0 +1,30 @@
+return State:new(
+    function()
+        if (nyq.keypress.back) then
+            -- terminal.commands.world()
+            Pop_state()
+        elseif (nyq.keypress.move_right) then
+            if (ui.vars.selected + 1 <= 4) then
+                ui.vars.selected = ui.vars.selected + 1
+            end
+        elseif (nyq.keypress.move_left) then
+            if (ui.vars.selected - 1 > 0) then
+                ui.vars.selected = ui.vars.selected - 1
+            end
+        elseif (nyq.keypress.move_down) then
+            if (ui.vars.selected + 2 <= 4) then
+                ui.vars.selected = ui.vars.selected + 2
+            end
+        elseif (nyq.keypress.move_up) then
+            if (ui.vars.selected - 2 > 0) then
+                ui.vars.selected = ui.vars.selected - 2
+            end
+        -- elseif (nyq.keypress.change_moves1) then
+        --     -- battle_ui:addMoves(moves["pikachu"])
+        -- elseif (nyq.keypress.change_moves2) then
+        --     -- battle_ui:addMoves(moves["charzard"])
+        end
+
+    end
+
+)
diff --git a/states/choice_select/init.lua b/states/choice_select/init.lua
new file mode 100644 (file)
index 0000000..0754c75
--- /dev/null
@@ -0,0 +1,3 @@
+return {
+    main = require("states.choice_select.main")
+}
diff --git a/states/choice_select/main.lua b/states/choice_select/main.lua
new file mode 100644 (file)
index 0000000..1f97a39
--- /dev/null
@@ -0,0 +1,11 @@
+return State:new(
+    function()
+        if nyq.keypress.move_right and ui.vars.selected < ui.vars.max then
+            ui.vars.selected = ui.vars.selected + 1
+        elseif nyq.keypress.move_left and ui.vars.selected > 1 then
+            ui.vars.selected = ui.vars.selected - 1
+        elseif nyq.keypress.select then
+            print(ui.vars.selected)
+        end
+    end
+)
diff --git a/states/enter_text/init.lua b/states/enter_text/init.lua
new file mode 100644 (file)
index 0000000..eb0fa15
--- /dev/null
@@ -0,0 +1,3 @@
+return {
+    main = require("states.enter_text.main")
+}
diff --git a/states/enter_text/main.lua b/states/enter_text/main.lua
new file mode 100644 (file)
index 0000000..c928bcc
--- /dev/null
@@ -0,0 +1,72 @@
+return State:new(
+    function()
+        if ui.vars.string == nil then return end
+        local canInput = not ui.vars.full and string.len(ui.vars.string) < ui.vars.character_limit
+
+        if Ex.Config.controller ~= "none" then
+            if nyq.keypress.move_right  and ui.vars.cursor <= 31 then
+                ui.vars.cursor = ui.vars.cursor + 1
+            elseif nyq.keypress.move_left  and ui.vars.cursor > 0 then
+                if ui.vars.cursor == 32 then
+                    ui.vars.cursor = ui.vars.cursor - 2
+                else
+                    ui.vars.cursor = ui.vars.cursor - 1
+                end
+            elseif nyq.keypress.move_down and ui.vars.cursor < 22 then
+                ui.vars.cursor = ui.vars.cursor + 11
+            elseif nyq.keypress.move_up and ui.vars.cursor >= 11 then
+                ui.vars.cursor = ui.vars.cursor - 11
+            elseif nyq.keypress.back then
+                ui.vars.string = string.sub(ui.vars.string, 1, string.len(ui.vars.string) - 1)
+            elseif nyq.keypress.bag then
+                ui.vars.isUpper = not ui.vars.isUpper
+            elseif nyq.keypress.hotkey then
+                Pop_state()
+                -- terminal.commands.world()
+            end
+
+            local letter = ui.vars.letter_selection[ui.vars.cursor + 1]
+            if nyq.keypress.select then
+                if canInput and letter:match("[%a ]") then
+                    if ui.vars.isUpper then
+                        ui.vars.string = ui.vars.string .. string.upper(letter)
+                    else
+                        ui.vars.string = ui.vars.string .. letter
+                    end
+                elseif letter == ui.vars.key_backspace then
+                    ui.vars.string = string.sub(ui.vars.string, 1, string.len(ui.vars.string) - 1)
+                elseif letter == ui.vars.key_change_case then
+                    ui.vars.isUpper = not ui.vars.isUpper
+                elseif letter == ui.vars.key_done then
+                    -- terminal.commands.world()
+                    Pop_state()
+                end
+            end
+            -- print(ui.cursor)
+        else
+            if nyq.keypress.select then
+                -- terminal.commands.world()
+                Pop_state()
+            end
+        end
+
+        nyq.keypress.trigger = true;
+
+        if nyq.key then
+            if nyq.key == '\b' then
+                -- if string.len(uis.enter_text.string) > 0 then
+                if string.len(ui.vars.string) > 0 then
+                    -- ui.vars.string = string.sub(uis.enter_text.string, 1, string.len(ui.vars.string) - 1)
+                    ui.vars.string = string.sub(ui.vars.string, 1, string.len(ui.vars.string) - 1)
+                end
+                if uis.enter_text.full then
+                    ui.vars.full = false
+                end
+            else
+                if canInput then
+                    ui.vars.string = ui.vars.string .. nyq.key
+                end
+            end
+        end
+    end
+)
diff --git a/states/init.lua b/states/init.lua
new file mode 100644 (file)
index 0000000..01cd328
--- /dev/null
@@ -0,0 +1,13 @@
+states = {}
+states.battle = require("states.battle")
+states.world = require("states.world")
+states.choice_select = require("states.choice_select")
+states.start = require("states.start")
+states.loadsave = require("states.loadsave")
+states.enter_text = require("states.enter_text")
+states.bag = require("states.bag")
+states.party = require("states.party")
+states.start_menu = require("states.start_menu")
+states.settings = require("states.settings")
+states.mapping = require("states.mapping")
+states.partybox = require("states.partybox")
diff --git a/states/loadsave/init.lua b/states/loadsave/init.lua
new file mode 100644 (file)
index 0000000..bff519d
--- /dev/null
@@ -0,0 +1,3 @@
+return {
+    main = require("states.loadsave.main");
+}
diff --git a/states/loadsave/main.lua b/states/loadsave/main.lua
new file mode 100644 (file)
index 0000000..c1ec72b
--- /dev/null
@@ -0,0 +1,52 @@
+return State:new(
+    function()
+        if nyq.keypress.select then
+            if #players == 0 then
+                print("go to player creation")
+            elseif ui.selected == 1 then
+                player = Ex.Database.getFromUUID("players", players[ui.selected2].uuid)
+                print("loading player:")
+                for k, v in pairs(player) do 
+                    print(k, v)
+                end
+            elseif ui.selected == 2 then
+                print("go to player creation")
+            end
+            local menu_items = {
+                [1] = { name = "Map", },
+                [2] = { name = "Clonemon", },
+                [3] = { name = "bag", },
+                [4] = { name = "Player", },
+                [5] = { name = "Save", },
+                [6] = { name = "Settings", },
+                [7] = { name = "Quit", }
+            }
+            params = {
+                menu_items = menu_items,
+                world_id = 1
+            }
+            temps.ui = uis.world
+            state = states.world.main
+        end
+        if #players > 0 then
+            if (nyq.keypress.move_down) then
+                if (ui.selected + 1 <= ui.menu_size) then
+                    ui.selected = ui.selected + 1
+                end
+            elseif (nyq.keypress.move_up) then
+                if (ui.selected - 1 > 0) then
+                    ui.selected = ui.selected - 1
+                end
+            elseif (nyq.keypress.move_right) then
+                if (ui.selected2 + 1 <= #players) then
+                    ui.selected2 = ui.selected2 + 1
+                end
+            elseif (nyq.keypress.move_left) then
+                if (ui.selected2 - 1 > 0) then
+                    ui.selected2 = ui.selected2 - 1
+                end
+            end
+        end
+    end
+)
+
diff --git a/states/mapping/init.lua b/states/mapping/init.lua
new file mode 100644 (file)
index 0000000..92bc654
--- /dev/null
@@ -0,0 +1,3 @@
+return {
+    main = require("states.mapping.main");
+}
diff --git a/states/mapping/main.lua b/states/mapping/main.lua
new file mode 100644 (file)
index 0000000..c935238
--- /dev/null
@@ -0,0 +1,116 @@
+return State:new(
+    function ()
+
+        nyq.keypress.trigger = true;
+        local option = ui.vars.select_options[ui.vars.selected]
+
+
+        if ui.vars.state == "apply" then
+            print("applying?")
+            local mappings = ui.vars.temp_settings
+            for k, v in pairs(ui.vars.temp_settings) do
+                if v.key == "___" then
+                    ui:notifySet("warning", "not all keys are mapped")
+                    ui.vars.state = "select input"
+                    ui.vars.isChangeingInput = false
+                    return
+                end
+            end
+
+            Ex.Database.update(params.type .. "_mappings", 1, {
+                move_north = mappings.move_north.key,
+                move_east = mappings.move_east.key,
+                move_south = mappings.move_south.key,
+                move_west = mappings.move_west.key,
+                move_up = mappings.move_up.key,
+                move_right = mappings.move_right.key,
+                move_down = mappings.move_down.key,
+                move_left = mappings.move_left.key,
+                _select = mappings.select.key,
+                back = mappings.back.key,
+                pause = mappings.pause.key,
+                hotkey = mappings.hotkey.key,
+            })
+            ui:notifySet("change", "mappings have been applied")
+            ui.vars.state = "select input"
+            ui.vars.isChangeingInput = false
+        elseif ui.vars.state == "select input" then
+            if nyq.keypress.back then
+                Pop_state()
+            end
+            if nyq.keypress.select then
+                if option.value then
+                    ui:setOptions(option.name)
+                    ui.vars.isChangeingInput = true
+                    ui.vars.state = "change input"
+                elseif option.name == "apply" then
+                    ui.vars.isChangeingInput = true
+                    ui.vars.state = "apply"
+                elseif option.name == "clear" then
+                    for k, v in pairs(ui.vars.temp_settings) do
+                        v.key = "___"
+                    end
+                    ui:setOptions()
+                elseif option.name == "go back" then
+                    Pop_state()
+                end
+            elseif nyq.keypress.move_down and (ui.vars.selected + 1 <= ui.vars.selection_max) then
+                ui.vars.selected = ui.vars.selected + 1
+            elseif nyq.keypress.move_up and (ui.vars.selected - 1 > 0) then
+                ui.vars.selected = ui.vars.selected - 1
+            end
+        elseif ui.vars.state == "change input" then
+            nyq.delay(10)
+            local key = nil
+
+            if (params.type == "keyboard") then
+                key = nyq.keypressCheck()
+            elseif (params.type == "gamepad") then
+                key = nyq.gamepadCheck(0)
+            end
+
+
+            nyq.delay(10)
+            if key then
+                -- print(option.name, ui.temp_settings[option.name].key, key)
+                local found = false
+                for k, v in pairs(ui.vars.temp_settings) do
+                    if
+                        ((v.key == key) and
+                            (not
+                                (
+                                    (
+                                        (key:find("up") and option.name:find("north")) or
+                                        (key:find("right") and option.name:find("east")) or
+                                        (key:find("down") and option.name:find("south")) or
+                                        (key:find("left") and option.name:find("west"))
+                                    )
+                                    or
+                                    (
+                                        (key:find("up") and option.name:find("up")) or
+                                        (key:find("right") and option.name:find("right")) or
+                                        (key:find("down") and option.name:find("down")) or
+                                        (key:find("left") and option.name:find("left"))
+                                    )
+                                )
+                            )
+                        ) and
+                        (k ~= option.name)
+                    then
+                        found = true
+                        break
+                    end
+                end
+                if not found then
+                    ui.vars.temp_settings[option.name].key = key
+                else
+                    ui:notifySet("warning", "this key has already been mapped")
+                end
+            end
+            ui:setOptions()
+            ui.vars.state = "select input"
+            ui.vars.isChangeingInput = false
+        end
+
+    end
+)
diff --git a/states/party/doWhat.lua b/states/party/doWhat.lua
new file mode 100644 (file)
index 0000000..8f48957
--- /dev/null
@@ -0,0 +1,19 @@
+return State:new(
+    function()
+        if (nyq.keypress.select) then
+            if ui.vars.selected == ui:getSelectOptions()["Switch"] then
+                ui.vars.clonemon_switch = ui.vars.clonemon_selected
+                state = states.party.switch
+            end
+        elseif (nyq.keypress.back) then
+            ui.vars.selected = ui.vars.clonemon_selected
+            Pop_state()
+        elseif (nyq.keypress.move_down)  and ui.vars.selected < ui.vars.selection_max then
+            ui.vars.selected = ui.vars.selected + 1
+        elseif (nyq.keypress.move_up) and ui.vars.selected > 1 then
+            ui.vars.selected = ui.vars.selected - 1
+        end
+
+    end
+
+)
diff --git a/states/party/init.lua b/states/party/init.lua
new file mode 100644 (file)
index 0000000..1b9663a
--- /dev/null
@@ -0,0 +1,5 @@
+return {
+    main = require("states.party.main");
+    doWhat = require("states.party.doWhat");
+    switch = require("states.party.switch");
+}
diff --git a/states/party/main.lua b/states/party/main.lua
new file mode 100644 (file)
index 0000000..97d5f04
--- /dev/null
@@ -0,0 +1,39 @@
+return State:new(
+    function()
+        if (nyq.keypress.select) and ui.vars.selected ~= 7 then
+            Push_state()
+            ui.vars.clonemon_selected = ui.vars.selected
+            ui.vars.selected = 1
+            state = states.party.doWhat
+        elseif (nyq.keypress.select) and ui.vars.selected == 7 then
+            Pop_state()
+        elseif (nyq.keypress.back) then
+            -- terminal.commands.world()
+            Pop_state()
+        elseif (nyq.keypress.move_right) then
+            if ui.vars.selected == 6 then
+                ui.vars.selected = 7
+            elseif (ui.vars.selected + 1 <= 6) then
+                ui.vars.selected = ui.vars.selected + 1
+            end
+        elseif (nyq.keypress.move_left) then
+            if (ui.vars.selected - 1 > 0) then
+                ui.vars.selected = ui.vars.selected - 1
+            end
+        elseif (nyq.keypress.move_down) then
+            if ui.vars.selected == 5 or ui.vars.selected == 6 then
+                ui.vars.selected = 7
+            elseif (ui.vars.selected + 2 <= 6) then
+                ui.vars.selected = ui.vars.selected + 2
+            end
+        elseif (nyq.keypress.move_up) then
+            if ui.vars.selected == 7 then
+                ui.vars.selected = 6
+            elseif (ui.vars.selected - 2 > 0) then
+                ui.vars.selected = ui.vars.selected - 2
+            end
+        end
+
+    end
+
+)
diff --git a/states/party/switch.lua b/states/party/switch.lua
new file mode 100644 (file)
index 0000000..2aa0036
--- /dev/null
@@ -0,0 +1,33 @@
+return State:new(
+    function()
+        if (nyq.keypress.select) then
+            local temp = my_clonemon[ui.vars.clonemon_selected]
+            my_clonemon[ui.vars.clonemon_selected] = my_clonemon[ui.vars.clonemon_switch]
+            my_clonemon[ui.vars.clonemon_switch] = temp
+            params.my_clonemon = my_clonemon
+            ui.vars.selected = ui.vars.clonemon_switch
+            Pop_state()
+
+        elseif (nyq.keypress.back) then
+            Pop_state()
+        elseif (nyq.keypress.move_right) then
+            if (ui.vars.clonemon_switch + 1 <= 6) then
+                ui.vars.clonemon_switch = ui.vars.clonemon_switch + 1
+            end
+        elseif (nyq.keypress.move_left) then
+            if (ui.vars.clonemon_switch - 1 > 0) then
+                ui.vars.clonemon_switch = ui.vars.clonemon_switch - 1
+            end
+        elseif (nyq.keypress.move_down) then
+            if (ui.vars.clonemon_switch + 2 <= 6) then
+                ui.vars.clonemon_switch = ui.vars.clonemon_switch + 2
+            end
+        elseif (nyq.keypress.move_up) then
+            if (ui.vars.clonemon_switch - 2 > 0) then
+                ui.vars.clonemon_switch = ui.vars.clonemon_switch - 2
+            end
+        end
+
+    end
+
+)
diff --git a/states/partybox/init.lua b/states/partybox/init.lua
new file mode 100644 (file)
index 0000000..59783d8
--- /dev/null
@@ -0,0 +1,3 @@
+return {
+    main = require("states.partybox.main");
+}
diff --git a/states/partybox/main.lua b/states/partybox/main.lua
new file mode 100644 (file)
index 0000000..750acac
--- /dev/null
@@ -0,0 +1,21 @@
+return State:new(
+    function()
+        nyq.keypress.trigger = true;
+        if nyq.keypress.back then
+            Pop_state()
+        elseif nyq.keypress.move_right and ui.vars.selected + 1 <= 25 then
+            ui.vars.selected = ui.vars.selected + 1
+        elseif nyq.keypress.move_left and ui.vars.selected - 1 > 0 then
+            ui.vars.selected = ui.vars.selected - 1
+        elseif nyq.keypress.move_down and ui.vars.selected + 5 < 25 then
+            ui.vars.selected = ui.vars.selected + 5
+        elseif nyq.keypress.move_up and ui.vars.selected - 5 >= 0 then
+            ui.vars.selected = ui.vars.selected - 5
+        elseif nyq.keypress.move_east then
+            ui.vars.box_number = (ui.vars.box_number % 4) + 1
+        elseif nyq.keypress.move_west then
+            ui.vars.box_number = ui.vars.box_number - 1
+            if ui.vars.box_number < 1 then ui.vars.box_number = 4 end
+        end
+    end
+)
diff --git a/states/settings/init.lua b/states/settings/init.lua
new file mode 100644 (file)
index 0000000..bc0b6ea
--- /dev/null
@@ -0,0 +1,3 @@
+return {
+    main = require("states.settings.main");
+}
diff --git a/states/settings/main.lua b/states/settings/main.lua
new file mode 100644 (file)
index 0000000..6931321
--- /dev/null
@@ -0,0 +1,101 @@
+return State:new(
+    function ()
+
+        nyq.keypress.trigger = true;
+        local option = ui.vars.select_options[ui.vars.selected]
+        -- if nyq.keypress.back then
+        if not ui.vars.selected_submenu then
+            if nyq.keypress.back then
+                Pop_state()
+            elseif nyq.keypress.select then
+                if option.name == "go back" then
+                    Pop_state()
+                end
+                if option.name == "apply" then
+
+                    local speed = nil
+
+                    for k, v in pairs(Speed_options) do
+                        if v == ui.vars.temp_settings.speed then
+                            speed = k
+                            print(type(speed))
+                            print(speed)
+                        end
+                    end
+                    local t = {
+                        controller = ui.vars.temp_settings.controller,
+                        fullscreen = ui.vars.temp_settings.fullscreen and 1 or 0,
+                        resolution_scale = ui.vars.temp_settings.resolution_scale,
+                        speed = speed
+                    }
+                    Ex.Database.update("config", 1, t)
+
+                    Ex.Config.db.controller = t.controller
+
+                    ui:notifySet("change", "settings have been updated")
+                elseif option.name == "reset" then
+                    ui.vars.temp_settings = copy.shallow_copy({
+                        controller = Ex.Config.db.controller,
+                        fullscreen = Ex.Config.db.fullscreen,
+                        resolution_scale = Ex.Config.db.resolution_scale,
+                        speed = Speed_options[Ex.Config.db.speed],
+                    })
+                    ui:setOptions()
+                elseif option.name == "map controller" then
+                    params = {type = "gamepad"}
+                    Push_state()
+                    state = states.mapping.main
+                    temps.ui = uis.mapping
+                elseif option.name == "map keyboard" then
+                    params = {type = "keyboard"}
+                    Push_state()
+                    state = states.mapping.main
+                    temps.ui = uis.mapping
+                end
+                ui.vars.selected_submenu = option.options ~= nil
+            elseif nyq.keypress.move_down and (ui.vars.selected + 1 <= ui.vars.selection_max) then
+                ui.vars.selected = ui.vars.selected + 1
+            elseif nyq.keypress.move_up and (ui.vars.selected - 1 > 0) then
+                ui.vars.selected = ui.vars.selected - 1
+            end
+        else
+
+            if nyq.keypress.back then
+                ui.vars.selected_submenu = false
+            elseif nyq.keypress.select then
+                local val = option.options[ui.vars.subselected]
+                local bg_color = {r = 0, g = 0, b = 0, a = 0}
+                local fg_color = {r = 128, g = 128, b = 128, a = 0}
+                local fg_color_selected = {r = 255, g = 255, b = 255, a = 0}
+
+                if ui.vars.temp_settings[option.name] ~= val then
+                    v = tostring(val)
+                    if option.name == "speed" then
+                        v = "x" .. v
+                    end
+
+                    ui:textChange("menu", option.name, option.name .. ": " .. v, fg_color, bg_color)
+                    ui:textChange("menu", option.name .. " selected", option.name .. ": " .. v, fg_color_selected, bg_color)
+                    ui.vars.temp_settings[option.name] = val
+
+                    ui.vars.restart_required = false
+
+                    for k, v in pairs(ui.vars.temp_settings) do
+                        if (v ~= Ex.Config.db[k]) and (k ~= "controller") then
+                            ui.vars.restart_required = true
+                            break
+                        end
+                    end
+
+                end
+                ui.vars.subselected = 1
+                ui.vars.selected_submenu = false
+            elseif nyq.keypress.move_down and (ui.vars.subselected + 1 <= ui.vars.subselection_max) then
+                ui.vars.subselected = ui.vars.subselected + 1
+            elseif nyq.keypress.move_up and (ui.vars.subselected - 1 > 0) then
+                ui.vars.subselected = ui.vars.subselected - 1
+            end
+        end
+
+    end
+)
diff --git a/states/start/init.lua b/states/start/init.lua
new file mode 100644 (file)
index 0000000..a4dd167
--- /dev/null
@@ -0,0 +1,3 @@
+return {
+    main = require("states.start.main");
+}
diff --git a/states/start/main.lua b/states/start/main.lua
new file mode 100644 (file)
index 0000000..d500c96
--- /dev/null
@@ -0,0 +1,56 @@
+return State:new(
+    function ()
+        nyq.keypress.trigger = true;
+        if nyq.keypress.select then
+            -- terminal.commands.world()
+            players = Ex.Database.getAll("players") or {nil}
+            -- print("loading all players: \n")
+            -- for k, v in pairs(players) do
+            --     for k2, v2 in pairs(v) do
+            --         print(k2, v2)
+            --     end
+            --     print()
+            -- end
+            -- temps.ui = uis.loadsave
+            -- state = states.loadsave.main
+            state = states.start_menu.main
+            temps.ui = uis.start_menu
+        elseif nyq.keypress.change_moves1 then
+            -- pretend like this is a new file
+            -- Ex.Database.insert("moves", {
+            --     name = "NONE",
+            --     pp = 0,
+            --     power = 0
+            -- })
+            -- Ex.Database.insert("moves", {
+            --     name = "kick",
+            --     pp = 200,
+            --     power = 20
+            -- })
+            -- Ex.Database.insert("pokemon", {
+            --     name = "charzard",
+            --     type = 1,
+            --     gender = 0,
+            --     move_one_id = 1,
+            --     move_two_id = 1,
+
+            -- })
+            -- Ex.Database.insert("players", {
+            --     name = "ash",
+            --     uuid = Ex.Database.uuid(),
+            --     age = 33,
+            --     pokemon_id = 1
+            -- })
+            -- Ex.Database.insert("people", {
+            --     name = "blue",
+            --     age = 500,
+            --     level = 10,
+            --     spritesheet = "sup.png"
+            -- })
+            -- Ex.Database.insert("players", {
+            --     uuid Ex.Database.uuid(),
+            --     person_id = 2
+            -- })
+        end
+    end
+)
diff --git a/states/start_menu/init.lua b/states/start_menu/init.lua
new file mode 100644 (file)
index 0000000..0b94c41
--- /dev/null
@@ -0,0 +1,3 @@
+return {
+    main = require("states.start_menu.main")
+}
diff --git a/states/start_menu/main.lua b/states/start_menu/main.lua
new file mode 100644 (file)
index 0000000..88ec2a7
--- /dev/null
@@ -0,0 +1,19 @@
+return State:new(
+    function ()
+        nyq.keypress.trigger = true;
+        if nyq.keypress.select then
+            if ui.vars.selected == ui.vars.select_options["play"] then
+                state  = states.loadsave.main
+                temps.ui = uis.loadsave
+            elseif ui.vars.selected == ui.vars.select_options["settings"] then
+                Push_state()
+                state  = states.settings.main
+                temps.ui = uis.settings
+            end
+        elseif nyq.keypress.move_down and (ui.vars.selected + 1 <= ui.vars.selection_max) then
+            ui.vars.selected = ui.vars.selected + 1
+        elseif nyq.keypress.move_up and (ui.vars.selected - 1 > 0) then
+            ui.vars.selected = ui.vars.selected - 1
+        end
+    end
+)
diff --git a/states/world/init.lua b/states/world/init.lua
new file mode 100644 (file)
index 0000000..5c2fc66
--- /dev/null
@@ -0,0 +1,6 @@
+return  {
+    main = require("states.world.main");
+    pause = require("states.world.pause");
+    text = require("states.world.text");
+    option = require("states.world.option");
+}
diff --git a/states/world/main.lua b/states/world/main.lua
new file mode 100644 (file)
index 0000000..8e19714
--- /dev/null
@@ -0,0 +1,20 @@
+return State:new(
+    function()
+        nyq.keypress.trigger = false;
+        if (nyq.keypress.pause) then
+            state = states.world.pause
+        end
+
+        ui.ai:collisionUpdate()
+
+        if nyq.keypress.move_north then
+            ui.ai:travel("north")
+        elseif nyq.keypress.move_east then
+            ui.ai:travel("east")
+        elseif nyq.keypress.move_south then
+            ui.ai:travel("south")
+        elseif nyq.keypress.move_west then
+            ui.ai:travel("west")
+        end
+    end
+)
diff --git a/states/world/option.lua b/states/world/option.lua
new file mode 100644 (file)
index 0000000..9b94571
--- /dev/null
@@ -0,0 +1,12 @@
+return State:new(
+    function()
+        nyq.keypress.trigger = true;
+        if (nyq.keypress.select) then
+            state = states.world.text
+            ui.vars.text_pos  = ui.vars.text_pos + 1
+        elseif (nyq.keypress.move_down) and ui.vars.selected < ui.vars.selection_max then
+            ui.vars.selected = ui.vars.selected + 1
+        elseif (nyq.keypress.move_up)  and ui.vars.selected  > 1 then
+            ui.vars.selected = ui.vars.selected - 1
+        end
+end)
diff --git a/states/world/pause.lua b/states/world/pause.lua
new file mode 100644 (file)
index 0000000..fd44860
--- /dev/null
@@ -0,0 +1,124 @@
+return State:new(
+    function()
+        nyq.keypress.trigger = true;
+        if (nyq.keypress.select) then
+            if ui.vars.selected == 6 then
+                Push_state()
+                states.settings.main:reset()
+                state = states.settings.main
+                temps.ui = uis.settings
+            end
+            if ui.vars.selected == 7 then
+                nyq.exit()
+            end
+            if ui.vars.selected == 3 then
+                Push_state()
+                states.bag.main:reset()
+                state = states.bag.main
+                temps.ui = uis.bag
+                params = {
+                    items = {
+                        [1] = {
+                            name = "book",
+                            description = "can read it",
+                            image = "",
+                            quantity = 1
+                        },
+                        [2] = {
+                            name = "cup",
+                            description = "drink things",
+                            image = "",
+                            quantity = 2
+                        },
+                        [3] = {
+                            name = "pencil",
+                            description = "write things",
+                            image = "",
+                            quantity = 3
+                        }
+                    },
+                    berries = {
+                        [1] = {
+                            name = "blueberry",
+                            description = "improves stats",
+                            image = "",
+                            quantity = 1
+                        },
+                        [2] = {
+                            name = "raseberry",
+                            description = "raises defense stat",
+                            image = "",
+                            quantity = 2
+                        },
+                        [3] = {
+                            name = "blackberry",
+                            description = "clears status effects",
+                            image = "",
+                            quantity = 3
+                        }
+                    },
+                    cloneballs = {
+                        [1] = {
+                            name = "ULTRA BALL",
+                            description = "A better Ball with a higher catch rate than a Great Ball",
+                            image = "",
+                            quantity = 1
+                        },
+                        [2] = {
+                            name = "NET BALL",
+                            description = "A BALL that works on WATER- and BUG- type Clonemon",
+                            image = "",
+                            quantity = 2
+                        },
+                    }
+                }
+            end
+            if ui.vars.selected == 2 then
+                Push_state()
+                states.party.main:reset()
+                params = {
+                    my_clonemon = my_clonemon
+                }
+                state = states.party.main
+                temps.ui = uis.party
+
+            end
+            if ui.vars.selected == 4 then
+                Push_state()
+                params = {
+                    -- entry = "test",
+                    -- moves = moves.charzard,
+                    rivals_pokemon = {
+                        [1] = {
+                            name = "meowth",
+                        },
+                    },
+                    my_pokemon = {
+                        name = "charzard",
+                        moves = moves.charzard,
+                        level = 100,
+                    },
+                    player = {
+                        name = "nyquist"
+                    }
+                }
+                uis.world.paused = false
+                state = states.battle.enterBattle
+                temps.ui = uis.battle
+            end
+        end
+        if (nyq.keypress.pause) or (nyq.keypress.back) then
+            -- temps.state = states.world.main
+            state = states.world.main
+        end
+        if (nyq.keypress.move_down) then
+            if (ui.vars.selected + 1 <= ui.vars.menu_size) then
+                ui.vars.selected = ui.vars.selected + 1
+            end
+        elseif (nyq.keypress.move_up) then
+            if (ui.vars.selected - 1 > 0) then
+                ui.vars.selected = ui.vars.selected - 1
+            end
+        end
+    end
+)
diff --git a/states/world/text.lua b/states/world/text.lua
new file mode 100644 (file)
index 0000000..812bac9
--- /dev/null
@@ -0,0 +1,16 @@
+return State:new(
+    function()
+        nyq.keypress.trigger = true;
+        if (nyq.keypress.select) then
+            if ui.vars.text_done then
+                -- temps.state = states.world.main
+                state = states.world.main
+                ui.vars.text_pos = 0
+                ui.vars.text_done = false
+                ui.vars.text_end = true
+            elseif (ui.vars.text_pos < ui.vars.text_max) then
+                ui.vars.text_pos = ui.vars.text_pos + 1
+            end
+
+        end
+end)
diff --git a/steam/ContentBuilder/builder_linux/linux32/crashhandler.so b/steam/ContentBuilder/builder_linux/linux32/crashhandler.so
new file mode 100644 (file)
index 0000000..99837ee
Binary files /dev/null and b/steam/ContentBuilder/builder_linux/linux32/crashhandler.so differ
diff --git a/steam/ContentBuilder/builder_linux/linux32/libstdc++.so.6 b/steam/ContentBuilder/builder_linux/linux32/libstdc++.so.6
new file mode 100644 (file)
index 0000000..fa12047
Binary files /dev/null and b/steam/ContentBuilder/builder_linux/linux32/libstdc++.so.6 differ
diff --git a/steam/ContentBuilder/builder_linux/linux32/steamcmd b/steam/ContentBuilder/builder_linux/linux32/steamcmd
new file mode 100644 (file)
index 0000000..13d6050
Binary files /dev/null and b/steam/ContentBuilder/builder_linux/linux32/steamcmd differ
diff --git a/steam/ContentBuilder/builder_linux/linux32/steamerrorreporter b/steam/ContentBuilder/builder_linux/linux32/steamerrorreporter
new file mode 100644 (file)
index 0000000..3ae5201
Binary files /dev/null and b/steam/ContentBuilder/builder_linux/linux32/steamerrorreporter differ
diff --git a/steam/ContentBuilder/builder_linux/steamcmd.sh b/steam/ContentBuilder/builder_linux/steamcmd.sh
new file mode 100644 (file)
index 0000000..d1a022e
--- /dev/null
@@ -0,0 +1,40 @@
+#!/usr/bin/env bash
+
+STEAMROOT="$(cd "${0%/*}" && echo $PWD)"
+STEAMEXE=`basename "$0" .sh`
+
+UNAME=`uname`
+if [ "$UNAME" == "Linux" ]; then
+       PLATFORM=linux32
+       export LD_LIBRARY_PATH="$STEAMROOT/$PLATFORM:$LD_LIBRARY_PATH"
+else # if [ "$UNAME" == "Darwin" ]; then
+       PLATFORM=osx32
+    export DYLD_LIBRARY_PATH="$STEAMROOT/$PLATFORM:$DYLD_LIBRARY_PATH"
+fi
+
+ulimit -n 2048
+
+MAGIC_RESTART_EXITCODE=42
+
+if [ "$DEBUGGER" == "gdb" ] || [ "$DEBUGGER" == "cgdb" ]; then
+       ARGSFILE=$(mktemp $USER.steam.gdb.XXXX)
+
+       # Set the LD_PRELOAD varname in the debugger, and unset the global version. 
+       if [ "$LD_PRELOAD" ]; then
+               echo set env LD_PRELOAD=$LD_PRELOAD >> "$ARGSFILE"
+               echo show env LD_PRELOAD >> "$ARGSFILE"
+               unset LD_PRELOAD
+       fi
+
+       $DEBUGGER -x "$ARGSFILE" "$STEAMROOT/$PLATFORM/$STEAMEXE" "$@"
+       rm "$ARGSFILE"
+else
+       $DEBUGGER "$STEAMROOT/$PLATFORM/$STEAMEXE" "$@"
+fi
+
+STATUS=$?
+
+if [ $STATUS -eq $MAGIC_RESTART_EXITCODE ]; then
+    exec "$0" "$@"
+fi
+exit $STATUS
diff --git a/steam/ContentBuilder/builder_osx/crashhandler.dylib b/steam/ContentBuilder/builder_osx/crashhandler.dylib
new file mode 100644 (file)
index 0000000..20cf99e
Binary files /dev/null and b/steam/ContentBuilder/builder_osx/crashhandler.dylib differ
diff --git a/steam/ContentBuilder/builder_osx/steamcmd b/steam/ContentBuilder/builder_osx/steamcmd
new file mode 100644 (file)
index 0000000..44abf88
Binary files /dev/null and b/steam/ContentBuilder/builder_osx/steamcmd differ
diff --git a/steam/ContentBuilder/builder_osx/steamcmd.sh b/steam/ContentBuilder/builder_osx/steamcmd.sh
new file mode 100644 (file)
index 0000000..76530a2
--- /dev/null
@@ -0,0 +1,45 @@
+#!/usr/bin/env bash
+
+STEAMROOT="$(cd "${0%/*}" && echo $PWD)"
+STEAMCMD=`basename "$0" .sh`
+
+UNAME=`uname`
+if [ "$UNAME" == "Linux" ]; then
+  STEAMEXE="${STEAMROOT}/linux32/${STEAMCMD}"
+  PLATFORM="linux32"
+  export LD_LIBRARY_PATH="$STEAMROOT/$PLATFORM:$LD_LIBRARY_PATH"
+else # if [ "$UNAME" == "Darwin" ]; then
+  STEAMEXE="${STEAMROOT}/${STEAMCMD}"
+  if [ ! -x ${STEAMEXE} ]; then
+    STEAMEXE="${STEAMROOT}/Steam.AppBundle/Steam/Contents/MacOS/${STEAMCMD}"
+  fi
+  export DYLD_LIBRARY_PATH="$STEAMROOT:$DYLD_LIBRARY_PATH"
+  export DYLD_FRAMEWORK_PATH="$STEAMROOT:$DYLD_FRAMEWORK_PATH"
+fi
+
+ulimit -n 2048
+
+MAGIC_RESTART_EXITCODE=42
+
+if [ "$DEBUGGER" == "gdb" ] || [ "$DEBUGGER" == "cgdb" ]; then
+  ARGSFILE=$(mktemp $USER.steam.gdb.XXXX)
+
+  # Set the LD_PRELOAD varname in the debugger, and unset the global version.
+  if [ "$LD_PRELOAD" ]; then
+    echo set env LD_PRELOAD=$LD_PRELOAD >> "$ARGSFILE"
+    echo show env LD_PRELOAD >> "$ARGSFILE"
+    unset LD_PRELOAD
+  fi
+
+  $DEBUGGER -x "$ARGSFILE" "$STEAMEXE" "$@"
+  rm "$ARGSFILE"
+else
+  $DEBUGGER "$STEAMEXE" "$@"
+fi
+
+STATUS=$?
+
+if [ $STATUS -eq $MAGIC_RESTART_EXITCODE ]; then
+    exec "$0" "$@"
+fi
+exit $STATUS
diff --git a/steam/ContentBuilder/output/2762581_preview.manifest.txt b/steam/ContentBuilder/output/2762581_preview.manifest.txt
new file mode 100755 (executable)
index 0000000..706bc14
--- /dev/null
@@ -0,0 +1,179 @@
+Content Manifest for Depot 2762581 
+
+Manifest ID / date     : 0 / Wed Dec 31 19:00:00 1969 
+Total number of files  : 169 
+Total number of chunks : 0 
+Total bytes on disk    : 0 
+Total bytes compressed : 0 
+CRC raw / encrypted    : 0x0 / 0x0 
+
+          Size Chunks File SHA                                 Flags Name
+             0      0 0000000000000000000000000000000000000000    40 .cache
+             0      0 0000000000000000000000000000000000000000    40 .cache\formats
+             2      1 1489f923c4dca729178b3e3233458550d8dddf29     0 .cache\formats\0
+             2      1 1489f923c4dca729178b3e3233458550d8dddf29     0 .cache\formats\1
+           111      1 bec6820df48d54720627d0868d564ad27bb58973     0 .cache\formats\2
+             2      1 1489f923c4dca729178b3e3233458550d8dddf29     0 .cache\formats\3
+             2      1 1489f923c4dca729178b3e3233458550d8dddf29     0 .cache\formats\4
+             2      1 1489f923c4dca729178b3e3233458550d8dddf29     0 .cache\formats\5
+             2      1 1489f923c4dca729178b3e3233458550d8dddf29     0 .cache\formats\6
+             2      1 1489f923c4dca729178b3e3233458550d8dddf29     0 .cache\formats\7
+             2      1 1489f923c4dca729178b3e3233458550d8dddf29     0 .cache\formats\8
+             2      1 1489f923c4dca729178b3e3233458550d8dddf29     0 .cache\formats\9
+             0      0 0000000000000000000000000000000000000000    40 database
+         2,028      1 4605fd37e95398e34017f5bda75df73bd78510bc     0 database\init.lua
+         9,290      1 f50b42d051690447584033c17b5b0c63b274c24d     0 init.lua
+       265,216      1 94d39c6fc6540dc077b3c7bed4ce3cfac1acd171     0 libmodplug-1.dll
+        25,600      1 1d0919202c0705439f2f0b395e80fdff12974afa     0 libogg-0.dll
+       368,128      1 9e92bcd41d9f137530e6a8681e1cfe6c8e21d224     0 libopus-0.dll
+        46,592      1 53840bd4b39fc1c51d0f4566441c5e3cb4f0393f     0 libopusfile-0.dll
+       210,944      1 e3d1403be06beb32fc8dc7e8a58c31e18b586a70     0 libpng16-16.dll
+       285,184      1 f7c6a50a32e37775e40cc83f960553ec75217951     0 lua53.dll
+       259,072      1 55bff0e9ed6b35b2a8fd56aa495da3c56239c7af     0 mapeditor.exe
+             0      0 0000000000000000000000000000000000000000    40 map_configs
+         4,534      1 e775926638259944cf570fda1a31dba74b99ea75     0 map_configs\mapeditor_config.lua
+       638,658      1 9d2d0ec283cf223b8a345a82bdf9f32c637c023b     0 n2de.exe
+             0      0 0000000000000000000000000000000000000000    40 resources
+             0      0 0000000000000000000000000000000000000000    40 resources\data
+             0      0 0000000000000000000000000000000000000000    40 resources\data\test
+           519      1 f572c121744fa33ae8bbfda7f661393b5328ee70     0 resources\data\test\map2.dat
+           889      1 73ceac29c4eece82049306d3c38ad89f3ad0e769     0 resources\data\test\objects2.dat
+             0      0 0000000000000000000000000000000000000000    40 resources\fonts
+       510,612      1 1e3ada8fee1f9631cc8e85c1720b5cfe02f8f59c     0 resources\fonts\NotoSansMono-Regular.ttf
+             0      0 0000000000000000000000000000000000000000    40 resources\images
+         2,308      1 a899f8d629784e5b747196580f2b56d8fa3070c3     0 resources\images\axolotl.png
+         1,085      1 97d0784672ff08951d856aea07da284044efe3a3     0 resources\images\bag.png
+        16,259      1 00558a37edd2ac4852b38dccef6d9baeccddcb94     0 resources\images\battle_ui.png
+        32,658      1 33e7b533bb1ac12f11643835cb7186ee1d91d28b     0 resources\images\berry_one.png
+           435      1 dbe69edeb2c9e1c067f98265a54601a89ac33a91     0 resources\images\border1.png
+           324      1 cf0842593e692b196cd142408e38cd7a1d823c51     0 resources\images\border1_unselected.png
+           213      1 56feef6c5d8f6c4a3129feb01ec46ffb1e944aed     0 resources\images\border2..png
+           301      1 532f2ac06759e2143a73d113ae5e5de1a3196c18     0 resources\images\border2.png
+           187      1 a8dad63e630aa14ffadf2e8d38400a277bae614f     0 resources\images\border2_unselected.png
+        37,137      1 0d59b9d04f38191f7cf42189f7e9a429aa926994     0 resources\images\character_spritesheet_1.png
+         4,044      1 e9cd7f0d6aa75340206dceff1d102dbd5c13d7e5     0 resources\images\choice_select_test_one.png
+         5,342      1 4d363e8cc021ba6b0377e8da8273ab769b941fe1     0 resources\images\choice_select_test_two.png
+       141,573      1 6a06e91c091d713e2fad9df25e0e0a3c9b35fbd3     0 resources\images\clonemon.png
+       135,878      1 99d0cf95fea23e012bba16e06a5e271d0cbfd9f0     0 resources\images\clonemon_battle_grass.png
+         7,735      1 4e5c57f756003815cb6e3f79628dd7032f8b8bd2     0 resources\images\clonemon_battle_ui.png
+         1,391      1 cdc6b037763732ef67af8af6452579dccd934a22     0 resources\images\clonemon_battle_ui_grass.png
+        14,530      1 79e13032d63472706dc99eeb850232449d1c50ab     0 resources\images\clonemon_party.png
+        55,427      1 1cdbc2c4fd38c881f970eb87491f722b27595a80     0 resources\images\generic_house_one.png
+        21,647      1 28ca85cd00439b5acf687f3569233cc3544abefe     0 resources\images\gradient.png
+        50,793      1 03e8ab59576236e01313c53e84526db7e79b561c     0 resources\images\house_two.png
+        20,953      1 e5f6e17b7ce334ecb6c96fe714683b31558392d1     0 resources\images\keyboard_lower.png
+        23,212      1 3d377ba00bb4998d62a8eb889fdbe9c1e2a7a96f     0 resources\images\keyboard_upper.png
+         7,430      1 8f8ba42e54bc992a16cc77ce9138e94cb5ab5d0b     0 resources\images\loadsave.png
+         4,560      1 97f87a383cd02831f3f2a78e299b5cccd72061b4     0 resources\images\logo.png
+           807      1 3600eb2b9b85f738f73e93d2815f9bce6e910576     0 resources\images\menu_items.png
+        11,743      1 81e7b91c29d10f4124ccb8aaeb768e6bd7c1f8e2     0 resources\images\nyquist.png
+       150,349      1 404910c2429dd55fa13beab1281a25b4d905daf4     0 resources\images\nyquist.xcf
+        10,059      1 c11893a53e805c34348fd45ad19d1f1d52962178     0 resources\images\nyquist2.png
+        39,812      1 8dd757f3814d85ca1cede6f1c95ac392f4143b5a     0 resources\images\nyquist_spritesheet.png
+        11,059      1 27c24c310d40937d5f318cdf0264a9d387431d00     0 resources\images\nyquist_spritesheet3.png
+        55,934      1 9425882cf965ad83f92c571e60d9736e9df4c574     0 resources\images\outdoors_backgorund_one.png
+         5,896      1 3e32e1e011535228dd783e5abd9b4e2e73bce89c     0 resources\images\pause.png
+        19,880      1 4b583b722341d067354541cc5a49ccc07f75540b     0 resources\images\potion_one.png
+        15,876      1 89ed067d607ca73595e6cddc6702f6831b393881     0 resources\images\potion_two.png
+        29,620      1 300898079938011f2018985fa3e3192522db0291     0 resources\images\Route_111.png
+        18,820      1 cde85671294535a7b6929f251de23ec4617ff824     0 resources\images\tileset_indoors_1.png
+        40,478      1 a2dc8443922c13d616cbac87332c937b3f46b750     0 resources\images\tileset_outside_1.png
+       163,112      1 bad98f6103e0f628e5c441886aa962a93288bc21     0 resources\images\town4.png
+        16,266      1 443dea0d5ea56b5c98fa35d45922d0b21592d677     0 resources\images\tree_one.png
+        17,176      1 25294231343dddf7a336b85c2980c4a44ca0441d     0 resources\images\tree_two.png
+       197,816      1 6bb6fc848997b1c773e4937b51d598e56357e424     0 resources\images\vs.png
+       104,796      1 af7955f837d3c8e2860d7e3b81318c743fc8e2bb     0 resources\images\vs2.png
+        99,385      1 b6656b952f835d46633e14c74b83ec0fd2447899     0 resources\images\vs3.png
+        10,409      1 05742d69b3673b2bcfa9d4c2e3c9d0fbcc517291     0 resources\images\well.png
+       118,784      1 aa7bbb2e79372465a69bdcf23c6883595a0f3ddc     0 resources\test.db
+             0      0 0000000000000000000000000000000000000000    40 resources\wavs
+     8,532,208      9 b33571119a1ca99d86741946e686e654c4976194     0 resources\wavs\battle1.wav
+       150,003      1 4390c0dbde32bbb68d980b50c042e7d7a2a935ba     0 resources\wavs\battle1.wav.asd
+     2,730,712      3 2c694dde8a2fc9cc7c535502613272334ce34c9e     0 resources\wavs\breakdown1.wav
+        50,516      1 a519b95d132027ab4a896500ee500b3c1efe8482     0 resources\wavs\breakdown1.wav.asd
+    14,946,216     15 3b2934f77513d1cc8280caf6d9e2196c26e6379a     0 resources\wavs\chipped.wav
+       259,795      1 c05760a58fa845bd3d1bc61d993884895e6d08de     0 resources\wavs\chipped.wav.asd
+    18,812,964     18 16b060274000913162de4d6fd63ad7515c3ce835     0 resources\wavs\chipped_dip.wav
+       317,091      1 bb22cad0a718421c34a11898f4ad5824961b5b98     0 resources\wavs\chipped_dip.wav.asd
+       903,496      1 45bdce858a5fca6bf2729a05b75ade82c0c6e66e     0 resources\wavs\clonks.wav
+    12,125,410     12 3ab27b042a71671b4371192e52b8d3d0bb6ce9e3     0 resources\wavs\destructo.wav
+    17,280,044     17 3d968fab67de0c13477cd52bb1111c18758fecfe     0 resources\wavs\good.wav
+       302,049      1 97c9a19afa5c46c67b049d56f097703a0310e433     0 resources\wavs\good.wav.asd
+         7,986      1 126a3fa63da6630657c895ecc050a7822c3faa46     0 resources\wavs\hihat.wav
+    10,237,016     10 1acd1ca494596b9dc15d2d55b00cf663c012cd60     0 resources\wavs\intro.wav
+        25,530      1 111f70d2c36c78b9682e21de0355f8e80ed3409e     0 resources\wavs\kick.wav
+     1,893,948      2 3e75d65b7d4a03609a0402246c5281573997abaa     0 resources\wavs\melody.mp3
+    17,953,648     18 955fe087f220dd49c8697bd6824f6dcbd9bfa3db     0 resources\wavs\meta19.wav
+       313,605      1 249d44320035b9d18c2717e42be4858142c3b620     0 resources\wavs\meta19.wav.asd
+     2,393,812      3 daa7e5f7eace4539d93908dd89303385e3e702db     0 resources\wavs\mutate.wav
+        45,252      1 41a2f55a03b6639aded29bcd0acb61411c0791ab     0 resources\wavs\mutate.wav.asd
+    13,100,060     13 c7a9065d0481efaf6585c6b99032f2437ca5c593     0 resources\wavs\pianer1.wav
+       227,727      1 798190b55189c0b9cc9237b0f5c20867ee810d22     0 resources\wavs\pianer1.wav.asd
+       512,044      1 c6612c8cc25a2cd1a531e8d95d368cab53376af7     0 resources\wavs\rise.wav
+        12,708      1 e1b7938ee70f0ebece0c4220189efd8f45a2d485     0 resources\wavs\rise.wav.asd
+     2,730,712      3 9a29fe4a1d8123d8887178288512f68c662dab20     0 resources\wavs\rise2.wav
+       845,644      1 c9e3a849ccafa77154c31a041f2b656ffb8a77eb     0 resources\wavs\rise3.wav
+         8,666      1 26618105e72d2cb25338b2111b4c6e3635450bb8     0 resources\wavs\snare.wav
+     2,233,552      3 23a8c4aed780bb334119606566a60b44fd027861     0 resources\wavs\TOD.mp3
+     1,623,592      2 9a5b0152d171fc5788aef24e03e54ced9dd2cfa2     0 resources\wavs\um_intro.wav
+     1,725,064      2 2500e40ce8bb1d5653d61a15b24a8873d2dd1a49     0 resources\wavs\um_main.wav
+       455,707      1 b4c4a0ad7e377fb0df73967d2d0dbc0b9fd0929a     0 resources\wavs\you_are_gay.mp3
+     2,255,872      3 3b80b1228631abbb7f2745828a25cbce0d9dce09     0 SDL2.dll
+       125,440      1 b03bb9d09447114a018110bfb91d56ef8d5ec3bb     0 SDL2_image.dll
+       285,184      1 b58b433009fe14286748a1fa11cd2faa7585acfd     0 SDL2_mixer.dll
+     1,561,088      2 808ff63ce1ebfcd734a0bb797fc01c9ef5615563     0 SDL2_ttf.dll
+     2,159,616      3 113a7cc6a35483ee09fc0d9c40a4fd2a763f24de     0 sqlite3.dll
+             0      0 0000000000000000000000000000000000000000    40 states
+             0      0 0000000000000000000000000000000000000000    40 states\bag
+            52      1 299499edd8d60b7799d7de8b5e42a2249febcf42     0 states\bag\init.lua
+           754      1 6fb8f72dd2b86b5b8a567e2380f2e5a335e9ec64     0 states\bag\main.lua
+             0      0 0000000000000000000000000000000000000000    40 states\battle
+         1,213      1 4fbeee17bf20a3706e042415135d44cafed564c0     0 states\battle\doSelect.lua
+           380      1 1eb978284f6963f324a7e8116e45d2aa92a51add     0 states\battle\enterBattle.lua
+           176      1 a8bc483ffcbf90bb7130003b20b0d698048a0abf     0 states\battle\init.lua
+           922      1 6f5a706f9ca273cb59f4b3afea0c83682509b01e     0 states\battle\moveSelect.lua
+             0      0 0000000000000000000000000000000000000000    40 states\choice_select
+            61      1 731ed20200b80f0d59dbd0d29561cd1939b6a6c9     0 states\choice_select\init.lua
+           338      1 61bd159678eddbbcef58126a5a53a17ca0e21b0c     0 states\choice_select\main.lua
+             0      0 0000000000000000000000000000000000000000    40 states\enter_text
+            58      1 44d1db296666c3fd30221fa7ad6e68a5870895ba     0 states\enter_text\init.lua
+         2,668      1 ac22f64cba766a319d24fd3906f52a56534d16e6     0 states\enter_text\main.lua
+           526      1 6d4e897c7af5f20d76a1cc0324795bc91544cf97     0 states\init.lua
+             0      0 0000000000000000000000000000000000000000    40 states\loadsave
+            56      1 19a6bac92a99da327ee9dc7ed5e6f01e071844dc     0 states\loadsave\init.lua
+         1,808      1 d70d295159d96b6750b4436d83dbef61af99936d     0 states\loadsave\main.lua
+             0      0 0000000000000000000000000000000000000000    40 states\party
+           686      1 0d440eb6b9ddf59004d3d9a58ad111e5f372c1af     0 states\party\doWhat.lua
+           148      1 7881f6dd0ca105b46f931480cff4a9c18704a557     0 states\party\init.lua
+         1,284      1 32d94a8642ff57d9b6e952d07db55a8fdd0e9168     0 states\party\main.lua
+         1,429      1 7cb8bf6dd706a5c74501d8639042c9c461a49f5b     0 states\party\switch.lua
+             0      0 0000000000000000000000000000000000000000    40 states\settings
+            57      1 56bb8b5fd239ef34cb48b82f1c8df1aecd289602     0 states\settings\init.lua
+            44      1 35269f8e7a1d0d8420c6054a356a30ec6b025219     0 states\settings\main.lua
+             0      0 0000000000000000000000000000000000000000    40 states\start
+            53      1 5fad90cca7e88040a4e9770de16e5f07ccde265c     0 states\start\init.lua
+         1,780      1 f18a204fa95e30b1db118a7b9e031e7036b311e4     0 states\start\main.lua
+             0      0 0000000000000000000000000000000000000000    40 states\start_menu
+            58      1 150a71bc5e5e4c9d787440ffb82061a99f4ce17c     0 states\start_menu\init.lua
+           683      1 c7a0257b1df676bd396027a4a53c3e175d05e842     0 states\start_menu\main.lua
+             0      0 0000000000000000000000000000000000000000    40 states\world
+           189      1 f577bfd6c53773633bd0400ce72926aa6afaca41     0 states\world\init.lua
+           636      1 d6a5c62bb4fc56e3478140550f38f9903b55d2bb     0 states\world\main.lua
+           482      1 fb2fb310725db843473b70a1148eadc7690047b1     0 states\world\option.lua
+         1,036      1 4bedec3948df0fa390d3fdedf6045dbd2dd29522     0 states\world\pause.lua
+           470      1 6af2c446ddf25dbc2c9849f6d680b4e5f17cf2a5     0 states\world\text.lua
+         5,700      1 f5f4016b45adf9ae3a0e12a02f5f0b45bc90c205     0 terminal.lua
+             0      0 0000000000000000000000000000000000000000    40 uis
+         4,035      1 85b6e15b628f6451291f053888c2533217a1d3a2     0 uis\bag.lua
+         7,320      1 0c26d92a11f8cbf74676f7c11ba9a15de8d4043f     0 uis\battle.lua
+         1,354      1 27fb59758a46dc418df0a3ac587d8389e14a8529     0 uis\choice_select.lua
+         5,537      1 91954f51f6e8e4379f7ca9043db753427c7f8e5d     0 uis\enter_text.lua
+           462      1 ac848ad940595378854ecfc6afa9a8683c6b02d5     0 uis\init.lua
+         3,379      1 49c7a7de483945ef2b443ae129a9b62bdb96e03a     0 uis\loadsave.lua
+         6,358      1 8ed12f6c2eccd66b6fbee747e605d45b574b7717     0 uis\party.lua
+           341      1 8a5c0858f53d6a8bdc695ae1a2798f977a744721     0 uis\pause.lua
+         1,017      1 d84c80ec4f12754ea9674ab3701e74061c24a750     0 uis\settings.lua
+         3,016      1 cdac401c82dfc97a1e16af7c830b8dd7dc62332c     0 uis\start.lua
+         1,251      1 a323e64c317d2a3e7f5cf6c8c07dfc2708145eb5     0 uis\start_menu.lua
+        11,964      1 f0cf8e949f1dc0dcc0a36617d48128746d2b504a     0 uis\world.lua
+       108,544      1 ec3f6cf88711ef8cfb3cc439cb75471a2bb9e1b5     0 zlib1.dll
diff --git a/steam/ContentBuilder/output/app_build_2762580.log b/steam/ContentBuilder/output/app_build_2762580.log
new file mode 100755 (executable)
index 0000000..fd9ed1b
--- /dev/null
@@ -0,0 +1,4 @@
+[2024-01-18 03:58:54]: Starting AppID 2762580 build (flags 0x0).
+[2024-01-18 03:58:54]: Building depot 2762581...
+
+[2024-01-18 03:59:01]: Successfully finished AppID 2762580 build (BuildID 13203732).
diff --git a/steam/ContentBuilder/output/depot_build_2762581.log b/steam/ContentBuilder/output/depot_build_2762581.log
new file mode 100755 (executable)
index 0000000..4850413
--- /dev/null
@@ -0,0 +1,178 @@
+[2024-01-18 03:58:54]: Starting build for depot 2762581, content path is "/mnt/c/Users/sahww/Development/github/clonemon/steam/ContentBuilder/content/", build flags 0x0
+[2024-01-18 03:58:54]: Building file listing for depot 2762581 ...
+[2024-01-18 03:58:56]: Found 260 files for mapping: /mnt/c/Users/sahww/Development/github/clonemon/steam/ContentBuilder/content/windows * -> .
+[2024-01-18 03:58:56]: Found 260 files (138 MB) for depot 2762581
+[2024-01-18 03:58:56]: Building depot 2762581, baseline manifest 4792084950510594223 (217 files)
+[2024-01-18 03:58:57]: Found 330 chunks ( 286 used previously ) for depot 2762581, took 0 minutes, 0 seconds
+[2024-01-18 03:58:57]: Changes to baseline manifest 4792084950510594223 :
+[2024-01-18 03:58:57]: Added  : ".init.lua.swp" 20 kB 
+[2024-01-18 03:58:57]: Changed: "extensions\audio\init.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Added  : "extensions\config" 0 kB ,Flags: 64
+[2024-01-18 03:58:57]: Added  : "extensions\config\init.lua" 3 kB 
+[2024-01-18 03:58:57]: Added  : "extensions\config\mappings" 0 kB ,Flags: 64
+[2024-01-18 03:58:57]: Added  : "extensions\config\mappings\default_gamepad.lua" 1 kB 
+[2024-01-18 03:58:57]: Added  : "extensions\config\mappings\default_keyboard.lua" 1 kB 
+[2024-01-18 03:58:57]: Added  : "extensions\config\mappings\init.lua" 1 kB 
+[2024-01-18 03:58:57]: Changed: "extensions\database\init.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Changed: "extensions\database\schema.lua" 2 kB size, 2 kB changed 
+[2024-01-18 03:58:57]: Added  : "extensions\images" 0 kB ,Flags: 64
+[2024-01-18 03:58:57]: Added  : "extensions\images\init.lua" 1 kB 
+[2024-01-18 03:58:57]: Added  : "extensions\init.lua" 1 kB 
+[2024-01-18 03:58:57]: Changed: "extensions\libaudio.dll" 156 kB size, 156 kB changed 
+[2024-01-18 03:58:57]: Changed: "extensions\libdatabase.dll" 163 kB size, 163 kB changed 
+[2024-01-18 03:58:57]: Added  : "extensions\libimages.dll" 161 kB 
+[2024-01-18 03:58:57]: Added  : "extensions\libloops.dll" 159 kB 
+[2024-01-18 03:58:57]: Added  : "extensions\libsprites.dll" 163 kB 
+[2024-01-18 03:58:57]: Changed: "extensions\libterminal.dll" 155 kB size, 155 kB changed 
+[2024-01-18 03:58:57]: Added  : "extensions\libtext.dll" 161 kB 
+[2024-01-18 03:58:57]: Added  : "extensions\loops" 0 kB ,Flags: 64
+[2024-01-18 03:58:57]: Added  : "extensions\loops\init.lua" 1 kB 
+[2024-01-18 03:58:57]: Added  : "extensions\metatables" 0 kB ,Flags: 64
+[2024-01-18 03:58:57]: Added  : "extensions\metatables\ui.lua" 16 kB 
+[2024-01-18 03:58:57]: Added  : "extensions\sprites" 0 kB ,Flags: 64
+[2024-01-18 03:58:57]: Added  : "extensions\sprites\init.lua" 1 kB 
+[2024-01-18 03:58:57]: Changed: "extensions\terminal\commands.lua" 4 kB size, 4 kB changed 
+[2024-01-18 03:58:57]: Changed: "extensions\terminal\init.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Added  : "extensions\text" 0 kB ,Flags: 64
+[2024-01-18 03:58:57]: Added  : "extensions\text\init.lua" 1 kB 
+[2024-01-18 03:58:57]: Changed: "init.lua" 7 kB size, 7 kB changed 
+[2024-01-18 03:58:57]: Added  : "lua-5.4.6.tar.gz" 355 kB 
+[2024-01-18 03:58:57]: Added  : "lua54.dll" 347 kB 
+[2024-01-18 03:58:57]: Changed: "mapeditor.exe" 199 kB size, 199 kB changed 
+[2024-01-18 03:58:57]: Added  : "map_configs\controls" 0 kB ,Flags: 64
+[2024-01-18 03:58:57]: Added  : "map_configs\controls\controls.lua" 1 kB 
+[2024-01-18 03:58:57]: Added  : "map_configs\crops" 0 kB ,Flags: 64
+[2024-01-18 03:58:57]: Added  : "map_configs\crops\indoor.lua" 3 kB 
+[2024-01-18 03:58:57]: Added  : "map_configs\crops\outdoor.lua" 2 kB 
+[2024-01-18 03:58:57]: Added  : "map_configs\indoor1.lua" 1 kB 
+[2024-01-18 03:58:57]: Added  : "map_configs\outdoor1.lua" 1 kB 
+[2024-01-18 03:58:57]: Added  : "modules\ai.lua" 4 kB 
+[2024-01-18 03:58:57]: Changed: "modules\clock.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Changed: "modules\collection.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Changed: "modules\copy.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Changed: "modules\find.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Changed: "modules\hashTable.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Added  : "modules\metatables" 0 kB ,Flags: 64
+[2024-01-18 03:58:57]: Added  : "modules\metatables\entity.lua" 3 kB 
+[2024-01-18 03:58:57]: Added  : "modules\player.lua" 1 kB 
+[2024-01-18 03:58:57]: Changed: "modules\state.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Changed: "modules\string.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Changed: "modules\table.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Changed: "modules\uuid.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Added  : "modules\world.lua" 10 kB 
+[2024-01-18 03:58:57]: Changed: "n2de.exe" 132 kB size, 132 kB changed 
+[2024-01-18 03:58:57]: Changed: "README.adoc" 3 kB size, 3 kB changed 
+[2024-01-18 03:58:57]: Added  : "resources\data\test\map1.dat" 1 kB 
+[2024-01-18 03:58:57]: Changed: "resources\data\test\map2.dat" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Added  : "resources\data\test\map3.dat" 1 kB 
+[2024-01-18 03:58:57]: Added  : "resources\data\test\map4.dat" 1 kB 
+[2024-01-18 03:58:57]: Added  : "resources\data\test\map5.dat" 1 kB 
+[2024-01-18 03:58:57]: Added  : "resources\data\test\map6.dat" 1 kB 
+[2024-01-18 03:58:57]: Added  : "resources\data\test\map7.dat" 1 kB 
+[2024-01-18 03:58:57]: Added  : "resources\data\test\objects1.dat" 1 kB 
+[2024-01-18 03:58:57]: Changed: "resources\data\test\objects2.dat" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Added  : "resources\data\test\objects3.dat" 1 kB 
+[2024-01-18 03:58:57]: Added  : "resources\data\test\objects4.dat" 1 kB 
+[2024-01-18 03:58:57]: Added  : "resources\data\test\objects5.dat" 1 kB 
+[2024-01-18 03:58:57]: Added  : "resources\data\test\objects6.dat" 3 kB 
+[2024-01-18 03:58:57]: Added  : "resources\data\test\objects7.dat" 1 kB 
+[2024-01-18 03:58:57]: Added  : "resources\images\map_indoor_1.png" 13 kB 
+[2024-01-18 03:58:57]: Added  : "resources\images\map_indoor_2.png" 10 kB 
+[2024-01-18 03:58:57]: Added  : "resources\images\map_outdoor1.png" 170 kB 
+[2024-01-18 03:58:57]: Added  : "resources\images\map_outdoor_1.png" 6 kB 
+[2024-01-18 03:58:57]: Added  : "resources\images\map_outdoor_10.png" 6 kB 
+[2024-01-18 03:58:57]: Added  : "resources\images\map_outdoor_2.png" 6 kB 
+[2024-01-18 03:58:57]: Added  : "resources\images\map_outdoor_3.png" 6 kB 
+[2024-01-18 03:58:57]: Added  : "resources\images\map_outdoor_4.png" 6 kB 
+[2024-01-18 03:58:57]: Added  : "resources\images\map_outdoor_5.png" 6 kB 
+[2024-01-18 03:58:57]: Added  : "resources\images\map_outdoor_6.png" 6 kB 
+[2024-01-18 03:58:57]: Added  : "resources\images\map_outdoor_7.png" 6 kB 
+[2024-01-18 03:58:57]: Added  : "resources\images\map_outdoor_8.png" 6 kB 
+[2024-01-18 03:58:57]: Added  : "resources\images\map_outdoor_9.png" 6 kB 
+[2024-01-18 03:58:57]: Changed: "resources\images\menu_items.png" 6 kB size, 6 kB changed 
+[2024-01-18 03:58:57]: Added  : "resources\images\spritesheet_indoors_1.backup.png" 24 kB 
+[2024-01-18 03:58:57]: Changed: "resources\images\spritesheet_indoors_1.png" 21 kB size, 21 kB changed 
+[2024-01-18 03:58:57]: Added  : "resources\images\spritesheet_outdoor_1.png" 95 kB 
+[2024-01-18 03:58:57]: Added  : "resources\images\spritesheet_partybox.png" 1 kB 
+[2024-01-18 03:58:57]: Changed: "resources\test.db" 148 kB size, 148 kB changed 
+[2024-01-18 03:58:57]: Changed: "states\bag\init.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Changed: "states\bag\main.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Changed: "states\battle\doSelect.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Changed: "states\battle\enterBattle.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Changed: "states\battle\init.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Changed: "states\battle\moveSelect.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Changed: "states\choice_select\init.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Changed: "states\choice_select\main.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Changed: "states\enter_text\init.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Changed: "states\enter_text\main.lua" 3 kB size, 3 kB changed 
+[2024-01-18 03:58:57]: Changed: "states\init.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Changed: "states\loadsave\init.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Changed: "states\loadsave\main.lua" 2 kB size, 2 kB changed 
+[2024-01-18 03:58:57]: Changed: "states\mapping\init.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Changed: "states\mapping\main.lua" 3 kB size, 3 kB changed 
+[2024-01-18 03:58:57]: Added  : "states\partybox" 0 kB ,Flags: 64
+[2024-01-18 03:58:57]: Added  : "states\partybox\init.lua" 1 kB 
+[2024-01-18 03:58:57]: Added  : "states\partybox\main.lua" 1 kB 
+[2024-01-18 03:58:57]: Changed: "states\party\doWhat.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Changed: "states\party\init.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Changed: "states\party\main.lua" 2 kB size, 2 kB changed 
+[2024-01-18 03:58:57]: Changed: "states\party\switch.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Changed: "states\settings\init.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Changed: "states\settings\main.lua" 3 kB size, 3 kB changed 
+[2024-01-18 03:58:57]: Changed: "states\start\init.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Changed: "states\start\main.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Changed: "states\start_menu\init.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Changed: "states\start_menu\main.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Changed: "states\world\init.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Changed: "states\world\main.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Changed: "states\world\option.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Changed: "states\world\pause.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Changed: "states\world\text.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Added  : "tests" 0 kB ,Flags: 64
+[2024-01-18 03:58:57]: Added  : "tests\chunkloader" 0 kB ,Flags: 64
+[2024-01-18 03:58:57]: Added  : "tests\chunkloader\tst.lua" 3 kB 
+[2024-01-18 03:58:57]: Changed: "uis\bag.lua" 4 kB size, 4 kB changed 
+[2024-01-18 03:58:57]: Changed: "uis\battle.lua" 8 kB size, 8 kB changed 
+[2024-01-18 03:58:57]: Changed: "uis\choice_select.lua" 2 kB size, 2 kB changed 
+[2024-01-18 03:58:57]: Changed: "uis\enter_text.lua" 5 kB size, 5 kB changed 
+[2024-01-18 03:58:57]: Changed: "uis\init.lua" 1 kB size, 1 kB changed 
+[2024-01-18 03:58:57]: Changed: "uis\loadsave.lua" 4 kB size, 4 kB changed 
+[2024-01-18 03:58:57]: Changed: "uis\mapping.lua" 4 kB size, 4 kB changed 
+[2024-01-18 03:58:57]: Changed: "uis\party.lua" 7 kB size, 7 kB changed 
+[2024-01-18 03:58:57]: Added  : "uis\partybox.lua" 1 kB 
+[2024-01-18 03:58:57]: Changed: "uis\settings.lua" 5 kB size, 5 kB changed 
+[2024-01-18 03:58:57]: Changed: "uis\start.lua" 4 kB size, 4 kB changed 
+[2024-01-18 03:58:57]: Changed: "uis\start_menu.lua" 2 kB size, 2 kB changed 
+[2024-01-18 03:58:57]: Changed: "uis\world.lua" 5 kB size, 5 kB changed 
+[2024-01-18 03:58:57]: Removed: .cache (0 kB)
+[2024-01-18 03:58:57]: Removed: .cache\formats (0 kB)
+[2024-01-18 03:58:57]: Removed: .cache\formats\0 (1 kB)
+[2024-01-18 03:58:57]: Removed: .cache\formats\1 (1 kB)
+[2024-01-18 03:58:57]: Removed: .cache\formats\10 (1 kB)
+[2024-01-18 03:58:57]: Removed: .cache\formats\2 (1 kB)
+[2024-01-18 03:58:57]: Removed: .cache\formats\3 (1 kB)
+[2024-01-18 03:58:57]: Removed: .cache\formats\4 (1 kB)
+[2024-01-18 03:58:57]: Removed: .cache\formats\5 (1 kB)
+[2024-01-18 03:58:57]: Removed: .cache\formats\6 (1 kB)
+[2024-01-18 03:58:57]: Removed: .cache\formats\7 (1 kB)
+[2024-01-18 03:58:57]: Removed: .cache\formats\8 (1 kB)
+[2024-01-18 03:58:57]: Removed: .cache\formats\9 (1 kB)
+[2024-01-18 03:58:57]: Removed: .gitignore (1 kB)
+[2024-01-18 03:58:57]: Removed: config (0 kB)
+[2024-01-18 03:58:57]: Removed: config\init.lua (3 kB)
+[2024-01-18 03:58:57]: Removed: config\mappings (0 kB)
+[2024-01-18 03:58:57]: Removed: config\mappings\default_gamepad.lua (1 kB)
+[2024-01-18 03:58:57]: Removed: config\mappings\default_keyboard.lua (1 kB)
+[2024-01-18 03:58:57]: Removed: config\mappings\init.lua (1 kB)
+[2024-01-18 03:58:57]: Removed: extensions\formats (0 kB)
+[2024-01-18 03:58:57]: Removed: extensions\formats\init.lua (1 kB)
+[2024-01-18 03:58:57]: Removed: extensions\libformats.dll (575 kB)
+[2024-01-18 03:58:57]: Removed: extensions\n2de.exe (628 kB)
+[2024-01-18 03:58:57]: Removed: lua53.dll (279 kB)
+[2024-01-18 03:58:57]: Removed: map_configs\mapeditor_config.lua (4 kB)
+[2024-01-18 03:58:57]: Removed: modules\ui_mt.lua (19 kB)
+[2024-01-18 03:58:57]: Removed: terminal.lua (5 kB)
+[2024-01-18 03:58:57]: Summary: 71 files added, 68 files changed, 28 files removed
+[2024-01-18 03:58:57]: Uploading new manifest to 208.64.201.182:80 (handle 11931383876820588005, 34490 bytes).
+[2024-01-18 03:58:58]: Uploading 38 out of 38 missing chunks.
+[2024-01-18 03:59:00]: Success! New manifestID 4648740560032500941 created and 38 new chunks uploaded.
diff --git a/steam/ContentBuilder/output/depot_build_2762581.vdf b/steam/ContentBuilder/output/depot_build_2762581.vdf
new file mode 100755 (executable)
index 0000000..405c605
--- /dev/null
@@ -0,0 +1,9 @@
+"depotbuild"
+{
+       "appid"         "2762580"
+       "depotid"               "2762581"
+       "flags"         "0"
+       "steamid"               "76561198048577880"
+       "manifest"              "4648740560032500941"
+       "baselinemanifest"              "4792084950510594223"
+}
diff --git a/steam/ContentBuilder/output/depot_build_2762582.log b/steam/ContentBuilder/output/depot_build_2762582.log
new file mode 100755 (executable)
index 0000000..fbc3efe
--- /dev/null
@@ -0,0 +1,15 @@
+[2024-01-02 20:31:49]: Starting build for depot 2762582, content path is "/home/nyquist/Development/github/clonemon/steam/ContentBuilder/content/", build flags 0x0
+[2024-01-02 20:31:49]: Building file listing for depot 2762582 ...
+[2024-01-02 20:31:49]: Found 193 files for mapping: /home/nyquist/Development/github/clonemon/steam/ContentBuilder/content/steamdeck * -> .
+[2024-01-02 20:31:49]: Found 193 files (137 MB) for depot 2762582
+[2024-01-02 20:31:49]: Building depot 2762582, baseline manifest 5027810996746026268 (193 files)
+[2024-01-02 20:31:50]: Found 267 chunks ( 268 used previously ) for depot 2762582, took 0 minutes, 0 seconds
+[2024-01-02 20:31:50]: Changes to baseline manifest 5027810996746026268 :
+[2024-01-02 20:31:50]: Changed: "config\init.lua" 1 kB size, 1 kB changed 
+[2024-01-02 20:31:50]: Changed: "init.lua" 7 kB size, 7 kB changed 
+[2024-01-02 20:31:50]: Changed: "n2de.exe" 626 kB size, 626 kB changed 
+[2024-01-02 20:31:50]: Added  : "test.db" 0 kB 
+[2024-01-02 20:31:50]: Removed: resources\test.db (124 kB)
+[2024-01-02 20:31:50]: Summary: 1 files added, 3 files changed, 1 files removed
+[2024-01-02 20:31:50]: Uploading new manifest to 208.64.201.182:80 (handle 17745443725001411915, 25986 bytes).
+[2024-01-02 20:31:50]: Success! New manifestID 251304651669591706 created and 0 new chunks uploaded.
diff --git a/steam/ContentBuilder/output/depot_build_2762582.vdf b/steam/ContentBuilder/output/depot_build_2762582.vdf
new file mode 100755 (executable)
index 0000000..2e6cb21
--- /dev/null
@@ -0,0 +1,9 @@
+"depotbuild"
+{
+       "appid"         "2762580"
+       "depotid"               "2762582"
+       "flags"         "0"
+       "steamid"               "76561198048577880"
+       "manifest"              "251304651669591706"
+       "baselinemanifest"              "5027810996746026268"
+}
diff --git a/steam/ContentBuilder/output/depot_build_2762583.log b/steam/ContentBuilder/output/depot_build_2762583.log
new file mode 100755 (executable)
index 0000000..23cab94
--- /dev/null
@@ -0,0 +1,5 @@
+[2024-01-02 18:09:34]: Starting build for depot 2762583, content path is "/home/nyquist/Development/github/clonemon/steam/ContentBuilder/content/", build flags 0x0
+[2024-01-02 18:09:34]: Building file listing for depot 2762583 ...
+[2024-01-02 18:09:34]: Found 0 files for mapping: /home/nyquist/Development/github/clonemon/steam/ContentBuilder/content steamdeck -> .
+[2024-01-02 18:09:34]: Adding empty folder for empty depot 2762583
+[2024-01-02 18:09:34]: ERROR! Failed to initialize build on server (Access Denied) 
diff --git a/steam/ContentBuilder/output/for build logs and intermediate files.txt b/steam/ContentBuilder/output/for build logs and intermediate files.txt
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/steam/ContentBuilder/readme.txt b/steam/ContentBuilder/readme.txt
new file mode 100644 (file)
index 0000000..e305ec2
--- /dev/null
@@ -0,0 +1 @@
+run_build.bat shows how to run a Steam content build for AppID 1000 which has one depot 1001.\r
diff --git a/steam/ContentBuilder/run_build.bat b/steam/ContentBuilder/run_build.bat
new file mode 100644 (file)
index 0000000..c090cdf
--- /dev/null
@@ -0,0 +1 @@
+builder\steamcmd.exe +login account password +run_app_build ..\scripts\simple_app_build.vdf +quit\r
diff --git a/steam/ContentBuilder/scripts/app_build_2762580.vdf b/steam/ContentBuilder/scripts/app_build_2762580.vdf
new file mode 100644 (file)
index 0000000..dda3535
--- /dev/null
@@ -0,0 +1,17 @@
+"AppBuild"
+{
+       "AppID" "2762580" // Your AppID
+    "Desc" "optimized"
+       "Preview" "0" // make this a preview build only, nothing is uploaded
+        // "Local" "..\..\ContentServer\htdocs" // put content on local content server instead of uploading to Steam
+       "Local" "" 
+       "SetLive" "" // set this build live on beta branch AlphaTest
+       "ContentRoot" "..\content\" // content root folder relative to this script file
+       "BuildOutput" "..\output\" // put build cache and log files on different drive for better performance
+       "Depots"
+       {
+               // file mapping instructions for each depot are in separate script files
+               "2762581" "depot_build_2762581.vdf"
+               // "2762582" "depot_build_2762582.vdf"
+       }
+}
diff --git a/steam/ContentBuilder/scripts/depot_build_1002.vdf b/steam/ContentBuilder/scripts/depot_build_1002.vdf
new file mode 100644 (file)
index 0000000..8140e48
--- /dev/null
@@ -0,0 +1,40 @@
+"DepotBuild"\r
+{\r
+       "DepotID" "1002"\r
+\r
+       "ContentRoot" "D:\content\depot1002" // override ContentRoot from app build script\r
+\r
+       "FileMapping"\r
+       {\r
+               // all source files and folders in ".\bin" will be mapped into folder ".\executables" in depot\r
+               "LocalPath" "bin\*"\r
+               "DepotPath" "executables\"\r
+               "Recursive" "1" // include all subfolders\r
+       }\r
+\r
+       "FileMapping"\r
+       {\r
+               // override audio files in \\audio with German versions\r
+               "LocalPath" "localization\german\audio\*"\r
+               "DepotPath" "audio\"\r
+       }\r
+\r
+       "FileMapping"\r
+       {\r
+               // copy install script for german version into depot root folder\r
+               "LocalPath" "localization\german\german_installscript.vdf"\r
+               "DepotPath" "."\r
+       }\r
+\r
+       "FileExclusion" "bin\server.exe" // exclude this file\r
+       "FileExclusion" "*.pdb" // exclude all .PDB files everywhere\r
+       "FileExclusion" "bin\tools*" // exclude all files under bin/tools/\r
+\r
+       "InstallScript" "localization\german\german_installscript.vdf"\r
+\r
+       "FileProperties"\r
+       {\r
+               "LocalPath" "bin\setup.cfg"\r
+               "Attributes" "userconfig" // this file will be modified during runtime\r
+       }\r
+}
\ No newline at end of file
diff --git a/steam/ContentBuilder/scripts/depot_build_2762581.vdf b/steam/ContentBuilder/scripts/depot_build_2762581.vdf
new file mode 100644 (file)
index 0000000..555679f
--- /dev/null
@@ -0,0 +1,20 @@
+"DepotBuild"\r
+{\r
+       // Set your assigned depot ID here\r
+       "DepotID" "2762581"\r
+\r
+       // include all files recursivley\r
+       "FileMapping"\r
+       {\r
+               // This can be a full path, or a path relative to ContentRoot\r
+               "LocalPath" ".\windows\*"\r
+\r
+               // This is a path relative to the install folder of your game\r
+               "DepotPath" "."\r
+               \r
+               // If LocalPath contains wildcards, setting this means that all\r
+               // matching files within subdirectories of LocalPath will also\r
+               // be included.\r
+               "Recursive" "1"\r
+  }\r
+}\r
diff --git a/steam/ContentBuilder/scripts/depot_build_2762582.vdf b/steam/ContentBuilder/scripts/depot_build_2762582.vdf
new file mode 100644 (file)
index 0000000..9b13398
--- /dev/null
@@ -0,0 +1,20 @@
+"DepotBuild"\r
+{\r
+       // Set your assigned depot ID here\r
+       "DepotID" "2762582"\r
+\r
+       // include all files recursivley\r
+       "FileMapping"\r
+       {\r
+               // This can be a full path, or a path relative to ContentRoot\r
+               "LocalPath" ".\steamdeck\*"\r
+\r
+               // This is a path relative to the install folder of your game\r
+               "DepotPath" "."\r
+               \r
+               // If LocalPath contains wildcards, setting this means that all\r
+               // matching files within subdirectories of LocalPath will also\r
+               // be included.\r
+               "Recursive" "1"\r
+  }\r
+}\r
diff --git a/steam/ContentBuilder/scripts/simple_app_build.vdf b/steam/ContentBuilder/scripts/simple_app_build.vdf
new file mode 100644 (file)
index 0000000..b2e9426
--- /dev/null
@@ -0,0 +1,21 @@
+"AppBuild"\r
+{\r
+       "AppID" "1000" // your AppID\r
+       "Desc" "This is a simple build script" // internal description for this build\r
+\r
+       "ContentRoot" "..\content\" // root content folder, relative to location of this file\r
+       "BuildOutput" "..\output\" // build output folder for build logs and build cache files\r
+\r
+       "Depots"\r
+       {\r
+               "1001" // your DepotID\r
+               {\r
+                       "FileMapping"\r
+                       {\r
+                               "LocalPath" "*" // all files from contentroot folder\r
+                               "DepotPath" "." // mapped into the root of the depot\r
+                               "recursive" "1" // include all subfolders\r
+                       }\r
+               }\r
+       }\r
+}
\ No newline at end of file
diff --git a/tests/chunkloader/tst.lua b/tests/chunkloader/tst.lua
new file mode 100644 (file)
index 0000000..e1105e4
--- /dev/null
@@ -0,0 +1,137 @@
+local chunkLoader <const> = {}
+local boundries <const> = {}
+local LEFT <const> = 0 
+local RIGHT <const> =  1
+local TOP <const> = 2
+local BOTTOM <const> = 3
+local stack <const> = {}
+
+function chunkLoader:addBoundries(boundries)
+    self.boundries = boundries
+end
+
+function chunkLoader:goRight(x, p)
+    -- local p = false
+
+    -- for i, v in pairs(stack) do
+    --     p = v == LEFT
+    --     if p then
+    --         table.remove(stack, i)
+    --     end
+    -- end
+
+    local v = p and (.5 * (x - 1)) or (2 * x + 3)
+
+    v = math.floor(v)
+    local bmax = self.boundries.right.max
+    local bmin = self.boundries.right.min
+
+    if (v > bmax) and (v < bmin) then
+        return nil
+    end
+    table.insert(stack, RIGHT)
+    return v
+end
+
+function chunkLoader:goLeft(x, p)
+    -- local p = false
+
+    -- for i, v in pairs(stack) do
+    --     p = v == RIGHT
+    --     if p then
+    --         table.remove(stack, i)
+    --     end
+    -- end
+    local v = p and (.5 * (x - 3)) or  (2 * x + 1)
+    v = math.floor(v)
+    local bmax = self.boundries.left.max
+    local bmin = self.boundries.left.min
+
+    if (v > bmax) and (v < bmin) then
+        return nil
+    end
+    table.insert(stack, LEFT)
+    return v 
+end
+
+function chunkLoader:goTop(x, p)
+    -- local p = false
+
+    -- for i, v in pairs(stack) do
+    --     p = v == BOTTOM
+    --     if p then
+    --         table.remove(stack, i)
+    --     end
+    -- end
+    local v = p and (.5 * (x - 2)) or  (2 * x + 4)
+    v = math.floor(v)
+    local bmax = self.boundries.top.max
+    local bmin = self.boundries.top.min
+
+    if (v > bmax) and (v < bmin) then
+        return nil
+    end
+    table.insert(stack, TOP)
+    return v 
+end
+
+function chunkLoader:goBottom(x, p)
+    -- local p = false
+
+    -- for i, v in pairs(stack) do
+    --     p = v == TOP
+    --     if p then
+    --         table.remove(stack, i)
+    --     end
+    -- end
+    local v = p and (.5 * (x - 4)) or  (2 * x + 2)
+    v = math.floor(v)
+    local bmax = self.boundries.bottom.max
+    local bmin = self.boundries.bottom.min
+
+    if (v > bmax) and (v < bmin) then
+        return nil
+    end
+    table.insert(stack, BOTTOM)
+    return v 
+end
+
+chunkLoader:addBoundries({
+    left = {max = 200, min = 0},
+    right = {max = 200, min = 0},
+    top = {max = 200, min = 0},
+    bottom = {max = 200, min = 0},
+})
+
+-- local id = 20
+-- local id = chunkLoader:goBottom(id)
+-- print(id)
+-- local id = chunkLoader:goBottom(id)
+-- print(id)
+-- local id = chunkLoader:goBottom(id)
+-- print(id)
+-- local id = chunkLoader:goTop(id)
+-- print(id)
+-- local id = chunkLoader:goTop(id)
+-- print(id)
+-- local id = chunkLoader:goTop(id)
+-- print(id)
+--
+local id = 20
+print(id)
+local id = chunkLoader:goTop(id)
+print(id)
+local id = chunkLoader:goTop(id)
+print(id)
+local id = chunkLoader:goRight(id)
+print(id)
+local id = chunkLoader:goRight(id)
+print(id)
+local id = chunkLoader:goBottom(id, true)
+print(id)
+local id = chunkLoader:goBottom(id, true)
+print(id)
+local id = chunkLoader:goLeft(id, true)
+print(id)
+local id = chunkLoader:goLeft(id, true)
+print(id)
diff --git a/uis/bag.lua b/uis/bag.lua
new file mode 100644 (file)
index 0000000..1d85c3f
--- /dev/null
@@ -0,0 +1,119 @@
+local assign = require("extensions.metatables.ui")
+local vars <const> = {}
+local ui, ui_mt = assign("bag", {vars = vars})
+
+function ui:init(window_size, options)
+    ui_mt:_init(nil, window_size, "NotoSansMono-Regular.ttf", 8, options, function()
+        vars.line_count = 7
+        vars.description_line_ids = {}
+    end)
+end
+
+function ui:startCallback()
+    nyq.hasFrameCap(false)
+    vars.selection_rect = ui:createRect({r = 100, g = 0, b = 0, a = 50}, true, 6)
+    vars.selected = 1
+    vars.types = {}
+    local i = 1
+    for k, v in pairs(params) do
+        vars.types[i] = k
+        i = i + 1
+        vars[k] = {
+            text_ids = {},
+            description_lines = {}
+        }
+    end
+    vars.type_selected = 1
+    vars.type_section_max = #vars.types
+
+    vars.type_selected = 1
+    for i = 1, vars.line_count do
+        ui:addText2(
+            vars.description_line_ids,
+            i,
+            "description", -- blank string here causes crashing
+            5,
+            {r = 0, g = 0, b = 0, a = 255},
+            {r = 0, g = 0, b = 0, a = 0}
+        )
+    end
+
+    ui:addBackgroundImage("gradient", "gradient.png")
+    ui:setBackgroundImage("gradient")
+    vars.bag_id = ui:imageCreate("bag.png", 1)
+
+    for _, type in pairs(vars.types) do
+        ui:addText("label", type, type, 5,
+            {r = 0, g = 0, b = 0, a = 150},
+            {r = 0, g = 0, b = 0, a = 0}
+        )
+        for i, item in pairs(params[type]) do
+            vars[type].text_ids[i] = {}
+            ui:addText2(vars[type].text_ids[i], "name", item.name, 5,
+                {r = 0, g = 0, b = 0, a = 150},
+                {r = 0, g = 0, b = 0, a = 0}
+            )
+            vars[type].description_lines[i] = {}
+            vars[type].description_lines[i] = string.WordWrap(item.description, 20)
+            ui:addText2(vars[type].text_ids[i], "quantity", string.format("x%d", item.quantity), 5,
+                {r = 0, g = 0, b = 0, a = 150},
+                {r = 0, g = 0, b = 0, a = 0}
+            )
+        end
+    end
+end
+
+function ui:update()
+    local type = vars.types[vars.type_selected]
+    ui:updateBackground()
+    ui:imageUpdate(vars.bag_id, {x = 0, y = 0}, {w = ui.window_size.w, h = ui.window_size.h})
+    local itembox_width = 118
+    local padding = 2
+    local size = ui:getTextSize("label", type)
+    if nyq.getTicks() % 600 <= 300 then
+        ui:updateMenuItem("transparent_arrow_left", 1, {
+            x = 7,
+            y = 8
+        })
+        ui:updateMenuItem("transparent_arrow_right", 1, {
+            x = 107,
+            y = 8
+        })
+    end
+    ui:updateText("label", type, {
+            x = padding + (itembox_width / 2) - (size.w / 2), y = 6
+    })
+
+    local ys = {}
+    for i, item in pairs(vars[type].text_ids) do
+        local y = 18 + ((i - 1) * (ui.font_size + 1))
+        ys[i] = y + 1
+        ui:updateText2(vars[type].text_ids[i], "name", {
+            x = 130, y = y
+        })
+        ui:updateText2(vars[type].text_ids[i], "quantity", {
+            x = 210, y = y
+        })
+    end
+    local size = ui:getTextSize2(vars[type].text_ids[vars.selected], "name")
+    vars.selection_max = #vars[type].text_ids
+    ui:rectUpdate(vars.selection_rect,
+                    {x = 130,
+                     y = ys[vars.selected]},
+                     {w = 99,
+                     h = ui.font_size + 2})
+
+
+    for i, line in pairs(vars[type].description_lines[vars.selected]) do
+        ui:textChange2(vars.description_line_ids, i, line,
+            {r = 0, g = 0, b = 0, a = 150},
+            {r = 0, g = 0, b = 0, a = 0}
+        )
+        local y = 74 + ((i - 1) * (ui.font_size + 1))
+        ui:updateText2(vars.description_line_ids, i, {
+            x = 8, y = y
+        })
+    end
+end
+
+return ui
diff --git a/uis/battle.lua b/uis/battle.lua
new file mode 100644 (file)
index 0000000..b48a0ab
--- /dev/null
@@ -0,0 +1,203 @@
+local assign = require("extensions.metatables.ui")
+local vars <const> = {}
+local ui, ui_mt = assign("battle", {vars = vars})
+
+function ui:init(spritesheet, window_size, options)
+    ui_mt:_init(spritesheet, window_size, "NotoSansMono-Regular.ttf", 8, options, function()
+        vars.narration = {}
+        vars.narration.fg_color = {r = 255, g = 255, b = 255, a = 255}
+        vars.narration.bg_color = {r = 255, g = 255, b = 255, a = 0}
+        vars.current_pokemon = ""
+        vars.move_select = {}
+        vars.move_select.moves = {}
+        vars.move_select.pp = {}
+        vars.move_select.pp.position = {x = 170, y = 133}
+        vars.move_select.type = {}
+        vars.move_select.type.position = {x = 170, y = 145}
+        vars.line_count = 2
+        vars.line_ids = {}
+
+        local positions = {
+            [1] = {x = 12, y = 133},
+            [2] = {x = 82, y = 133},
+            [3] = {x = 12, y = 145},
+            [4] = {x = 82, y = 145}
+        }
+
+        for i = 1, #positions do
+            vars.move_select.moves[i] = {}
+            vars.move_select.moves[i].string = nil
+            vars.move_select.moves[i].position = positions[i]
+            vars.move_select.moves[i].pp_id = nil
+            vars.move_select.moves[i].name_id = nil
+            vars.move_select.moves[i].type_id = nil
+        end
+        vars.text_box = {}
+        vars.text_box.position = {x = 0, y = 130}
+        vars.triggered_song = false
+
+
+        vars.formats = {}
+        vars.formats.clonemon_enter = "A Wild Clonemon has appeared"
+        vars.formats.enter_battle = "%s entered the battle"
+        vars.formats.lose = "you lost"
+        vars.formats.lose_money = "you get %d for winning"
+        vars.formats.doWhat = "what will %s do?"
+        vars.selected = 1
+    end)
+
+end
+
+
+function ui:startCallback()
+    nyq.hasFrameCap(true)
+    vars.menu_items_id = ui:newSprite("menu_items.png")
+    ui:linesCreate("narration", 3, vars.narration.fg_color, vars.narration.bg_color)
+    ui:spriteAddCrops(vars.menu_items_id, "selection arrow", 6, {
+        {
+            x = 7,
+            y = 0,
+            w = 7,
+            h = 7
+        }
+    })
+    ui:addCrop("my_health",
+        {x = 0, y = 30, w = 100, h = 28},
+        {w = 100, h = 28}
+    )
+    ui:addCrop("doWhat",
+        {x = 100, y = 28, w = 85, h = 30},
+        {w = 85, h = 30}
+    )
+
+    vars.narration.background_rect_id = ui:createRect({r = 0, g = 0, b = 0, a = 200}, true, 4)
+    ui:addCrop("move_select",
+        {x = 0, y = 0, w = 240, h = 30},
+        {w = 240, h = 30}
+    )
+    ui:addBackgroundImage("grassland", "clonemon_battle_grass.png")
+    ui:setBackgroundImage("grassland")
+
+    local format = vars.formats.enter_battle
+    local str = string.format(format, params.rivals_pokemon[1].name)
+
+    ui:addText("narration", "enter_battle", str, 5, vars.narration.fg_color, vars.narration.bg_color)
+
+    local fg_color = {r = 0, g = 0, b = 0, a = 255}
+    local bg_color = {r = 0, g = 0, b = 0, a = 0}
+    ui:addText("pokemon", "name", params.my_pokemon.name, 5, fg_color, bg_color)
+    ui:addText("pokemon", "level", params.my_pokemon.level, 5, {r = 0, g = 0, b = 0, a = 255},
+                                            {r = 0, g = 0, b = 0, a = 0})
+    format = vars.formats.doWhat
+    str = string.format(format, params.player.name)
+
+    ui:addText("do_narration", "narration", str, 5, vars.narration.fg_color,
+                                            vars.narration.bg_color)
+
+    vars.do_options = {}
+    for i = 1, 4 do
+        vars.do_options[i] = {}
+    end
+    vars.do_options[1].position = {x = 167, y = 132}
+    vars.do_options[2].position = {x = 220, y = 132}
+    vars.do_options[3].position = {x = 167, y = 132 + ui.font_size + 1}
+    vars.do_options[4].position = {x = 220, y = 132 + ui.font_size + 1}
+    ui:addText2(vars.do_options[1], "id", "fight", 6, fg_color, bg_color)
+    ui:addText2(vars.do_options[2], "id", "bag", 6, fg_color, bg_color)
+    ui:addText2(vars.do_options[3], "id", "clonemon", 6, fg_color, bg_color)
+    ui:addText2(vars.do_options[4], "id", "run", 6, fg_color, bg_color)
+
+    local fg_color = {r = 0, g = 0, b = 0, a = 0}
+    local bg_color = {r = 255, g = 255, b = 255, a = 0}
+
+    for i, move in ipairs(vars.move_select.moves) do
+        ui:addText2(move, "name_id", params.my_pokemon.moves[i].name, 5, fg_color, bg_color)
+
+        str = string.format("pp %s/%s", params.my_pokemon.moves[i].pp.remaining,
+                            params.my_pokemon.moves[i].pp.total)
+
+        ui:addText2(move, "pp_id", str, 5, fg_color, bg_color)
+
+        str = string.format("%s", params.my_pokemon.moves[i].type)
+
+        ui:addText2(move, "type_id", str, 5, fg_color, bg_color)
+    end
+    Ex.Audio.init({
+        battle = {file = "battle1.wav", loop = -1},
+    })
+    Ex.Audio.play("battle")
+end
+
+function ui:updateMyHealth()
+    ui:updateCrop("my_health", {x = 139, y = 90})
+    ui:updateText("pokemon", "name", {x = 140, y = 90})
+    ui:updateText("pokemon", "level", {x = 223, y = 90})
+end
+
+
+function ui:updateNarration(type, text)
+    ui:rectUpdate(vars.narration.background_rect_id, vars.text_box.position, {w = 240, h = 30})
+
+    local position = Copy.shallow_copy(vars.text_box.position)
+    position.x = position.x + 4
+    position.y = position.y + 0
+
+    -- need worldwrap
+    if type == "enter_battle" then
+        vars.narration.pages = 1
+        ui:updateText("narration", "enter_battle", position)
+    elseif type == "custom" then
+        ui:linesDraw("narration", text, 48, position)
+    end
+end
+
+function ui:updateDo()
+    ui:rectUpdate(vars.narration.background_rect_id, vars.text_box.position, {w = 155, h = 30})
+    ui:updateCrop("doWhat", {x = 155, y = 130})
+    ui:updateText("do_narration", "narration", {x = 4, y = 130})
+
+    for i = 1, 4 do
+        ui:updateText2(vars.do_options[i], "id", vars.do_options[i].position)
+    end
+
+    local size = ui:getTextSize2(vars.do_options[vars.selected], "id")
+    local text_pos = vars.do_options[vars.selected].position
+
+    ui:spriteUpdateCrop(vars.menu_items_id, "selection arrow", 1, {
+        x = text_pos.x - 8 , y = text_pos.y + 2
+    })
+end
+
+function ui:addMoves(moves)
+    local fg_color = {r = 0, g = 0, b = 0, a = 0}
+    local bg_color = {r = 255, g = 255, b = 255, a = 0}
+
+    for i, move in ipairs(vars.move_select.moves) do
+        str = string.format("pp %s/%s", moves[i].pp.remaining,
+                            moves[i].pp.total)
+        str = string.format("%s", moves[i].type)
+    end
+end
+
+function ui:updateMoveSelect()
+
+    ui:updateCrop("move_select", vars.text_box.position)
+
+    for i, move in ipairs(vars.move_select.moves) do
+        ui:updateText2(move, "name_id", move.position)
+    end
+
+    move = vars.move_select.moves[vars.selected]
+    ui:updateText2(move, "pp_id", vars.move_select.pp.position)
+    ui:updateText2(move, "type_id", vars.move_select.type.position)
+
+    local size = ui:getTextSize2(vars.move_select.moves[vars.selected], "name_id")
+    local text_pos = vars.move_select.moves[vars.selected].position
+
+    ui:spriteUpdateCrop(vars.menu_items_id, "selection arrow", 1, {
+        x = text_pos.x - 8 , y = text_pos.y + 2
+    })
+
+end
+
+return ui
diff --git a/uis/choice_select.lua b/uis/choice_select.lua
new file mode 100644 (file)
index 0000000..dfc0a9f
--- /dev/null
@@ -0,0 +1,53 @@
+local assign = require("extensions.metatables.ui")
+local vars <const> = {}
+local ui, ui_mt = assign("choice_select", {vars = vars})
+
+function ui:init(window_size, options)
+    ui_mt:_init(nil, window_size, "NotoSansMono-Regular.ttf", 8, options, function()
+        vars.sprite_ids = {}
+        vars.unselected_rect_ids = {}
+        vars.selected = 1
+    end)
+end
+
+function ui:startCallback()
+    nyq.hasFrameCap(false)
+    ui:addBackgroundImage("background", "gradient.png")
+    ui:setBackgroundImage("background")
+
+    vars.max = params.count
+
+    for i = 1, vars.max do
+        local w = (ui.window_size.w / vars.max)
+        local x = (i - 1) * w
+        vars.sprite_ids[i] = ui:newSprite(params.sprite)
+        vars.unselected_rect_ids[i]  = ui:createRect({r = 0, g = 0, b = 0, a = 200}, true, 2)
+        ui:spriteAddCrops(vars.sprite_ids[i], "choices", 0, { {
+            x = x,
+            y = 0,
+            w = w,
+            h = ui.window_size.h
+        } })
+    end
+end
+
+function ui:update()
+    ui:updateBackground()
+
+    for i = 1, vars.max do
+        local w = (ui.window_size.w / vars.max)
+        local x = (i - 1) * w
+        if i ~= vars.selected then
+            ui:rectUpdate(vars.unselected_rect_ids[i], {
+                x = x,
+                y = 0,
+            }, {
+                w = w,
+                h = ui.window_size.h
+            })
+        end
+        ui:spriteUpdateCrop(vars.sprite_ids[i], "choices", 1, {x = x, y = 0})
+    end
+end
+
+return ui
diff --git a/uis/enter_text.lua b/uis/enter_text.lua
new file mode 100644 (file)
index 0000000..4703c81
--- /dev/null
@@ -0,0 +1,170 @@
+local assign = require("extensions.metatables.ui")
+local vars <const> = {}
+local ui, ui_mt = assign("enter_text", {vars = vars})
+
+function ui:init(window_size, options)
+    ui_mt:_init(nil, window_size, "NotoSansMono-Regular.ttf", 8, options, function()
+        vars.string_id = {}
+        vars.line_count = 5
+        vars.character_length = 46
+        vars.string = ""
+        vars.full = false
+        vars. rect_position = {y = 0, x = 0}
+        vars.input = {}
+        vars.character_limit = nil
+        vars.clonemon_image_id = nil
+        vars.title = nil
+    end)
+end
+
+
+function ui:startCallback()
+    nyq.hasFrameCap(false)
+    ui:addBackgroundImage("background", "clonemon_battle_grass.png")
+    ui:setBackgroundImage("background")
+    vars.rect_id = ui:createRect({r = 0, g = 0, b = 0, a = 180}, true, 0)
+    vars.blinker = ui:createRect({r = 255, g = 255, b = 255, a = 255}, true, 0)
+    vars.clonemon_image_id = ui:newSprite(params.sprite)
+    vars.string = ""
+    ui:spriteAddCrops(vars.clonemon_image_id, "clonemon", 0, {
+        {x = 105, y = 0, w = 91 , h = 62}
+    })
+    local fg_color = {r = 0, g = 0, b = 0, a = 0}
+    local bg_color = {r = 255, g = 255, b = 255, a = 0}
+    vars.character_limit = params.character_limit
+    vars.title = params.title
+    vars.cursor = 0
+    if vars.title then
+        ui:addText("text", "input", vars.title, 5, {r = 0, g = 0, b = 0, a = 0},
+        {r = 0, g = 0, b = 0, a = 0})
+    end
+    vars.line_count = 1
+
+    if (Ex.Config.controller == "none") then
+        vars.rect_position.x = 0
+        vars.rect_position.y = 115
+    else
+        vars.rect_position.x = 0
+        vars.rect_position.y = 80
+        vars.keyboard_upper_id = ui:imageCreate("keyboard_upper.png", 1)
+        vars.keyboard_lower_id = ui:imageCreate("keyboard_lower.png", 1)
+        vars.key_selector_id = ui:createRect({r = 255, g = 255, b = 255, a = 100}, true, 2)
+        vars.keyboard_background__id = ui:createRect({r = 51, g = 51, b = 51, a = 200}, true, 0)
+        vars.isUpper = false
+        vars.key_change_case = "\n"
+        vars.key_backspace = "\b"
+        vars.key_done = "\z"
+        vars.letter_selection = {
+            "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", " ",
+            "a", "s", "d", "f", "g", "h", "j", "k", "l", " ", vars.key_backspace,
+            "z", "x", "c", "v", "b", "n", "m", " ",vars.key_change_case, vars.key_done, vars.key_done,
+        }
+    end
+        vars.rect_size = {w = 91 , h = 11}
+
+    ui:addText2(
+        vars.string_id,
+        "line",
+        "Enter Name", -- blank string here causes crashing
+        5,
+        {r = 0, g = 0, b = 0, a = 255},
+        {r = 0, g = 0, b = 0, a = 0}
+    )
+end
+
+function ui:update()
+    ui:updateBackground()
+    local title_offset = 0
+    local text_offset = 0
+    local title_size = nil
+    if vars.title then
+        title_size = ui:getTextSize("text", "input")
+        text_offset = (ui.window_size.w / 2) - (((vars.rect_size.w) - (title_size.w)) / 2)
+        title_offset = text_offset - (title_size.w)
+        ui:updateText("text", "input", { x = title_offset, y = vars.rect_position.y})
+    end
+
+    ui:rectUpdate(vars.rect_id, {x = vars.rect_position.x + (text_offset), y = vars.rect_position.y},
+                              vars.rect_size)
+
+    local position = nil
+    local y = ((vars.rect_position.y) - (1))
+    if (Ex.Config.controller == "none") then
+        position = {
+            x = ui.window_size.w / 2 - (91 / 2),
+            y = 30
+        }
+    else
+        local cx = vars.cursor % 11
+        local cy = math.floor(vars.cursor / 11)
+        if vars.isUpper then
+            ui:imageUpdate(vars.keyboard_upper_id, {x = 4, y = 98}, {w = 230, h = 59})
+        else
+            ui:imageUpdate(vars.keyboard_lower_id, {x = 4, y = 98}, {w = 230, h = 59})
+        end
+        local w = 23
+        if vars.letter_selection[vars.cursor + 1] == vars.key_done then
+            w = 44
+            if vars.cursor == 32 then
+                cx = cx - 1
+            end
+        end
+        ui:rectUpdate(vars.key_selector_id, {x = 3 + (21 * cx), y = 97 + (20 * cy)},
+                            {w = w , h = 21})
+        ui:rectUpdate(vars.keyboard_background__id, {x = 3, y = 97},
+                            {w = 233 , h = 61})
+        position = {
+            x = ui.window_size.w / 2 - (91 / 2),
+            y = 9
+        }
+    end
+
+    ui:spriteUpdateCrop(vars.clonemon_image_id, "clonemon", 1, position)
+
+    if string.len(vars.string) == 0 then
+        if nyq.getTicks() % 600 <= 300 then
+            ui:rectUpdate(vars.blinker, {x =  3 + text_offset + vars.rect_position.x, y = y + 2},
+                                      {w = (ui.font_size) / 4, h = (ui.font_size )})
+        end
+        return
+    end
+
+
+    local strlen = string.len(vars.string)
+    if strlen >= vars.character_length then
+        vars.full = true
+    end
+
+    if not (strlen > 0) then return end
+
+    ui:textChange2(
+        vars.string_id,
+        "line",
+        vars.string,
+        {r = 255, g = 255, b = 255, a = 255},
+        {r = 0, g = 0, b = 0, a = 0}
+    )
+
+    local x = 3 + text_offset + vars.rect_position.x
+    ui:updateText2(vars.string_id, "line",
+        {x = x, y = y }
+    )
+    local size = ui:getTextSize2(vars.string_id, "line")
+
+    if not vars.full then
+        local position = {x = x + size.w, y = y + 2}
+        local size = {w = (ui.font_size) / 4, h = (ui.font_size)}
+        if nyq.getTicks() % 600 <= 300 then
+            if strlen < vars.character_length then
+                ui:rectUpdate(vars.blinker, position, size)
+
+            elseif(i + 1 <= vars.line_count) then
+                ui:rectUpdate(vars.blinker, position, size)
+            end
+        end
+    end
+
+
+end
+
+return ui
diff --git a/uis/init.lua b/uis/init.lua
new file mode 100644 (file)
index 0000000..888e34c
--- /dev/null
@@ -0,0 +1,13 @@
+uis = {}
+uis.start = require("uis.start")
+uis.world = require("uis.world")
+uis.battle = require("uis.battle")
+uis.loadsave = require("uis.loadsave")
+uis.enter_text = require("uis.enter_text")
+uis.choice_select = require("uis.choice_select")
+uis.party = require("uis.party")
+uis.bag = require("uis.bag")
+uis.start_menu = require("uis.start_menu")
+uis.settings = require("uis.settings")
+uis.mapping = require("uis.mapping")
+uis.partybox = require("uis.partybox")
diff --git a/uis/loadsave.lua b/uis/loadsave.lua
new file mode 100644 (file)
index 0000000..657dc3d
--- /dev/null
@@ -0,0 +1,97 @@
+local assign = require("extensions.metatables.ui")
+local vars <const> = {
+    players = {},
+    selected = 1,
+    selected2 = 1,
+    menu_size = 2
+
+}
+local ui, ui_mt = assign("loadsave", vars)
+
+function ui:init(spritesheet, window_size, options)
+    ui_mt:_init(spritesheet, window_size, "NotoSansMono-Regular.ttf", 8, options, function()
+    end)
+end
+
+function ui:startCallback()
+    local fg_color = {r = 0, g = 0, b = 0, a = 0}
+    local bg_color = {r = 255, g = 255, b = 255, a = 0}
+    ui:addCrop("load_selected",
+        {x = 0, y = 0, w = 208, h = 80},
+        {w = 208, h = 80}
+    )
+    ui:addCrop("box1_unselected",
+        {x = 208, y = 0, w = 208, h = 80},
+        {w = 208, h = 80}
+    )
+
+    ui:addCrop("box2_selected",
+        {x = 0, y = 80, w = 208, h = 32},
+        {w = 208, h = 32}
+    )
+    ui:addCrop("box2_unselected",
+        {x = 208, y = 80, w = 208, h = 32},
+        {w = 208, h = 32}
+    )
+    ui:addCrop("right_arrow",
+        {x = 416, y = 0, w = 22, h = 27},
+        {w = 22, h = 27}
+    )
+    ui:addCrop("left_arrow",
+        {x = 416, y = 27, w = 22, h = 27},
+        {w = 22, h = 27}
+    )
+    ui:addBackgroundImage("gradient", "gradient.png")
+    ui:setBackgroundImage("gradient")
+    if players then
+        for i, v in pairs(players) do
+            ui.players[i] = {}
+            for k2, v2 in pairs(v) do
+                if k2 == "person_id" then
+                    person = Ex.Database.getFromID("people", v2);
+                    local str = string.format("name: %s", person.name)
+                    ui:addText2(ui.players[i], "name_id", str, 5, fg_color, bg_color)
+                    local str = string.format("age: %d", person.age)
+                    ui:addText2(ui.players[i], "age_id", str, 5, fg_color, bg_color)
+                end
+
+            end
+        end
+    end
+    ui:addText("menu", "new_game", "new game", 5, fg_color, bg_color)
+end
+
+function ui:update()
+    nyq.hasFrameCap(true)
+    ui:updateBackground()
+
+    if players and #players > 0 then
+        if ui.selected == 1 then
+            ui:updateCrop("load_selected", {x = 16, y = 8})
+            ui:updateCrop("box2_unselected", {x = 16, y = 96})
+        elseif ui.selected == 2 then
+         ui:updateCrop("box1_unselected", {x = 16, y = 8})
+         ui:updateCrop("box2_selected", {x = 16, y = 96})
+        end
+        if (ui.selected2 < #players) then
+            if (nyq.getTicks() % 800 < 400) then
+                ui:updateCrop("right_arrow", {x = 215, y = 30}, {w = 22 * ui.scale, h = 27 * ui.scale})
+            end
+        end
+        if (ui.selected2 > 1) then
+            if (nyq.getTicks() % 800 < 400) then
+                ui:updateCrop("left_arrow", {x = 3, y = 30}, {w = 22 * ui.scale, h = 27 * ui.scale})
+            end
+        end
+        ui:updateText2(ui.players[ui.selected2], "name_id", {x = 22, y = 10})
+        ui:updateText2(ui.players[ui.selected2], "age_id", {x = 22, y = 20})
+        ui:updateText("menu", "new_game", {x = 22, y = 105})
+    else
+         ui:updateCrop("box2_selected", {x = 16, y = 8})
+         ui:updateText("menu", "new_game", {x = 22, y = 18})
+    end
+
+
+end
+
+return ui
diff --git a/uis/mapping.lua b/uis/mapping.lua
new file mode 100644 (file)
index 0000000..c74471d
--- /dev/null
@@ -0,0 +1,105 @@
+local assign = require("extensions.metatables.ui")
+local vars <const> = {}
+local ui, ui_mt = assign("mapping", {vars = vars})
+
+function ui:init(window_size, options)
+    ui_mt:_init(nil, window_size, "NotoSansMono-Regular.ttf", 6, options, function()
+    end)
+end
+
+function ui:setOptions(name)
+    local fg_color_selected = {r = 255, g = 255, b = 255, a = 0}
+    local bg_color = {r = 0, g = 0, b = 0, a = 0}
+    local fg_color = {r = 128, g = 128, b = 128, a = 0}
+    local i = 1
+    vars.restart_required = false
+    for k, v in pairs(vars.temp_settings) do
+        if v.key ~= Ex.Config.mappings[params.type][k].key then
+            vars.restart_required = true
+        end
+        vars.select_options[i] = {
+           name =  k,
+           value =  v.key
+        }
+        i = i + 1
+    end
+    vars.select_options[i] = {name = "clear"}
+    i = i + 1
+    vars.select_options[i] = {name = "apply"}
+    i = i + 1
+    vars.select_options[i] = {name = "go back"}
+
+    vars.selection_max = i
+    local max_width = 0
+
+    for k, v in pairs(vars.select_options) do
+
+        if v.value then
+            local color = fg_color_selected
+            if v.name == name then
+                v.value = "enter input"
+                color = {r = 255, g = 0, b = 0, a = 0}
+            end
+            local total_length = 20
+            local str = v.name .. ":"
+            for j = 0, total_length - string.len(str) do
+                str = str .. " "
+            end
+            str = str .. v.value
+            ui:addText("menu", v.name, str, 1, fg_color, bg_color)
+            ui:addText("menu", v.name .. " selected", str, 1, color, bg_color)
+        else
+            ui:addText("menu", v.name, v.name, 1, fg_color, bg_color)
+            ui:addText("menu", v.name .. " selected", v.name, 1, fg_color_selected, bg_color)
+        end
+
+        local size = ui:getTextSize("menu", v.name .. " selected")
+        if (size.w > max_width) then max_width = size.w end
+    end
+
+   vars.text_center = (unscaled_window_size.w / 2) - (max_width / 2)
+end
+
+function ui:startCallback()
+    vars.selected = 1
+    vars.select_options = {}
+    vars.selection_max = 0
+    vars.text_center = 0
+    vars.states = {"select input", "change input", "apply"}
+    vars.state = "select input"
+    ui:addText("warnings", "restart", "restart required", 1, {r = 255, g = 0, b = 0, a = 150}, {r = 0, g = 0, b = 0, a = 0})
+    vars.restart_required = false
+    vars.temp_settings = Copy.deepcopy(Ex.Config.mappings[params.type])
+    ui:setOptions()
+end
+
+function ui:update()
+    for k, v in pairs(vars.select_options) do
+
+        local y = 
+            (unscaled_window_size.h / 2) -
+            ( ((ui.font_size + 1) * vars.selection_max) / 2)
+            + ((ui.font_size + 1) * k)
+
+        local f = v.name
+        if vars.selected == k then
+            f = v.name .. " selected"
+        end
+
+        if not v.value then
+            ui:updateText("menu", f , {x = "center", y = y})
+        else
+            ui:updateText("menu", f , {x = vars.text_center, y = y})
+        end
+
+        if k == vars.selection_max and vars.restart_required then
+            size = ui:getTextSize("warnings", "restart")
+            ui:updateText("warnings", "restart", {x = "center", y = y + ui.font_size + 5})
+        end
+
+
+    end
+    ui:notifyUpdate()
+end
+
+return ui
diff --git a/uis/party.lua b/uis/party.lua
new file mode 100644 (file)
index 0000000..8bb7fea
--- /dev/null
@@ -0,0 +1,170 @@
+local assign = require("extensions.metatables.ui")
+local vars <const> = {}
+local ui, ui_mt = assign("party", {vars = vars})
+
+function ui:init(window_size, options)
+    ui_mt:_init(nil, window_size, "NotoSansMono-Regular.ttf", 6, options, function()
+        vars.selected = 1
+        vars.selection_max = 0
+    end)
+end
+
+function ui:startCallback()
+    vars.notSelected_rects = {}
+    vars.selection_max = ui:optionSelectInit({"Summary", "Switch", "Item", "Cancel"})
+
+    local fg_color = {r = 255, g = 255, b = 255, a = 160}
+    local fg_color2 = {r = 0, g = 0, b = 0, a = 255}
+    local bg_color = {r = 0, g = 0, b = 0, a = 0}
+
+    vars.narration = {}
+    ui:addText("narration", "choice", "Choose a Clonemon", 4, fg_color2, bg_color)
+    ui:addText("narration", "back", "go back", 4, fg_color2, bg_color)
+    ui:addText("narration", "do_what", " ", 6, fg_color2, bg_color)
+
+    for i = 1, 7 do
+        vars.notSelected_rects[i] = {}
+    end
+
+    vars.notSelected_rects[1].position = {x = 3, y = 4}
+    vars.notSelected_rects[2].position = {x = 121, y = 4}
+    vars.notSelected_rects[3].position = {x = 3, y = 50}
+    vars.notSelected_rects[4].position = {x = 121, y = 50}
+    vars.notSelected_rects[5].position = {x = 3, y = 96}
+    vars.notSelected_rects[6].position = {x = 121, y = 96}
+    vars.notSelected_rects[7].position = {x = 121, y = 143}
+    vars.clonemon_switch = 0
+
+    vars.clonemon = {}
+
+    for i, clonemon in pairs(my_clonemon) do
+        vars.clonemon[i] = {}
+        vars.clonemon[i].ids = {}
+        ui:addText2(vars.clonemon[i].ids, "name", clonemon.name, 4, fg_color, bg_color)
+        ui:addText2(vars.clonemon[i].ids, "max_hp", clonemon.max_hp, 4, fg_color, bg_color)
+        ui:addText2(vars.clonemon[i].ids, "hp", clonemon.hp, 4, fg_color, bg_color)
+        ui:addText2(vars.clonemon[i].ids, "level", clonemon.level, 4, fg_color, bg_color)
+    end
+
+    for i = 1, 7 do
+        vars.notSelected_rects[i].id = ui:createRect({r = 0, g = 0, b = 0, a = 125}, true, 3)
+    end
+
+    local rect_color = {r = 255, g = 255, b = 255, a = 255}
+
+    vars.narration.rect = {
+        id = ui:createRect(rect_color, true, 3),
+        position = {x = 3, y = 143},
+        size = {w = 116, h = 15}
+    }
+
+    vars.goBack = {
+        id = ui:createRect({r = 102, g = 114, b = 146, a = 255}, true, 3),
+        position = {x = 121, y = 143},
+        size = {w = 116, h = 15}
+    }
+
+    vars.doWhat = {
+        id = ui:createRect(rect_color, true, 5),
+        position = {x = 121, y = 50},
+        size = {w = 116, h = 108}
+    }
+
+    vars.boxes_id = ui:imageCreate("clonemon_party.png", 1)
+    vars.clonemon_selected = 1
+end
+
+function ui:partyUpdate()
+    ui:imageUpdate(vars.boxes_id, {x = 0, y = 0}, {w = ui.window_size.w, h = 140})
+    ui:rectUpdate(vars.narration.rect.id, vars.narration.rect.position, vars.narration.rect.size)
+    ui:rectUpdate(vars.goBack.id, vars.goBack.position, vars.goBack.size)
+    ui:updateText("narration", "choice", {x = 6, y = 146})
+    ui:updateText("narration", "back", {x = 200, y = 146})
+    if my_clonemon then
+        for i, clonemon in pairs(my_clonemon) do
+            local name_pos = {
+                x = vars.notSelected_rects[i].position.x + 4,
+                y = vars.notSelected_rects[i].position.y + 4,
+            }
+            ui:updateText2(vars.clonemon[i].ids, "name", name_pos)
+        end
+    end
+    for i = 1, 6 do
+        if vars.selected ~= i then
+            ui:rectUpdate(vars.notSelected_rects[i].id, vars.notSelected_rects[i].position, {w = 116, h = 44})
+        end
+    end
+    if vars.selected ~= 7 then
+        ui:rectUpdate(vars.notSelected_rects[7].id, vars.notSelected_rects[7].position, {w = 116, h = 15})
+    end
+end
+
+-- TODO:
+-- fix delay in appearing
+function ui:doWhatUpdate()
+    local fg_color2 = {r = 0, g = 0, b = 0, a = 255}
+    local bg_color = {r = 0, g = 0, b = 0, a = 0}
+    ui:imageUpdate(vars.boxes_id, {x = 0, y = 0}, {w = ui.window_size.w, h = 140})
+    ui:rectUpdate(vars.narration.rect.id, vars.narration.rect.position, vars.narration.rect.size)
+    self:optionSelectUpdate(
+        {
+        x = vars.notSelected_rects[vars.clonemon_selected].position.x + 116 - 8,
+        y = vars.notSelected_rects[vars.clonemon_selected].position.y + 22,
+    }
+    , vars.selected)
+    local format =  string.format("Do what with %s?", my_clonemon[vars.clonemon_selected].name)
+
+    ui:textChange("narration", "do_what", format , fg_color2, bg_color)
+    ui:updateText("narration", "do_what", {x = 6, y = 146})
+
+    if my_clonemon then
+        for i, clonemon in pairs(my_clonemon) do
+            local name_pos = {
+                x = vars.notSelected_rects[i].position.x + 4,
+                y = vars.notSelected_rects[i].position.y + 4,
+            }
+            ui:updateText2(vars.clonemon[i].ids, "name", name_pos)
+        end
+    end
+    for i = 1, 6 do
+        if vars.clonemon_selected ~= i then
+            ui:rectUpdate(vars.notSelected_rects[i].id, vars.notSelected_rects[i].position, {w = 116, h = 44})
+        end
+    end
+    if vars.clonemon_selected ~= 7 then
+        ui:rectUpdate(vars.notSelected_rects[7].id, vars.notSelected_rects[7].position, {w = 116, h = 15})
+    end
+end
+
+function ui:switchUpdate()
+    local fg_color2 = {r = 0, g = 0, b = 0, a = 255}
+    local bg_color = {r = 0, g = 0, b = 0, a = 0}
+    ui:imageUpdate(vars.boxes_id, {x = 0, y = 0}, {w = ui.window_size.w, h = 140})
+    ui:rectUpdate(vars.narration.rect.id, vars.narration.rect.position, vars.narration.rect.size)
+    -- ui:rectUpdate(ui.doWhat.id, ui.doWhat.position, ui.doWhat.size)
+    --
+    -- local format =  string.format("Do what with %s?", params.my_clonemon[ui.clonemon_selected].name)
+
+    ui:textChange("narration", "do_what", "Move to where?" , fg_color2, bg_color)
+    ui:updateText("narration", "do_what", {x = 6, y = 146})
+
+    if my_clonemon then
+        for i, clonemon in pairs(my_clonemon) do
+            local name_pos = {
+                x = vars.notSelected_rects[i].position.x + 4,
+                y = vars.notSelected_rects[i].position.y + 4,
+            }
+            ui:updateText2(vars.clonemon[i].ids, "name", name_pos)
+        end
+    end
+    for i = 1, 6 do
+        if vars.clonemon_selected ~= i  and vars.clonemon_switch ~= i then
+            ui:rectUpdate(vars.notSelected_rects[i].id, vars.notSelected_rects[i].position, {w = 116, h = 44})
+        end
+    end
+    if vars.clonemon_selected ~= 7 then
+        ui:rectUpdate(vars.notSelected_rects[7].id, vars.notSelected_rects[7].position, {w = 116, h = 15})
+    end
+end
+
+return ui
diff --git a/uis/partybox.lua b/uis/partybox.lua
new file mode 100644 (file)
index 0000000..9d7e8d7
--- /dev/null
@@ -0,0 +1,93 @@
+local assign = require("extensions.metatables.ui")
+local vars <const> = {}
+local ui, ui_mt = assign("partybox", {vars = vars})
+local fg_color = {r = 255, g = 255, b = 255, a = 255};
+local info_fg_color = {r = 0, g = 0, b = 0, a = 255};
+local bg_color = {r = 0, g = 0, b = 0, a = 0};
+local header_fg_color = {r = 255, g = 255, b = 255, a = 255};
+local header_bg_color = {r = 0, g = 0, b = 200, a = 255};
+
+function ui:init(spritesheet, window_size, options)
+    ui_mt:_init(spritesheet, window_size, "NotoSansMono-Regular.ttf", 8, options, function()
+    end)
+end
+
+function ui:startCallback()
+    vars.selection_rect = ui:createRect({r = 102, g = 153, b = 255, a = 50}, true, 2)
+    vars.box_rect = ui:createRect({r = 240, g = 240, b = 240, a = 255}, true, 0)
+    vars.info_rect = ui:createRect({r = 240, g = 240, b = 240, a = 255}, true, 0)
+    vars.selected = 1
+    vars.box_number = 1
+    ui:addText("box", "number", "number", 3, fg_color, bg_color)
+    ui:addBackgroundImage("gradient", "gradient.png")
+    ui:setBackgroundImage("gradient")
+
+    vars.clonemon = {}
+
+    local i = 1
+    for id,tab in pairs(World.clonemon) do
+        for k, v in pairs(tab) do
+            if k == "type_id" then
+                local type = World.clonemon_types[v]
+                ui:addText(tab.name, "type header", "type", 3, header_fg_color, header_bg_color)
+                ui:addText(tab.name, "type", type.name, 3, info_fg_color, bg_color)
+
+                ui:addText(tab.name, "name header", "name", 3, header_fg_color, header_bg_color)
+                ui:addText(tab.name, "name", tab.name, 3, info_fg_color, bg_color)
+
+                ui:addText(tab.name, "level header", "level", 3, header_fg_color, header_bg_color)
+                ui:addText(tab.name, "level", math.floor(tab.level), 3, info_fg_color, bg_color)
+                vars.clonemon[tab.name] = tab
+                vars.clonemon[tab.name].type = type
+                i = i + 1
+            end
+        end
+    end
+
+    -- local clonemon_type = World.clonemon_types[World.clonemon.type_id]
+    -- print(clonemon_type)
+end
+
+function ui:update()
+    ui:updateBackground()
+    local box_pos = {x = 67, y = 27}
+    local box_padding = {
+        right = 8,
+        bottom = box_pos.y, 
+        top = 26,
+        left = box_pos.x,
+    }
+    local box_size = {w = 170, h = 130}
+    local select_box_size = {w = (box_size.w - 1) / 5 + 1, h = (box_size.h - 1) / 5 + 1}
+    local x = (vars.selected - 1) % 5
+    local y = math.floor((vars.selected - 1) / 5)
+
+    local select_rect = { x = box_pos.x + (select_box_size.w - 1) * x , 
+                          y = box_pos.y + (select_box_size.h - 1) * y }
+
+    ui:rectUpdate(vars.selection_rect, select_rect, select_box_size)
+    ui:rectUpdate(vars.box_rect, box_pos, box_size)
+    ui:rectUpdate(vars.info_rect, {x = 3, y = 3}, {w = 61, h = 154})
+    ui:textChange("box", "number", string.format("box:%d", vars.box_number), fg_color, bg_color)
+    for k,v in pairs(vars.clonemon) do
+        if v.box_number == vars.box_number and v.box_position == vars.selected then
+            ui:updateText(v.name, "type header", {x = 5, y = 6})
+            ui:updateText(v.name, "type", {x = 5, y = 6 + ((ui.font_size + 3) * 1)})
+
+            ui:updateText(v.name, "name header", {x = 5, y = 6 + ((ui.font_size + 3) * 3)})
+            ui:updateText(v.name, "name", {x = 5, y = 6 + ((ui.font_size + 3) * 4)})
+
+            ui:updateText(v.name, "level header", {x = 5, y = 6 + ((ui.font_size + 3) * 6)})
+            ui:updateText(v.name, "level", {x = 5, y = 6 + ((ui.font_size + 3) * 7)})
+        end
+    end
+
+    local size = ui:getTextSize("box", "number")
+    local text_pos = {}
+    text_pos.x =  box_padding.left + (box_size.w / 2) - (size.w / 2)
+    text_pos.y = 5
+
+    ui:updateText("box", "number", text_pos)
+end
+
+return ui
diff --git a/uis/settings.lua b/uis/settings.lua
new file mode 100644 (file)
index 0000000..d016415
--- /dev/null
@@ -0,0 +1,156 @@
+local assign = require("extensions.metatables.ui")
+local vars <const> = {}
+local ui, ui_mt = assign("settings", {vars = vars})
+
+function ui:init(window_size, options)
+    ui_mt:_init(nil, window_size, "NotoSansMono-Regular.ttf", 6, options, function()
+        ui.start_time = nyq.getTicks()
+    end)
+end
+
+function ui:setOptions()
+    local bg_color = {r = 0, g = 0, b = 0, a = 0}
+    local fg_color = {r = 128, g = 128, b = 128, a = 0}
+    local fg_color_selected = {r = 255, g = 255, b = 255, a = 0}
+
+    vars.selected = 1
+    vars.subselected = 1
+    vars.select_options = {}
+    vars.subselection_max = 0
+    vars.temp_settings = Copy.shallow_copy({
+        controller = Ex.Config.db.controller,
+        fullscreen = Ex.Config.db.fullscreen,
+        resolution_scale = Ex.Config.db.resolution_scale,
+        speed = Speed_options[Ex.Config.db.speed],
+    })
+
+    ui:setControllerOptions()
+    vars.select_options = {
+        [1] = {
+            name = "resolution_scale",
+            value = Ex.Config.db.resolution_scale,
+            options = {
+                [1] = 3,
+                [2] = 4,
+                [3] = 5,
+                [4] = 6,
+            }
+        },
+        [2] = {
+            name = "speed",
+            value = "x" .. tostring(Speed_options[Ex.Config.db.speed]),
+            options = Speed_options 
+        },
+        [3] = {
+            name = "controller",
+            value = Ex.Config.db.controller,
+            options = vars.controller_options
+        },
+        [4] = {
+            name = "fullscreen",
+            value = Ex.Config.db.fullscreen and "true" or "false",
+            options = {
+                [1] = true,
+                [2] = false,
+            }
+        },
+        [5] = {
+            name = "map controller"
+        },
+        [6] = {
+            name = "map keyboard"
+        },
+        [7] = {
+            name = "reset"
+        },
+        [8] = {
+            name = "apply"
+        },
+        [9] = {
+            name = "go back"
+        },
+    }
+
+    vars.selection_max = #vars.select_options
+    vars.rect_id = ui:createRect({r = 26, g = 26, b = 26, a = 255}, true, 2)
+    vars.selected_submenu = false
+    ui:addText("warnings", "restart", "restart required", 1, {r = 255, g = 0, b = 0, a = 150}, bg_color);
+    ui.restart_required = false
+
+    for k, v in pairs(vars.select_options) do
+        if v.value then
+            ui:addText("menu", v.name, v.name .. ": ".. v.value, 1, fg_color, bg_color)
+            ui:addText("menu", v.name .. " selected", v.name .. ": " .. v.value , 1, fg_color_selected, bg_color)
+        else
+            ui:addText("menu", v.name, v.name, 1, fg_color, bg_color)
+            ui:addText("menu", v.name .. " selected", v.name, 1, fg_color_selected, bg_color)
+        end
+        if v.options then
+            for k2, v2 in pairs(v.options) do
+                ui:addText("submenu", v.name .. k2,  tostring(v2), 3, fg_color, bg_color)
+                ui:addText("submenu", v.name .. k2 .. " selected", tostring(v2), 3, fg_color_selected, bg_color)
+            end
+        end
+    end
+end
+
+function ui:setControllerOptions()
+    local gamepads = nyq.getGamepads()
+    if gamepads then
+        vars.controller_options = gamepads
+        vars.controller_options[#gamepads + 1] = "none"
+    else
+        vars.controller_options = {}
+        vars.controller_options[1] = "none"
+    end
+end
+
+function ui:startCallback(params)
+    ui:setOptions()
+end
+
+function ui:update()
+    ui:setControllerOptions()
+    for k, v in pairs(vars.select_options) do
+
+        local y = 
+            (unscaled_window_size.h / 2) -
+            ( ((ui.font_size + 1) * #vars.select_options) / 2)
+            + ((ui.font_size + 1) * k)
+
+        local f = v.name
+        if vars.selected == k then
+            f = v.name .. " selected"
+        end
+
+        local size = ui:getTextSize("menu", f)
+        local x = (unscaled_window_size.w / 2) - (size.w / 2)
+        ui:updateText("menu", f , {x = "center", y = y})
+
+        if vars.selected_submenu and vars.selected == k and v.value then
+            local h = ((ui.font_size + 1) * #v.options) + 2
+            ui:rectUpdate(vars.rect_id, {x = x, y = y + ui.font_size + 1}, {w = size.w, h = h})
+
+            if v.options then
+                for k2, _ in pairs(v.options) do
+                    if k2 == vars.subselected then
+                        vars.subselection_max = #v.options
+                        ui:updateText("submenu", v.name .. k2 .. " selected", {x = "center", y = y + ((ui.font_size + 1) * k2 )})
+                    else
+                        ui:updateText("submenu", v.name .. k2, {x = "center", y = y + ((ui.font_size + 1) * k2 )})
+                    end
+                end
+            end
+        end
+
+        if k == #vars.select_options and vars.restart_required then
+            size = ui:getTextSize("warnings", "restart")
+            ui:updateText("warnings", "restart", {x = "center", y = y + ui.font_size + 5})
+        end
+
+    end
+
+    ui:notifyUpdate()
+end
+
+return ui
diff --git a/uis/start.lua b/uis/start.lua
new file mode 100644 (file)
index 0000000..2874ec0
--- /dev/null
@@ -0,0 +1,94 @@
+local spritesheet <const> = "logo.png"
+local assign = require("extensions.metatables.ui")
+
+local vars <const> = {
+    images = {
+        clonemon = {
+            position = {x = 0, y = 0},
+        },
+    },
+    company = {
+        name = nil,
+    },
+    songPlayed = false,
+    selection = {
+        continue = nil,
+    },
+    count = 0,
+    angle = 0,
+    rotate = 370,
+    rotate_sign = 1,
+    start_time = nyq.getTicks(),
+}
+
+local ui, ui_mt = assign("start", vars)
+
+
+function ui:init(window_size, options)
+    ui_mt:_init(spritesheet, window_size, "NotoSansMono-Regular.ttf", 12, options, function()
+        local pos = {x = 0, y = 0}
+    end)
+end
+
+function vars:companyName()
+    nyq.clear({r = 0, g = 0, b = 0, a = 255})
+    ui:updateText("company", "name", {x = 60, y = 140})
+end
+
+function ui:startCallback()
+    nyq.hasFrameCap(true)
+    -- ui.images.clonemon.id = nyq.images.create("clonemon.png", 0)
+    ui.images.clonemon.id = ui:imageCreate("clonemon.png", 0)
+    local fg_color = {r = 255, g = 255, b = 204, a = 255}
+    local fg_color2 = {r = 0, g = 0, b = 0, a = 255}
+    local bg_color = {r = 0, g = 0, b = 0, a = 0}
+    local str = "made by NyqSoft"
+    ui:addText("company", "name", str, 5, {r = 255, g = 255, b =255, a = 255}, bg_color)
+    ui:addText("selection", "continue", "press 'select' to continue", 5, fg_color, bg_color)
+    ui:addText("selection", "continue2", "press 'select' to continue", 5, fg_color2, bg_color)
+    Ex.Audio.init({
+        intro = {file = "intro.wav", loop = -1},
+    })
+    if ui.songPlayed then
+         Ex.Audio.play("intro")
+    end
+end
+
+function ui:songPlayIntro()
+    if not ui.songPlayed then
+         Ex.Audio.stopAll()
+         Ex.Audio.play("intro")
+    end
+    ui.songPlayed = true
+end
+
+function ui:update()
+    if nyq.getTicks() - ui.start_time >= 1500 then
+        ui:songPlayIntro()
+        nyq.clear({r = 255, g = 128, b = 128, a = 255})
+        ui.angle = 90
+        ui.images.clonemon.position.x = (math.cos(ui.angle ) * 2) + ( 20)
+        ui.images.clonemon.position.y = (math.sin(ui.angle ) * 2) + ( 20)
+
+        ui:imageUpdate(ui.images.clonemon.id, ui.images.clonemon.position, {
+             w = (ui.window_size.w - 50) , h = (ui.window_size.h - 50) 
+        })
+
+        Ex.Images.rotate(ui.images.clonemon.id, ui.rotate)
+        ui.rotate = ui.rotate - (nyq.deltaTime * 30) * ui.rotate_sign
+
+        if ((ui.rotate <= 350) or (ui.rotate >= 370)) then 
+            ui.rotate_sign = ui.rotate_sign * -1
+        end
+
+        ui:updateText("selection", "continue2", {x = 25 - 1, y = 140 + 1})
+        ui:updateText("selection", "continue", {x = 25, y = 140})
+        return false
+    else
+        nyq.clear({r = 0, g = 0, b = 0, a = 255})
+        ui:updateText("company", "name", {x = 60, y = 140})
+        return true
+    end
+end
+
+return ui
diff --git a/uis/start_menu.lua b/uis/start_menu.lua
new file mode 100644 (file)
index 0000000..dcf69a6
--- /dev/null
@@ -0,0 +1,42 @@
+local assign = require("extensions.metatables.ui")
+local vars <const> = {}
+local ui, ui_mt = assign("start_menu", {vars = vars})
+
+function ui:init(window_size, options)
+    ui_mt:_init(nil, window_size, "NotoSansMono-Regular.ttf", 6, options, function()
+    end)
+end
+
+function ui:startCallback(params)
+    local bg_color = {r = 0, g = 0, b = 0, a = 0}
+    local fg_color = {r = 128, g = 128, b = 128, a = 0}
+    local fg_color_selected = {r = 255, g = 255, b = 255, a = 0}
+
+    ui:addText("menu", "play", "play", 5, fg_color, bg_color)
+    ui:addText("menu", "play selected", "play", 5, fg_color_selected, bg_color)
+
+    ui:addText("menu", "settings", "settings", 5, fg_color, bg_color)
+    ui:addText("menu", "settings selected", "settings", 5, fg_color_selected, bg_color)
+
+    ui:addText("menu", "help", "help", 5, fg_color, bg_color)
+
+    ui:addText("menu", "help selected", "help", 5, fg_color_selected, bg_color)
+    vars.selected = 1
+    vars.select_options = {}
+    vars.select_options["play"] = 1
+    vars.select_options["settings"] = 2
+    vars.select_options["help"] = 3
+    vars.selection_max = 3
+end
+
+function ui:update()
+    for v, i in pairs(vars.select_options) do
+        if vars.selected == i then
+            v = v .. " selected"
+        end
+        ui:updateText("menu", v , {x = 22, y = 105 + ((ui.font_size + 1) * i)})
+
+    end
+end
+
+return ui
diff --git a/uis/world.lua b/uis/world.lua
new file mode 100644 (file)
index 0000000..2b87356
--- /dev/null
@@ -0,0 +1,152 @@
+local player_spritesheet <const> = "nyquist_spritesheet.png"
+local ai <const> = require("modules.ai")
+local player <const> = require("modules.player")
+local vars <const> = {}
+local assign = require("extensions.metatables.ui")
+local ui, ui_mt = assign("world", {vars = vars, ai = ai})
+
+function ui:init(world_name, world_spritesheet,
+                 window_size, options)
+    ui_mt:_init(player_spritesheet, window_size, "NotoSansMono-Regular.ttf", 8,
+             options, function()
+        vars.world_spritesheet = world_spritesheet
+        vars.world_name = world_name
+        vars.selection_max = 0
+        vars.start_menu = {}
+        local pos = { x = ui.window_size.w - 55, y = 4 }
+        vars.start_menu.position = pos
+        vars.start_menu.selection = {}
+        vars.start_menu.size = {w = 0, h = 0}
+    end)
+    player:init(ui, "main", ui.spritesheet, ui.scale, .100, ui.window_size)
+    ai:init(world, player, options.scale, window_size)
+    -- ai:setNoClip(false)
+    world:init(4, player, {
+        [1] = {spec = {4, 5, 6}, limit = 6}, 
+    }, ui.window_size, "spritesheet_outdoor_1.png", "test")
+    world:generate(ui, {
+        hospital = {"house1", "house2"}
+    })
+    -- nyq.world.addObject(0, {
+    --     position = {x = 24, y = 12},
+    --     is_visable = true,
+    --     is_collidable = true,
+    --     hitbox = {x = 0, y = 0, w = 10, h = 10},
+    --     crops = {
+    --         {x = 4, y = 10, w = 14, h = 14}
+    --     }
+    -- })
+    print("world layout:\n")
+    print(world.current_pos)
+    world:print()
+    print()
+end
+
+function ui:startCallback()
+    nyq.hasFrameCap(true)
+    vars.selected = 1
+    vars.selection_rect = ui:createRect({r = 100, g = 0, b = 0, a = 50}, true, 6)
+    vars.text_rect_id  = ui:createRect({r = 0, g = 0, b = 0, a = 200}, true, 4)
+    vars.text_pos = 0
+    vars.text_max = 0
+    vars.text_done = false
+    vars.text_end = false
+
+    for i = 1, 3 do
+        local id = string.format("%d", i)
+        ui:addText("text", id, " ", 5,
+            {r = 255, g = 255, b = 255, a = 255},
+            {r = 0, g = 0, b = 0, a = 0}
+        )
+    end
+
+    player:start(ui)
+    world:mapStart(ui)
+    ai:start()
+
+    vars.menu_size = #params.menu_items
+    vars.start_menu.id = ui:imageCreate("pause.png", 5)
+
+    local padding = 11
+    local padding_top_and_bottom = 8
+    local fg_color = {r = 0, g = 0, b = 0, a = 0}
+    local bg_color = {r = 255, g = 255, b = 255, a = 0}
+
+    for i, item in ipairs(params.menu_items) do
+        vars.start_menu.selection[i] = {}
+        vars.start_menu.selection[i].position = {x = vars.start_menu.position.x + 8, y = padding_top_and_bottom  + padding * (i - 1)}
+        vars.start_menu.selection[i].id = nil
+        ui:addText2(vars.start_menu.selection[i], "id", item.name, 5, fg_color, bg_color)
+    end
+    local text_size = ui:getTextSize2(vars.start_menu.selection[1], "id")
+    vars.start_menu.size = {
+                w = 53, h = ((padding * (vars.menu_size - 1)) +
+                (padding_top_and_bottom)) + text_size.h
+    }
+end
+
+
+function ui:worldUpdate()
+    player:moveUpdate(ui)
+    world:mapUpdate(ui, {
+        scale = ui.scale,
+    })
+end
+
+function ui:pauseUpdate()
+    ui:imageUpdate(vars.start_menu.id, 
+                   vars.start_menu.position, vars.start_menu.size)
+    local size = ui:getTextSize2(vars.start_menu.selection[vars.selected], "id")
+    local text_pos = vars.start_menu.selection[vars.selected].position
+    ui:rectUpdate(vars.selection_rect,
+                    {x = (vars.start_menu.position.x) + (4),
+                     y = (text_pos.y)},
+                     {w = (vars.start_menu.size.w) - (9),
+                     h = size.h})
+    for i, selection in ipairs(vars.start_menu.selection) do
+        ui:updateText2(selection, "id", selection.position)
+    end
+end
+
+function ui:selectUpdate(options)
+    vars.selection_max = ui:optionSelectInit(options)
+    ui:optionSelectUpdate({x = 238, y = 118}, vars.selected)
+end
+
+function ui:textUpdate(text)
+    if vars.text_end then
+        vars.text_end = false
+        return
+    end
+
+    local lines = string.WordWrap(text, 38)
+    vars.text_max = math.ceil(#lines / 3)
+
+    for i = 1, 3 do
+        if not lines[i + (vars.text_pos * 3)] then
+            vars.text_done = true
+            break
+        end
+        local id = string.format("%d", i)
+        local y = 130 + ((i - 1) * (ui.font_size + 1))
+        ui:textChange("text", id, lines[i + (vars.text_pos * 3)],
+            {r = 255, g = 255, b = 255, a = 255},
+            {r = 0, g = 0, b = 0, a = 0}
+        )
+        ui:updateText("text", id, {x = 54,  y = y})
+    end
+
+    player:faceUpdate(ui)
+    ui:rectUpdate(vars.text_rect_id,
+    {
+        x = 50,
+        y = 130
+    },
+    {
+        w = 190,
+        h = 30
+    })
+end
+
+
+return ui