diff --git a/.gitignore b/.gitignore
index f3d6549..95832e8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
-/build/
\ No newline at end of file
+/build/
+/dist/
\ No newline at end of file
diff --git a/docs/format_map.txt b/docs/format_map.txt
new file mode 100644
index 0000000..f9b3c5d
--- /dev/null
+++ b/docs/format_map.txt
@@ -0,0 +1,200 @@
+Every map consists of two NARC archives storing the layout and
+textures of the scene:
+* .map.tex.lz: Textures
+* .map.dat.lz: Layout
+
+The exact content of these archives is thoroughly described
+below. As denoted by the file extension, the archives are LZ10
+compressed.
+
+* Content of .map.tex.lz:
+- Magic "TEX"
+ - NARC
+ - NARCs for each tileset
+ - NCBR texture
+ - NCLR palette
+
+
+* Content of .map.dat.lz:
+- Binary file "MPIF"
+- Binary file "TXIF"
+- Binary file "LYR"
+ - NARC container
+ - NARC files for each layer
+ - binary files; first uint32 is the data identifier
+- Binary file "CTA"
+ - NARC container
+ - ~todo~
+- Binary file "PLA"
+ - NARC container
+ - ~todo~
+
+
+---------------------------------------------------------------
+
+* MPIF (0x14 bytes)
+0x00 uint32 magic
+0x04 uint32 width
+0x08 uint32 height
+0x0C uint32 unknown
+0x10 uint32 unknown
+
+
+* TXIF (0x8 bytes + entries * 0x8 bytes)
+0x00 uint32 magic
+0x04 uint16 textures count
+0x06 uint16 unknown
+0x08 texture entries (à 0x8 bytes)
+ 0x00 uint16 unknown
+ 0x02 uint16 texture ID
+ 0x04 uint16 unknown
+ 0x05 uint16 unknown
+
+
+---------------------------------------------------------------
+
+* LYR files:
+
+Type 0x01 - Unknown:
+0x00 uint32 identifier
+
+
+Type 0x02 - Tiles
+0x00 uint32 identifier
+0x04 uint32 data size
+0x08 uint32 always 0x14, header size without identifier??
+0x0C uint32 entry size(?)
+0x10 uint32 unknown
+ ~todo~
+
+
+Type 0x03 - Collision
+0x00 uint32 identifier
+0x04 uint32 always 0x10, header size without identifier??
+0x08 uint32 entries count (width * height)
+0x0C uint32 width
+0x10 uint32 height
+0x14 entries (à 0x2 bytes)
+ 0x00 uint16 collision type
+
+
+Type 0x04 - Obstacles:
+0x00 uint32 identifier
+0x04 uint32 entries count
+0x08 entries (à 0xC bytes)
+ 0x00 uint16 X-Pos
+ 0x02 uint16 Y-Pos
+ 0x04 int8 unknown
+ 0x05 int8 unknown
+ 0x06 uint16 Obstacle ID
+ 0x08 int16 upper bytes for 0x06 (?)
+ 0x0A int8 unknown, maybe uint16
+ 0x0B int8 unknown, upper byte for 0x0A (?)
+
+
+Type 0x05 - Unused
+0x00 uint32 identifier
+ ~todo~
+
+
+Type 0x06 - Overlay collision(?)
+0x00 uint32 identifier
+0x04 uint32 always 0x10, header size without identifier??
+0x08 uint32 entries count (width * height)
+0x0C uint32 width
+0x10 uint32 height
+0x14 entries (à 0x2 bytes)
+ 0x00 uint16 collision type
+
+
+Type 0x07 - Trigger:
+0x00 uint32 identifier
+0x04 uint32 entries count
+0x08 entries (à 0xA bytes)
+ 0x00 uint16 X-Pos
+ 0x02 uint16 Y-Pos
+ 0x04 uint16 Width
+ 0x06 uint16 Height
+ 0x08 uint16 unknown
+
+
+Type 0x08 - NPC:
+0x00 uint32 identifier
+0x04 uint32 entries count
+0x08 entries (à 0xB bytes)
+ 0x00 uint16 X-Pos
+ 0x02 uint16 Y-Pos
+ 0x04 uint8 Direction
+ 0x05 bool8 Is active?
+ 0x06 uint16 NPC ID
+ 0x08 int8 unknown
+ 0x09 int8 unknown
+ 0x0A bool8 unknown
+
+
+Type 0x09 - Pokémon:
+0x00 uint32 identifier
+0x04 uint32 entries count
+0x08 entries (à 0xA bytes)
+ 0x00 uint16 X-Pos
+ 0x02 uint16 Y-Pos
+ 0x04 uint8 Behavior
+ 0x05 uint8 Appearance
+ 0x06 uint16 Pokémon ID
+ 0x08 int8 unknown
+ 0x09 int8 unknown
+
+
+Type 0x0A - Unknown
+0x00 uint32 identifier
+ ~todo~
+
+
+Type 0x0B - Unknown
+0x00 uint32 identifier
+ ~todo~
+
+
+Type 0x0C - Unknown
+0x00 uint32 identifier
+ ~todo~
+
+
+Type 0x0D - Unknown:
+0x00 uint32 identifier
+0x04 uint32 entries count
+0x08 entries (à 0x12 bytes)
+ ~todo~
+
+
+Type 0x0E - Unknown
+0x00 uint32 identifier
+ ~todo~
+
+
+--------------------------------------------------------------
+
+* Direction values
+0x00 down
+0x01 left
+0x02 up
+0x03 right
+0x04 down(?)
+0x05 left(?)
+0x06 up(?)
+0x07 right(?)
+0x08 down(?)
+0x09 left(?)
+0x0A up(?)
+0x0B right(?)
+
+* Appearance values
+0x00 Not active
+0x01 Active
+0x02 Spawns from Tree
+
+* Behavior values Qwilfish
+0x00 Moving
+0x01 Cautious
+0x02 Still (Unused)
+0x03 Still
\ No newline at end of file
diff --git a/docs/format_mesg.txt b/docs/format_mesg.txt
new file mode 100644
index 0000000..a689e3e
--- /dev/null
+++ b/docs/format_mesg.txt
@@ -0,0 +1,16 @@
+* FORMAT: MESG
+* EXTENSION: .meslz
+* COMPRESSION: LZ10
+* USE: Stores list of message strings.
+
+* STRUCTURE:
+Every MESG file starts with a header that is 0x18 bytes long:
+ 0x00 int File size
+ 0x04 int Number of messages
+ 0x08 int Unknown (always 0x10)
+ 0x0C byte[12] Unknown (constant)
+
+The header is followed by the actual text strings. The messages
+are preceeded by an integer denoting the length of the string.
+All messages appear to be encoded in UTF-8, although this needs
+to be confirmed...
diff --git a/docs/list_mons.txt b/docs/list_mons.txt
new file mode 100644
index 0000000..58917cb
--- /dev/null
+++ b/docs/list_mons.txt
@@ -0,0 +1,500 @@
+NONE (NONE x0)
+Charmander (Burn x1)
+Charmeleon (Burn x2)
+Squirtle (Soak x1)
+Wartortle (Soak x2)
+Blastoise (Rain Dance x9)
+Weedle (Tackle x1)
+Beedrill (Crush x2)
+Rattata (Tackle x1)
+Raticate (Cut x2)
+Spearow (Cut x1)
+Fearow (Cut x3)
+Pikachu (Recharge x3)
+Raichu (Recharge x4)
+Sandshrew (Tunnel x1)
+Sandslash (Tunnel x1)
+Vulpix (Burn x1)
+Ninetales (Burn x4)
+Jigglypuff (Tackle x1)
+Wigglytuff (Tackle x2)
+Zubat (Cut x1)
+Golbat (Crush x2)
+Oddish (Cut x1)
+Gloom (Cut x2)
+Vileplume (Cut x3)
+Mankey (Crush x1)
+Primeape (Crush x3)
+Growlithe (Burn x2)
+Arcanine (Burn x4)
+Abra (Tackle x1)
+Alakazam (Teleport x9)
+Machop (NONE x0)
+Machoke (Tackle x2)
+Machamp (Crush x3)
+Victreebel (Cut x2)
+Tentacruel (Crush x2)
+Geodude (Crush x1)
+Graveler (Crush x2)
+Golem (Crush x4)
+Ponyta (Burn x1)
+Rapidash (Burn x3)
+Magnemite (Recharge x2)
+Magneton (Recharge x5)
+Doduo (Agility x9)
+Dodrio (Tackle x2)
+Muk (Crush x3)
+Gastly (Psy Power x1)
+Haunter (Psy Power x2)
+Gengar (Psy Power x3)
+Drowzee (Crush x2)
+Hypno (Psy Power x2)
+Voltorb (Electrify x2)
+Electrode (Electrify x3)
+Koffing (Tackle x1)
+Weezing (Tackle x2)
+Rhyhorn (Tackle x2)
+Rhydon (Tackle x3)
+Kangaskhan (Crush x2)
+Horsea (Tackle x2)
+Seadra (Soak x3)
+Staryu (Cut x1)
+Starmie (Cut x3)
+Mr. Mime (Teleport x9)
+Scyther (Cut x3)
+Jynx (Teleport x9)
+Electabuzz (Flash x9)
+Magmar (Burn x2)
+Pinsir (Cut x2)
+Tauros (Tackle x2)
+Eevee (Tackle x1)
+Vaporeon (Soak x3)
+Jolteon (Electrify x3)
+Flareon (Burn x3)
+Omanyte (Tackle x2)
+Omastar (Soak x3)
+Dratini (Tackle x1)
+Spinarak (Tackle x1)
+Ariados (Tackle x3)
+Crobat (Crush x3)
+Chinchou (Recharge x2)
+Lanturn (Recharge x4)
+Pichu (Recharge x1)
+Mareep (Electrify x1)
+Flaaffy (Electrify x2)
+Ampharos (Electrify x3)
+Bellossom (Cut x3)
+Sudowoodo (Crush x2)
+Aipom (Tackle x1)
+Yanma (Cut x2)
+Espeon (Teleport x9)
+Umbreon (Cut x3)
+Murkrow (Cut x1)
+Misdreavus (NONE x0)
+Girafarig (Tackle x2)
+Pineco (Tackle x1)
+Forretress (Crush x2)
+Gligar (Cut x1)
+Qwilfish (Soak x1)
+Scizor (Cut x4)
+Sneasel (NONE x0)
+Slugma (Burn x1)
+Magcargo (Burn x2)
+Swinub (Tackle x1)
+Piloswine (Tackle x3)
+Corsola (Crush x2)
+Delibird (Crush x1)
+Mantine (Swim x9)
+Skarmory (Demist x9)
+Houndour (Tackle x1)
+Houndoom (Burn x2)
+Tyrogue (Crush x1)
+Elekid (Electrify x2)
+Magby (Burn x1)
+Miltank (Tackle x2)
+Larvitar (Crush x1)
+Pupitar (Crush x2)
+Tyranitar (Crush x4)
+Sceptile (Cut x3)
+Blaziken (Burn x3)
+Seedot (Tackle x1)
+Nuzleaf (Tackle x2)
+Shiftry (Cut x3)
+Taillow (Cut x1)
+Swellow (Cut x2)
+Wingull (Soak x1)
+Pelipper (Soak x3)
+Ralts (Tackle x1)
+Kirlia (Teleport x9)
+Gardevoir (Psy Power x3)
+Slakoth (Cut x1)
+Ninjask (Cut x2)
+Makuhita (Crush x2)
+Hariyama (Crush x3)
+Nosepass (Crush x2)
+Sableye (Cut x2)
+Mawile (Crush x2)
+Aron (Tackle x1)
+Lairon (Tackle x2)
+Aggron (Tackle x4)
+Roselia (Cut x2)
+Numel (Burn x1)
+Camerupt (Burn x3)
+Torkoal (Magma Flow x9)
+Cacnea (Tackle x1)
+Cacturne (Crush x2)
+Altaria (Cut x2)
+Claydol (Crush x3)
+Shuppet (Psy Power x1)
+Banette (Psy Power x2)
+Duskull (Psy Power x1)
+Dusclops (Psy Power x3)
+Absol (Cut x4)
+Snorunt (Crush x1)
+Glalie (Crush x3)
+Spheal (Tackle x1)
+Sealeo (Crush x2)
+Walrein (Crush x3)
+Huntail (Crush x3)
+Gorebyss (Crush x2)
+Bagon (Tackle x1)
+Shelgon (Tackle x2)
+Turtwig (NONE x0)
+Grotle (Tackle x2)
+Torterra (Tackle x4)
+Chimchar (NONE x0)
+Monferno (Burn x2)
+Infernape (Burn x3)
+Piplup (NONE x0)
+Prinplup (Cut x2)
+Empoleon (River Flow x2)
+Starly (NONE x0)
+Staravia (Cut x2)
+Staraptor (Fly x9)
+Bidoof (Crush x1)
+Bibarel (Soak x2)
+Kricketot (NONE x0)
+Kricketune (Cut x2)
+Shinx (Electrify x1)
+Luxio (Electrify x2)
+Luxray (Electrify x3)
+Budew (Tackle x1)
+Roserade (Cut x3)
+Cranidos (NONE x0)
+Shieldon (NONE x0)
+Bastiodon (Tackle x3)
+Mothim (Cut x2)
+Combee (Cut x1)
+Vespiquen (Crush x3)
+Pachirisu (NONE x0)
+Buizel (Soak x1)
+Floatzel (River Flow x1)
+Cherubi (Tackle x1)
+Cherrim (Tackle x2)
+Shellos (Soak x1)
+Gastrodon (Soak x2)
+Ambipom (Crush x2)
+Drifloon (Airlift x9)
+Drifblim (Elevate x9)
+Buneary (Crush x1)
+Lopunny (Crush x2)
+Mismagius (Psy Power x3)
+Honchkrow (Cut x3)
+Glameow (Cut x1)
+Purugly (Tackle x2)
+Chingling (Teleport x9)
+Stunky (Crush x1)
+Skuntank (Stink x9)
+Bronzor (Crush x1)
+Bronzong (Crush x3)
+Bonsly (Tackle x1)
+Mime Jr. (NONE x0)
+Happiny (Crush x1)
+Chatot (Cut x1)
+Gible (NONE x0)
+Gabite (Cut x3)
+Munchlax (NONE x0)
+Riolu (Crush x1)
+Hippopotas (NONE x0)
+Hippowdon (Sand Fill x9)
+Skorupi (Crush x1)
+Croagunk (NONE x0)
+Toxicroak (Crush x2)
+Carnivine (Cut x2)
+Finneon (Crush x1)
+Lumineon (Crush x2)
+Mantyke (Tackle x1)
+Snover (NONE x0)
+Abomasnow (Crush x3)
+Weavile (Cut x4)
+Lickilicky (Crush x3)
+Tangrowth (Tackle x2)
+Togekiss (Cut x3)
+Leafeon (Cut x3)
+Glaceon (Crush x3)
+Porygon-Z (Crush x3)
+Probopass (Crush x4)
+Dummy (NONE x0)
+Sharpedo (Crush x4)
+Wailmer (Tackle x2)
+Duskull (NONE x0)
+Riolu (NONE x0)
+Lucario (NONE x0)
+Wailord (NONE x0)
+Toxicroak (Crush x2)
+Spiritomb (NONE x0)
+Lucario (NONE x0)
+Heatran (NONE x0)
+Cresselia (NONE x0)
+Yanmega (NONE x0)
+Gliscor (NONE x0)
+Mamoswine (NONE x0)
+Rhyperior (NONE x0)
+Flygon (Cut x4)
+Salamence (Crush x4)
+Charizard (Burn x4)
+Drapion (NONE x0)
+Weavile (Cut x4)
+Starly (NONE x0)
+Pachirisu (NONE x0)
+Munchlax (NONE x0)
+Gardevoir (Psy Power x3)
+Shiftry (Cut x3)
+Honchkrow (Cut x3)
+Crobat (Crush x3)
+Bronzong (Crush x3)
+Alakazam (Teleport x9)
+Gabite (Cut x3)
+Drifblim (Elevate x9)
+Absol (Cut x4)
+Abomasnow (Crush x3)
+Bellossom (Cut x3)
+Claydol (Crush x3)
+Primeape (Crush x3)
+Blaziken (Burn x3)
+Gengar (Psy Power x3)
+Fearow (Cut x3)
+Swellow (Cut x2)
+Kangaskhan (Crush x2)
+Aggron (Tackle x4)
+Tyranitar (Crush x4)
+Tangrowth (Tackle x2)
+Eevee (Tackle x1)
+Flareon (Burn x3)
+Vaporeon (Soak x3)
+Jolteon (Electrify x3)
+Espeon (Teleport x9)
+Umbreon (Cut x3)
+Leafeon (Cut x3)
+Glaceon (Crush x3)
+Ariados (Tackle x3)
+Cacturne (Crush x2)
+Banette (Psy Power x2)
+Houndoom (Burn x2)
+Garchomp (Crush x5)
+Magmortar (Burn x5)
+Electivire (Electrify x3)
+Torterra (Tackle x4)
+Empoleon (River Flow x2)
+Infernape (Burn x3)
+Riolu (NONE x0)
+Bibarel (Soak x2)
+Bidoof (Crush x1)
+Pichu (Recharge x1)
+Bibarel (Soak x2)
+Bibarel (Soak x2)
+Bibarel (Soak x2)
+Bibarel (Soak x2)
+Bibarel (Soak x2)
+Bibarel (Soak x2)
+Pikachu (Recharge x3)
+Bidoof (Crush x1)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+Charizard (Burn x4)
+Aerodactyl (Crush x4)
+Dragonair (Crush x3)
+Kingdra (Crush x4)
+Celebi (NONE x0)
+Sharpedo (Crush x4)
+Flygon (Cut x4)
+Salamence (Crush x4)
+Rampardos (Tackle x5)
+Spiritomb (NONE x0)
+Garchomp (Crush x5)
+Lucario (NONE x0)
+Drapion (NONE x0)
+Magnezone (Electrify x3)
+Rhyperior (NONE x0)
+Electivire (Electrify x3)
+Magmortar (Burn x5)
+Yanmega (NONE x0)
+Gliscor (NONE x0)
+Mamoswine (NONE x0)
+Gallade (Cut x5)
+Dusknoir (Psy Power x3)
+Froslass (Crush x4)
+Heatran (NONE x0)
+Regigigas (NONE x0)
+Cresselia (NONE x0)
+Darkrai (Dark Power x9)
+Darkrai (Dark Power x9)
+Lucario (NONE x0)
+Heatran (NONE x0)
+Cresselia (NONE x0)
+Regirock (NONE x0)
+Regice (NONE x0)
+Registeel (NONE x0)
+Dialga (NONE x0)
+Palkia (NONE x0)
+Shaymin (NONE x0)
+Gallade (Cut x5)
+Rhyperior (NONE x0)
+Magmortar (Burn x5)
+Dialga (NONE x0)
+Dialga (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
+NONE (NONE x0)
\ No newline at end of file
diff --git a/nbproject/private/private.xml b/nbproject/private/private.xml
index 6ffd51f..6bb7f93 100644
--- a/nbproject/private/private.xml
+++ b/nbproject/private/private.xml
@@ -3,6 +3,7 @@
+ file:/C:/Users/Aurum/Documents/GitHub/AlmiaE/src/com/aurum/almia/game/Compression.java
file:/C:/Users/Aurum/Documents/GitHub/AlmiaE/src/com/aurum/almia/Main.java
diff --git a/src/com/aurum/almia/BitConverter.java b/src/com/aurum/almia/BitConverter.java
deleted file mode 100644
index edbe38c..0000000
--- a/src/com/aurum/almia/BitConverter.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2018 Aurum
- *
- * AlmiaE 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 3 of the License, or
- * (at your option) any later version.
- *
- * AlmiaE 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, see .
- */
-
-package com.aurum.almia;
-
-public class BitConverter {
- public static int stringToInt(String value) {
- return value != null ? Integer.decode(value) : 0;
- }
-
- public static byte[] reverse(byte[] data) {
- byte[] ret = new byte[data.length];
- for (int i = 0 ; i < data.length ; i++)
- ret[i] = data[data.length - 1 - i];
- return ret;
- }
-
- public static byte toByte(byte[] data, int offset) {
- return data[offset];
- }
-
- public static short toUByte(byte[] data, int offset) {
- return (short) (data[offset] & 0xFF);
- }
-
- public static short toShort(byte[] data, ByteOrder endian, int offset) {
- byte[] bytes = new byte[Short.BYTES];
- for (int i = 0 ; i < Short.BYTES ; i++)
- bytes[i] = data[i+offset];
- bytes = endian == ByteOrder.LITTLE_ENDIAN ? reverse(bytes) : bytes;
- return (short) (
- ((bytes[0] & 0xFF) << 8)
- | (bytes[1] & 0xFF)
- );
- }
-
- public static int toUShort(byte[] data, ByteOrder endian, int offset) {
- return (int) (toShort(data, endian, offset) & 0xFFFF);
- }
-
- public static int toInt(byte[] data, ByteOrder endian, int offset) {
- byte[] bytes = new byte[Integer.BYTES];
- for (int i = 0 ; i < Integer.BYTES ; i++)
- bytes[i] = data[i+offset];
- bytes = endian == ByteOrder.LITTLE_ENDIAN ? reverse(bytes) : bytes;
- return (int) (
- ((bytes[0] & 0xFF) << 24)
- | ((bytes[1] & 0xFF) << 16)
- | ((bytes[2] & 0xFF) << 8)
- | (bytes[3] & 0xFF)
- );
- }
-
- public static long toUInt(byte[] data, ByteOrder endian, int offset) {
- return (long) (toInt(data, endian, offset) & 0xFFFFFFFF);
- }
-
- public static long toLong(byte[] data, ByteOrder endian, int offset) {
- byte[] bytes = new byte[Long.BYTES];
- for (int i = 0 ; i < Long.BYTES ; i++)
- bytes[i] = data[i+offset];
- bytes = endian == ByteOrder.LITTLE_ENDIAN ? reverse(bytes) : bytes;
- return (long) (
- ((long) (bytes[0] & 0xFF) << 56)
- | ((long) (bytes[1] & 0xFF) << 48)
- | ((long) (bytes[2] & 0xFF) << 40)
- | ((long) (bytes[3] & 0xFF) << 32)
- | ((long) (bytes[4] & 0xFF) << 24)
- | ((long) (bytes[5] & 0xFF) << 16)
- | ((long) (bytes[6] & 0xFF) << 8)
- | (long) (bytes[7] & 0xFF)
- );
- }
-
- public static float toFloat(byte[] data, ByteOrder endian, int offset) {
- return Float.intBitsToFloat(toInt(data, endian, offset));
- }
-
- public static double toDouble(byte[] data, ByteOrder endian, int offset) {
- return Double.longBitsToDouble(toLong(data, endian, offset));
- }
-
- public static char toCharacter(byte[] data, ByteOrder endian, int offset) {
- return (char) toShort(data, endian, offset);
- }
-
- public static boolean toBoolean(byte[] data, int offset) {
- return data[offset] != 0;
- }
-
- public static byte[] getBytes(short val, ByteOrder endian) {
- byte[] bytes = new byte[Short.BYTES];
- bytes[0] = (byte) ((val >> 8) & 0xFF);
- bytes[1] = (byte) (val & 0xFF);
- return endian == ByteOrder.LITTLE_ENDIAN ? reverse(bytes) : bytes;
- }
-
- public static byte[] getBytes(int val, ByteOrder endian) {
- byte[] bytes = new byte[Integer.BYTES];
- bytes[0] = (byte) ((val >> 24) & 0xFF);
- bytes[1] = (byte) ((val >> 16) & 0xFF);
- bytes[2] = (byte) ((val >> 8) & 0xFF);
- bytes[3] = (byte) (val & 0xFF);
- return endian == ByteOrder.LITTLE_ENDIAN ? reverse(bytes) : bytes;
- }
-
- public static byte[] getBytes(long val, ByteOrder endian) {
- byte[] bytes = new byte[Long.BYTES];
- bytes[0] = (byte) ((val >> 56) & 0xFF);
- bytes[1] = (byte) ((val >> 48) & 0xFF);
- bytes[2] = (byte) ((val >> 40) & 0xFF);
- bytes[3] = (byte) ((val >> 32) & 0xFF);
- bytes[4] = (byte) ((val >> 24) & 0xFF);
- bytes[5] = (byte) ((val >> 16) & 0xFF);
- bytes[6] = (byte) ((val >> 8) & 0xFF);
- bytes[7] = (byte) (val & 0xFF);
- return endian == ByteOrder.LITTLE_ENDIAN ? reverse(bytes) : bytes;
- }
-
- public static byte[] getBytes(float val, ByteOrder endian) {
- return getBytes(Float.floatToIntBits(val), endian);
- }
-
- public static byte[] getBytes(double val, ByteOrder endian) {
- return getBytes(Double.doubleToLongBits(val), endian);
- }
-
- public static byte[] getBytes(char val, ByteOrder endian) {
- return getBytes((short) val, endian);
- }
-
- public static byte[] getBytes(boolean val) {
- return new byte[] { (byte) (val ? 1 : 0) };
- }
-}
\ No newline at end of file
diff --git a/src/com/aurum/almia/ByteOrder.java b/src/com/aurum/almia/ByteOrder.java
deleted file mode 100644
index 3e06879..0000000
--- a/src/com/aurum/almia/ByteOrder.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2018 Aurum
- *
- * AlmiaE 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 3 of the License, or
- * (at your option) any later version.
- *
- * AlmiaE 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, see .
- */
-
-package com.aurum.almia;
-
-public enum ByteOrder {
- BIG_ENDIAN (new byte[] { (byte) 0xFE, (byte) 0xFF }), // Left to right
- LITTLE_ENDIAN (new byte[] { (byte) 0xFF, (byte) 0xFE }); // Right to left
-
- private final byte[] bom;
- private ByteOrder(byte[] identifier) {
- this.bom = identifier;
- }
-
- /**
- * Returns the BOM.
- * @return the BOM.
- */
- public byte[] getBOM() {
- return bom;
- }
-
- /**
- * Returns the byte order for the given BOM.
- * @param bom the identifier
- * @return the byte order for the given BOM.
- */
- public static ByteOrder getByteOrder(byte[] bom) {
- return (bom == BIG_ENDIAN.bom) ? BIG_ENDIAN :
- (bom == LITTLE_ENDIAN.bom) ? LITTLE_ENDIAN : null;
- }
-}
\ No newline at end of file
diff --git a/src/com/aurum/almia/Lists.java b/src/com/aurum/almia/Lists.java
index ae80810..6df3874 100644
--- a/src/com/aurum/almia/Lists.java
+++ b/src/com/aurum/almia/Lists.java
@@ -19,29 +19,40 @@ package com.aurum.almia;
import java.io.BufferedReader;
import java.io.IOException;
-import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
-public class Lists {
- public static List pokemon_name, fieldwaza_name, assist_mes, yakumono_name, obstacles;
+public final class Lists {
+ private Lists() {}
+
+ public static List pokemon_name;
+ public static List fieldwaza_name;
+ public static List assist_mes;
+ public static List yakumono_name;
+ public static List obstacles;
+ public static List npcs;
public static void init() {
- pokemon_name = populate("/res/lists/pokemon_name.txt");
- fieldwaza_name = populate("/res/lists/fieldwaza_name.txt");
- assist_mes = populate("/res/lists/assist_mes.txt");
- yakumono_name = populate("/res/lists/yakumono_name.txt");
- obstacles = populate("/res/lists/obstacles.txt");
+ pokemon_name = populate("lists/pokemon_name.txt");
+ fieldwaza_name = populate("lists/fieldwaza_name.txt");
+ assist_mes = populate("lists/assist_mes.txt");
+ yakumono_name = populate("lists/yakumono_name.txt");
+
+ obstacles = populate("lists/obstacles.txt");
+ npcs = populate("lists/npcs.txt");
}
private static List populate(String filepath) {
- BufferedReader reader = new BufferedReader(new InputStreamReader(Lists.class.getResourceAsStream(filepath)));
+ BufferedReader reader = new BufferedReader(Resources.loadReader(filepath));
List list = new ArrayList();
String line;
+
try {
while ((line = reader.readLine()) != null)
list.add(line.trim());
+
+ reader.close();
}
catch (IOException ex) {
System.out.println(ex);
diff --git a/src/com/aurum/almia/Main.form b/src/com/aurum/almia/Main.form
index 4d48b05..dc1b236 100644
--- a/src/com/aurum/almia/Main.form
+++ b/src/com/aurum/almia/Main.form
@@ -74,10 +74,10 @@
-
+
-
+
diff --git a/src/com/aurum/almia/Main.java b/src/com/aurum/almia/Main.java
index 1f3ea8c..8f067c3 100644
--- a/src/com/aurum/almia/Main.java
+++ b/src/com/aurum/almia/Main.java
@@ -19,42 +19,51 @@ package com.aurum.almia;
import com.aurum.almia.game.Game;
import com.aurum.almia.game.map.Map;
-import com.aurum.almia.swing.MapEditor;
-import com.aurum.almia.swing.PokeIDEditor;
+import com.aurum.almia.editors.MapEditor;
+import com.aurum.almia.editors.PokeIDEditor;
import java.awt.Image;
-import java.awt.Toolkit;
import java.io.File;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Arrays;
+import java.util.Iterator;
import java.util.prefs.Preferences;
import javax.swing.JFileChooser;
+import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
-import javax.swing.UnsupportedLookAndFeelException;
-public class Main extends javax.swing.JFrame {
- public static String name = "AlmiaE v0.1.1";
- public static Image icon = Toolkit.getDefaultToolkit().createImage(Main.class.getResource("/res/icon.png"));
- public static boolean debug = false;
+public class Main extends JFrame {
+ public static final String NAME = "AlmiaE v0.5";
+ public static final Image ICON = Resources.loadImage("icon.png");
+ private static boolean debug = false;
- public static void main(String[] args) throws IOException {
- if (args.length > 0) {
- debug = args[0].equals("-d");
- }
+ public static void main(String[] args) {
+ Iterator argsi = Arrays.stream(args).iterator();
- try {
- javax.swing.UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
- }
- catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
- System.err.print(ex);
+ while(argsi.hasNext()) {
+ String arg = argsi.next();
+
+ switch(arg) {
+ case "-d": debug = true; break;
+ }
}
Lists.init();
+ try {
+ UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+ }
+ catch (Exception ex) {
+ System.err.print(ex);
+ }
+
new Main().setVisible(true);
}
+ public static boolean isDebug() {
+ return debug;
+ }
+
public Main() {
initComponents();
}
@@ -75,8 +84,8 @@ public class Main extends javax.swing.JFrame {
mnuAbout = new javax.swing.JMenuItem();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
- setTitle(Main.name);
- setIconImage(Main.icon);
+ setTitle(Main.NAME);
+ setIconImage(Main.ICON);
setResizable(false);
btnMapEditor.setText("Edit map");
@@ -210,7 +219,7 @@ public class Main extends javax.swing.JFrame {
}//GEN-LAST:event_mnuCloseActionPerformed
private void mnuAboutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnuAboutActionPerformed
- JOptionPane.showMessageDialog(this, "Copyright 2018 SunakazeKun\nhttps://github.com/SunakazeKun/AlmiaE", Main.name, JOptionPane.PLAIN_MESSAGE, null);
+ JOptionPane.showMessageDialog(this, "Copyright 2018 SunakazeKun\nhttps://github.com/SunakazeKun/AlmiaE", Main.NAME, JOptionPane.PLAIN_MESSAGE, null);
}//GEN-LAST:event_mnuAboutActionPerformed
private void btnPokemonEditorActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnPokemonEditorActionPerformed
@@ -218,14 +227,13 @@ public class Main extends javax.swing.JFrame {
}//GEN-LAST:event_btnPokemonEditorActionPerformed
private void btnMapEditorActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnMapEditorActionPerformed
- Object[] maps = getMaps().toArray();
+ Object[] maps = Game.current.getMapsList().toArray();
if (maps.length == 0) return;
- String mapname = (String) JOptionPane.showInputDialog(this, "Select a map file.", Main.name, JOptionPane.PLAIN_MESSAGE, null, maps, maps[0]);
+ String mapname = (String) JOptionPane.showInputDialog(this, "Select a map file.", Main.NAME, JOptionPane.PLAIN_MESSAGE, null, maps, maps[0]);
if (mapname == null) return;
if (mapname.isEmpty()) return;
-
try {
Map map = new Map(Game.current, mapname);
new MapEditor(map).setVisible(true);
@@ -235,25 +243,6 @@ public class Main extends javax.swing.JFrame {
}
}//GEN-LAST:event_btnMapEditorActionPerformed
- public List getMaps() {
- File[] files = new File(Game.current.filesystem.getAbsolutePath() + "/field/map").listFiles();
- List maps = new ArrayList();
-
- for (File file : files) {
- if (!file.isFile()) {
- continue;
- }
-
- String filename = file.getName();
-
- if (filename.endsWith(".map.dat.lz")) {
- maps.add(filename.replace(".map.dat.lz", ""));
- }
- }
-
- return maps;
- }
-
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton btnMapEditor;
private javax.swing.JButton btnPokemonEditor;
diff --git a/src/com/aurum/almia/Resources.java b/src/com/aurum/almia/Resources.java
new file mode 100644
index 0000000..536f4a6
--- /dev/null
+++ b/src/com/aurum/almia/Resources.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2018 Aurum
+ *
+ * AlmiaE 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AlmiaE 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, see .
+ */
+
+package com.aurum.almia;
+
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import javax.imageio.ImageIO;
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+
+public class Resources {
+ public static InputStream loadStream(String resdir) {
+ return Resources.class.getResourceAsStream("/res/" + resdir);
+ }
+
+ public static Reader loadReader(String resdir) {
+ return new InputStreamReader(loadStream(resdir));
+ }
+
+ public static BufferedImage loadImage(String resdir) {
+ BufferedImage image = null;
+ InputStream in = loadStream(resdir);
+
+ if (in == null)
+ return null;
+
+ try {
+ image = ImageIO.read(in);
+ in.close();
+ }
+ catch(IOException ex) {
+ System.out.println(ex);
+ }
+
+ return image;
+ }
+
+ public static Icon loadIcon(String resdir) {
+ return new ImageIcon(loadImage(resdir));
+ }
+
+ // Helpers for map object sprites
+ public static BufferedImage getTargetImg(int target) {
+ switch(target) {
+ case 56: target = 55; break;
+ case 61:
+ case 62:
+ case 63: target = 60; break;
+ case 65:
+ case 66:
+ case 67: target = 64; break;
+ case 69: target = 68; break;
+ case 71: target = 70; break;
+ case 73: target = 72; break;
+ case 79:
+ case 80:
+ case 81:
+ case 82:
+ case 83: target = 78; break;
+ }
+
+ return loadImage(String.format("targets/%d.png", target));
+ }
+
+ public static BufferedImage getNpcImg(int npc) {
+ return loadImage(String.format("npcs/%d.png", npc));
+ }
+
+ public static BufferedImage getMonImg(int mon, int form) {
+ return loadImage(String.format("mons/%d_%d.png", mon, form));
+ }
+}
diff --git a/src/com/aurum/almia/Utils.java b/src/com/aurum/almia/Utils.java
deleted file mode 100644
index 7cf47a9..0000000
--- a/src/com/aurum/almia/Utils.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2018 Aurum
- *
- * AlmiaE 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 3 of the License, or
- * (at your option) any later version.
- *
- * AlmiaE 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, see .
- */
-
-package com.aurum.almia;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-
-public class Utils {
- public static ByteBuffer loadFileIntoBuffer(String filepath) throws IOException {
- FileInputStream in = new FileInputStream(new File(filepath));
- ByteBuffer buffer = new ByteBuffer(in.available());
- in.read(buffer.getBuffer());
-
- return buffer;
- }
-
- public static void saveBytesToFile(byte[] bytes, File file) throws IOException {
- if (!(file.exists() && file.isFile())) {
- file.getParentFile().mkdirs();
- file.createNewFile();
- }
-
- try (FileOutputStream out = new FileOutputStream(file)) {
- out.write(bytes);
- out.flush();
- }
- }
-}
\ No newline at end of file
diff --git a/src/com/aurum/almia/editors/CollisionWidget.form b/src/com/aurum/almia/editors/CollisionWidget.form
new file mode 100644
index 0000000..7c51966
--- /dev/null
+++ b/src/com/aurum/almia/editors/CollisionWidget.form
@@ -0,0 +1,48 @@
+
+
+
diff --git a/src/com/aurum/almia/editors/CollisionWidget.java b/src/com/aurum/almia/editors/CollisionWidget.java
new file mode 100644
index 0000000..be155e9
--- /dev/null
+++ b/src/com/aurum/almia/editors/CollisionWidget.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2018 Aurum
+ *
+ * AlmiaE 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AlmiaE 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, see .
+ */
+
+package com.aurum.almia.editors;
+
+import com.aurum.almia.game.map.CollisionData;
+
+public class CollisionWidget extends javax.swing.JPanel {
+ private CollisionData data;
+
+ public CollisionWidget(CollisionData data) {
+ this.data = data;
+
+ initComponents();
+ }
+
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+ java.awt.GridBagConstraints gridBagConstraints;
+
+ lblUnk0 = new javax.swing.JLabel();
+ filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 32767));
+
+ setLayout(new java.awt.GridBagLayout());
+
+ lblUnk0.setFont(new java.awt.Font("Dialog", 3, 12)); // NOI18N
+ lblUnk0.setText("--WIP--");
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 0;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(lblUnk0, gridBagConstraints);
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 4;
+ gridBagConstraints.gridwidth = 2;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
+ gridBagConstraints.weightx = 1.0;
+ gridBagConstraints.weighty = 1.0;
+ add(filler1, gridBagConstraints);
+ }// //GEN-END:initComponents
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.Box.Filler filler1;
+ private javax.swing.JLabel lblUnk0;
+ // End of variables declaration//GEN-END:variables
+}
\ No newline at end of file
diff --git a/src/com/aurum/almia/editors/LocationWidget.form b/src/com/aurum/almia/editors/LocationWidget.form
new file mode 100644
index 0000000..2b9645c
--- /dev/null
+++ b/src/com/aurum/almia/editors/LocationWidget.form
@@ -0,0 +1,160 @@
+
+
+
diff --git a/src/com/aurum/almia/editors/LocationWidget.java b/src/com/aurum/almia/editors/LocationWidget.java
new file mode 100644
index 0000000..93a7d8c
--- /dev/null
+++ b/src/com/aurum/almia/editors/LocationWidget.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2018 Aurum
+ *
+ * AlmiaE 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AlmiaE 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, see .
+ */
+
+package com.aurum.almia.editors;
+
+import com.aurum.almia.game.map.LocationData;
+
+public class LocationWidget extends javax.swing.JPanel {
+ private LocationData.Entry entry;
+
+ public LocationWidget(LocationData.Entry entry) {
+ this.entry = entry;
+
+ initComponents();
+
+ spnPosX.setValue(entry.posX);
+ spnPosY.setValue(entry.posY);
+ spnWidth.setValue(entry.width);
+ spnHeight.setValue(entry.height);
+ spnUnk8.setValue(entry.unk8);
+ }
+
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+ java.awt.GridBagConstraints gridBagConstraints;
+
+ lblPosX = new javax.swing.JLabel();
+ lblPosY = new javax.swing.JLabel();
+ lblWidth = new javax.swing.JLabel();
+ lblHeight = new javax.swing.JLabel();
+ lblUnk8 = new javax.swing.JLabel();
+ spnPosX = new javax.swing.JSpinner();
+ spnPosY = new javax.swing.JSpinner();
+ spnWidth = new javax.swing.JSpinner();
+ spnHeight = new javax.swing.JSpinner();
+ spnUnk8 = new javax.swing.JSpinner();
+ filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 32767));
+
+ setLayout(new java.awt.GridBagLayout());
+
+ lblPosX.setText("X Position");
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 0;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(lblPosX, gridBagConstraints);
+
+ lblPosY.setText("Y Position");
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 1;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(lblPosY, gridBagConstraints);
+
+ lblWidth.setText("Width");
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 2;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(lblWidth, gridBagConstraints);
+
+ lblHeight.setText("Height");
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 3;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(lblHeight, gridBagConstraints);
+
+ lblUnk8.setText("short (0x8)");
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 4;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(lblUnk8, gridBagConstraints);
+
+ spnPosX.setModel(new javax.swing.SpinnerNumberModel((short)0, null, null, (short)1));
+ spnPosX.addChangeListener(new javax.swing.event.ChangeListener() {
+ public void stateChanged(javax.swing.event.ChangeEvent evt) {
+ spnPosXStateChanged(evt);
+ }
+ });
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 1;
+ gridBagConstraints.gridy = 0;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(spnPosX, gridBagConstraints);
+
+ spnPosY.setModel(new javax.swing.SpinnerNumberModel((short)0, null, null, (short)1));
+ spnPosY.addChangeListener(new javax.swing.event.ChangeListener() {
+ public void stateChanged(javax.swing.event.ChangeEvent evt) {
+ spnPosYStateChanged(evt);
+ }
+ });
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 1;
+ gridBagConstraints.gridy = 1;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(spnPosY, gridBagConstraints);
+
+ spnWidth.setModel(new javax.swing.SpinnerNumberModel(0, 0, 65535, 1));
+ spnWidth.addChangeListener(new javax.swing.event.ChangeListener() {
+ public void stateChanged(javax.swing.event.ChangeEvent evt) {
+ spnWidthStateChanged(evt);
+ }
+ });
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 1;
+ gridBagConstraints.gridy = 2;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(spnWidth, gridBagConstraints);
+
+ spnHeight.setModel(new javax.swing.SpinnerNumberModel(0, 0, 65535, 1));
+ spnHeight.addChangeListener(new javax.swing.event.ChangeListener() {
+ public void stateChanged(javax.swing.event.ChangeEvent evt) {
+ spnHeightStateChanged(evt);
+ }
+ });
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 1;
+ gridBagConstraints.gridy = 3;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(spnHeight, gridBagConstraints);
+
+ spnUnk8.setModel(new javax.swing.SpinnerNumberModel((short)0, null, null, (short)1));
+ spnUnk8.addChangeListener(new javax.swing.event.ChangeListener() {
+ public void stateChanged(javax.swing.event.ChangeEvent evt) {
+ spnUnk8StateChanged(evt);
+ }
+ });
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 1;
+ gridBagConstraints.gridy = 4;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(spnUnk8, gridBagConstraints);
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 5;
+ gridBagConstraints.gridwidth = 2;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
+ gridBagConstraints.weightx = 1.0;
+ gridBagConstraints.weighty = 1.0;
+ add(filler1, gridBagConstraints);
+ }// //GEN-END:initComponents
+
+ private void spnPosXStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spnPosXStateChanged
+ entry.posX = (short)spnPosX.getValue();
+ }//GEN-LAST:event_spnPosXStateChanged
+
+ private void spnPosYStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spnPosYStateChanged
+ entry.posY = (short)spnPosY.getValue();
+ }//GEN-LAST:event_spnPosYStateChanged
+
+ private void spnWidthStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spnWidthStateChanged
+ entry.width = (int)spnWidth.getValue();
+ }//GEN-LAST:event_spnWidthStateChanged
+
+ private void spnHeightStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spnHeightStateChanged
+ entry.height = (int)spnHeight.getValue();
+ }//GEN-LAST:event_spnHeightStateChanged
+
+ private void spnUnk8StateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spnUnk8StateChanged
+ entry.unk8 = (short)spnUnk8.getValue();
+ }//GEN-LAST:event_spnUnk8StateChanged
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.Box.Filler filler1;
+ private javax.swing.JLabel lblHeight;
+ private javax.swing.JLabel lblPosX;
+ private javax.swing.JLabel lblPosY;
+ private javax.swing.JLabel lblUnk8;
+ private javax.swing.JLabel lblWidth;
+ private javax.swing.JSpinner spnHeight;
+ private javax.swing.JSpinner spnPosX;
+ private javax.swing.JSpinner spnPosY;
+ private javax.swing.JSpinner spnUnk8;
+ private javax.swing.JSpinner spnWidth;
+ // End of variables declaration//GEN-END:variables
+}
\ No newline at end of file
diff --git a/src/com/aurum/almia/editors/MapEditor.form b/src/com/aurum/almia/editors/MapEditor.form
new file mode 100644
index 0000000..0bc27c8
--- /dev/null
+++ b/src/com/aurum/almia/editors/MapEditor.form
@@ -0,0 +1,150 @@
+
+
+
diff --git a/src/com/aurum/almia/editors/MapEditor.java b/src/com/aurum/almia/editors/MapEditor.java
new file mode 100644
index 0000000..00fe8e4
--- /dev/null
+++ b/src/com/aurum/almia/editors/MapEditor.java
@@ -0,0 +1,534 @@
+/*
+ * Copyright (C) 2018 Aurum
+ *
+ * AlmiaE 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AlmiaE 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, see .
+ */
+
+package com.aurum.almia.editors;
+
+import com.aurum.almia.Main;
+import com.aurum.almia.Resources;
+import com.aurum.almia.game.map.*;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.io.IOException;
+import javax.swing.Icon;
+import javax.swing.JPanel;
+import javax.swing.JTree;
+import javax.swing.SwingUtilities;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeCellRenderer;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreePath;
+import javax.swing.tree.TreeSelectionModel;
+
+public class MapEditor extends javax.swing.JFrame {
+ private class MapRenderer extends JPanel implements Runnable {
+ static final int FPS = 30;
+
+ Thread thread;
+ boolean isRunning;
+
+ public MapRenderer() {
+ update();
+ }
+
+ public void update() {
+ setPreferredSize(new Dimension(map.mapInfo.width, map.mapInfo.height));
+ repaint();
+ }
+
+ @Override
+ public void paintComponent(Graphics g) {
+ super.paintComponent(g);
+
+ try {
+ map.render(g);
+ }
+ catch (IOException ex) {
+ System.out.println(ex);
+ }
+ }
+
+ @Override
+ public void run() {
+ double timePerTick = 1000000000 / FPS;
+ double delta = 0;
+ long now = 0;
+ long diff = 0;
+ long last = System.nanoTime();
+ long timer = 0;
+
+ while(isRunning) {
+ now = System.nanoTime();
+ diff = now - last;
+ timer += diff;
+ delta += diff / timePerTick;
+
+ if (delta >= 1) {
+ update();
+ delta--;
+ }
+
+ if (timer >= 1000000000) {
+ timer = 0;
+ }
+
+ last = now;
+ }
+ }
+
+ public synchronized void start() {
+ if (isRunning)
+ return;
+
+ isRunning = true;
+
+ thread = new Thread(this);
+ thread.start();
+ }
+
+ public synchronized void stop() {
+ if (!isRunning)
+ return;
+
+ isRunning = false;
+
+ try {
+ thread.join();
+ }
+ catch(InterruptedException ex) {
+ System.out.println(ex);
+ }
+ }
+ }
+
+ private class ObjTreeCellRenderer extends DefaultTreeCellRenderer {
+ final Icon ICON_MISC = Resources.loadIcon("mapEditor/node_misc.png");
+ final Icon ICON_LOCATION = Resources.loadIcon("mapEditor/node_location.png");
+ final Icon ICON_TARGET = Resources.loadIcon("mapEditor/node_target.png");
+ final Icon ICON_POKEMON = Resources.loadIcon("mapEditor/node_mon.png");
+ final Icon ICON_NPC = Resources.loadIcon("mapEditor/node_npc.png");
+
+ @Override
+ public Component getTreeCellRendererComponent(JTree tree,
+ Object value, boolean selected, boolean expanded,
+ boolean leaf, int row, boolean hasFocus) {
+ super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
+
+ Object val = ((DefaultMutableTreeNode)value).getUserObject();
+
+ if (val != null) {
+ if (val instanceof MapInfo) setIcon(ICON_MISC);
+ else if (val instanceof CollisionData) setIcon(ICON_MISC);
+ else if (val instanceof TextureInfo) setIcon(ICON_MISC);
+ else if (val instanceof TextureInfo.Entry) setIcon(ICON_MISC);
+ else if (val instanceof LocationData) setIcon(ICON_LOCATION);
+ else if (val instanceof LocationData.Entry) setIcon(ICON_LOCATION);
+ else if (val instanceof TargetData) setIcon(ICON_TARGET);
+ else if (val instanceof TargetData.Entry) setIcon(ICON_TARGET);
+ else if (val instanceof MonData) setIcon(ICON_POKEMON);
+ else if (val instanceof MonData.Entry) setIcon(ICON_POKEMON);
+ else if (val instanceof NpcData) setIcon(ICON_NPC);
+ else if (val instanceof NpcData.Entry) setIcon(ICON_NPC);
+ }
+
+ return this;
+ }
+ }
+
+ private Map map;
+ private Object selectedData;
+
+ private JPanel editorWidget;
+ private MapRenderer renderer;
+ private DefaultTreeModel treeModel;
+ private DefaultMutableTreeNode treeRoot;
+
+ public MapEditor(Map map) {
+ this.map = map;
+ this.selectedData = null;
+ this.editorWidget = null;
+ this.renderer = new MapRenderer();
+ this.treeModel = null;
+ this.treeRoot = null;
+
+ initComponents();
+ initData();
+ }
+
+ public void initData() {
+ setTitle(String.format("Map Editor: Editing %s", map.name));
+ treeModel = (DefaultTreeModel)tree.getModel();
+ tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
+ scrRender.getViewport().add(renderer);
+ renderer.start();
+
+ treeRoot = new DefaultMutableTreeNode(map.name, true);
+
+ // Generic map info blocks
+ DefaultMutableTreeNode mapInfoNode = new DefaultMutableTreeNode(map.mapInfo, false);
+ DefaultMutableTreeNode texInfoNode = new DefaultMutableTreeNode(map.texInfo, true);
+
+ for (TextureInfo.Entry entry : map.texInfo.entries) {
+ texInfoNode.add(new DefaultMutableTreeNode(entry, false));
+ }
+
+ treeRoot.add(mapInfoNode);
+ treeRoot.add(texInfoNode);
+
+ // Layer object blocks
+ for (Layer layer : map.layers) {
+ DefaultMutableTreeNode layerNode = new DefaultMutableTreeNode(layer, true);
+ DefaultMutableTreeNode collisionNode = new DefaultMutableTreeNode(layer.collisionData, false);
+ DefaultMutableTreeNode collOverlayNode = new DefaultMutableTreeNode(layer.collOverlayData, false);
+ DefaultMutableTreeNode locationsNode = new DefaultMutableTreeNode(layer.locationData, true);
+ DefaultMutableTreeNode targetsNode = new DefaultMutableTreeNode(layer.targetData, true);
+ DefaultMutableTreeNode monsNode = new DefaultMutableTreeNode(layer.monData, true);
+ DefaultMutableTreeNode npcsNode = new DefaultMutableTreeNode(layer.npcData, true);
+
+ for (LocationData.Entry entry : layer.locationData.entries)
+ locationsNode.add(new DefaultMutableTreeNode(entry, false));
+
+ for (TargetData.Entry entry : layer.targetData.entries)
+ targetsNode.add(new DefaultMutableTreeNode(entry, false));
+
+ for (MonData.Entry entry : layer.monData.entries)
+ monsNode.add(new DefaultMutableTreeNode(entry, false));
+
+ for (NpcData.Entry entry : layer.npcData.entries)
+ npcsNode.add(new DefaultMutableTreeNode(entry, false));
+
+ layerNode.add(collisionNode);
+ layerNode.add(collOverlayNode);
+ layerNode.add(locationsNode);
+ layerNode.add(targetsNode);
+ layerNode.add(monsNode);
+ layerNode.add(npcsNode);
+
+ treeRoot.add(layerNode);
+ }
+
+ treeModel.setRoot(treeRoot);
+ }
+
+ public DefaultMutableTreeNode getSelectedNode() {
+ return (DefaultMutableTreeNode)tree.getLastSelectedPathComponent();
+ }
+
+ public Object getSelectedNodeObject() {
+ DefaultMutableTreeNode node = getSelectedNode();
+ return node == null ? null : node.getUserObject();
+ }
+
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+ java.awt.GridBagConstraints gridBagConstraints;
+
+ treeMenu = new javax.swing.JPopupMenu();
+ mnuAdd = new javax.swing.JMenuItem();
+ mnuDelete = new javax.swing.JMenuItem();
+ mnuClone = new javax.swing.JMenuItem();
+ scrTree = new javax.swing.JScrollPane();
+ tree = new javax.swing.JTree();
+ scrRender = new javax.swing.JScrollPane();
+ scrSettings = new javax.swing.JScrollPane();
+ tlb1 = new javax.swing.JToolBar();
+ btnSaveAll = new javax.swing.JButton();
+
+ mnuAdd.setText("Add");
+ mnuAdd.setToolTipText("");
+ mnuAdd.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ mnuAddActionPerformed(evt);
+ }
+ });
+ treeMenu.add(mnuAdd);
+
+ mnuDelete.setText("Delete");
+ mnuDelete.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ mnuDeleteActionPerformed(evt);
+ }
+ });
+ treeMenu.add(mnuDelete);
+
+ mnuClone.setText("Copy");
+ mnuClone.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ mnuCloneActionPerformed(evt);
+ }
+ });
+ treeMenu.add(mnuClone);
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
+ setTitle("Map Editor: Editing ");
+ setIconImage(Main.ICON);
+ setMinimumSize(new java.awt.Dimension(800, 600));
+ setPreferredSize(new java.awt.Dimension(900, 600));
+ addWindowListener(new java.awt.event.WindowAdapter() {
+ public void windowClosing(java.awt.event.WindowEvent evt) {
+ formWindowClosing(evt);
+ }
+ });
+ getContentPane().setLayout(new java.awt.GridBagLayout());
+
+ javax.swing.tree.DefaultMutableTreeNode treeNode1 = new javax.swing.tree.DefaultMutableTreeNode("root");
+ tree.setModel(new javax.swing.tree.DefaultTreeModel(treeNode1));
+ tree.setCellRenderer(new ObjTreeCellRenderer());
+ tree.addMouseListener(new java.awt.event.MouseAdapter() {
+ public void mouseClicked(java.awt.event.MouseEvent evt) {
+ treeMouseClicked(evt);
+ }
+ });
+ tree.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() {
+ public void valueChanged(javax.swing.event.TreeSelectionEvent evt) {
+ treeValueChanged(evt);
+ }
+ });
+ scrTree.setViewportView(tree);
+
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 1;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
+ gridBagConstraints.weightx = 0.2;
+ gridBagConstraints.weighty = 1.0;
+ gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 0);
+ getContentPane().add(scrTree, gridBagConstraints);
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 1;
+ gridBagConstraints.gridy = 1;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
+ gridBagConstraints.weightx = 0.6;
+ gridBagConstraints.weighty = 1.0;
+ gridBagConstraints.insets = new java.awt.Insets(2, 0, 2, 0);
+ getContentPane().add(scrRender, gridBagConstraints);
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 2;
+ gridBagConstraints.gridy = 1;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
+ gridBagConstraints.weightx = 0.3;
+ gridBagConstraints.weighty = 1.0;
+ gridBagConstraints.insets = new java.awt.Insets(2, 0, 2, 2);
+ getContentPane().add(scrSettings, gridBagConstraints);
+
+ tlb1.setFloatable(false);
+ tlb1.setRollover(true);
+
+ btnSaveAll.setIcon(new javax.swing.ImageIcon(getClass().getResource("/res/tl_save.png"))); // NOI18N
+ btnSaveAll.setText("Save all data");
+ btnSaveAll.setFocusable(false);
+ btnSaveAll.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
+ btnSaveAll.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
+ btnSaveAll.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ btnSaveAllActionPerformed(evt);
+ }
+ });
+ tlb1.add(btnSaveAll);
+
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 0;
+ gridBagConstraints.gridwidth = 3;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
+ gridBagConstraints.weightx = 1.0;
+ getContentPane().add(tlb1, gridBagConstraints);
+
+ pack();
+ setLocationRelativeTo(null);
+ }// //GEN-END:initComponents
+
+ private void btnSaveAllActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSaveAllActionPerformed
+ try {
+ map.save();
+ }
+ catch (IOException ex) {
+ System.out.println(ex);
+ }
+ }//GEN-LAST:event_btnSaveAllActionPerformed
+
+ private void treeValueChanged(javax.swing.event.TreeSelectionEvent evt) {//GEN-FIRST:event_treeValueChanged
+ if (editorWidget != null) {
+ scrSettings.getViewport().remove(editorWidget);
+ editorWidget = null;
+ selectedData = null;
+ }
+
+ Object userObject = getSelectedNodeObject();
+
+ if (userObject == null)
+ return;
+
+ if (userObject instanceof MapInfo)
+ editorWidget = new MapInfoWidget((MapInfo)userObject);
+ else if (userObject instanceof TextureInfo.Entry)
+ editorWidget = new TexInfoWidget((TextureInfo.Entry)userObject);
+ else if (userObject instanceof MonData.Entry)
+ editorWidget = new MonWidget((MonData.Entry)userObject);
+ else if (userObject instanceof NpcData.Entry)
+ editorWidget = new NpcWidget((NpcData.Entry)userObject);
+ else if (userObject instanceof LocationData.Entry)
+ editorWidget = new LocationWidget((LocationData.Entry)userObject);
+ else if (userObject instanceof TargetData.Entry)
+ editorWidget = new TargetWidget((TargetData.Entry)userObject);
+ else if (userObject instanceof CollisionData)
+ editorWidget = new CollisionWidget((CollisionData)userObject);
+
+ selectedData = userObject;
+
+ if (editorWidget != null)
+ scrSettings.getViewport().add(editorWidget);
+
+ scrSettings.repaint();
+ }//GEN-LAST:event_treeValueChanged
+
+ private void treeMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_treeMouseClicked
+ if (!SwingUtilities.isRightMouseButton(evt))
+ return;
+
+ // Find the node
+ int x = evt.getX();
+ int y = evt.getY();
+ TreePath path = tree.getPathForLocation(x, y);
+ if (path == null)
+ return;
+
+ tree.setSelectionPath(path);
+
+ Object userObject = getSelectedNodeObject();
+
+ if (userObject == null)
+ return;
+
+ // Display operations
+ if (userObject instanceof AbstractData) {
+ mnuAdd.setEnabled(true);
+ mnuDelete.setEnabled(false);
+ mnuClone.setEnabled(false);
+ treeMenu.show(evt.getComponent(), x, y);
+ }
+ else if (userObject instanceof AbstractEntry) {
+ mnuAdd.setEnabled(false);
+ mnuDelete.setEnabled(true);
+ mnuClone.setEnabled(true);
+ treeMenu.show(evt.getComponent(), x, y);
+ }
+ }//GEN-LAST:event_treeMouseClicked
+
+ private void mnuAddActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnuAddActionPerformed
+ // Get the node and object
+ DefaultMutableTreeNode selected = getSelectedNode();
+ if (selected == null)
+ return;
+ AbstractData data = (AbstractData)selected.getUserObject();
+ if (data == null)
+ return;
+
+ // Create the entry
+ AbstractEntry entry = null;
+
+ if (data instanceof TextureInfo) entry = ((TextureInfo) data).new Entry();
+ else if (data instanceof MonData) entry = ((MonData) data).new Entry();
+ else if (data instanceof NpcData) entry = ((NpcData) data).new Entry();
+ else if (data instanceof LocationData) entry = ((LocationData) data).new Entry();
+ else if (data instanceof TargetData) entry = ((TargetData) data).new Entry();
+
+ // Create the node, and add this and the data
+ if (entry == null)
+ return;
+
+ data.entries.add(entry);
+
+ DefaultMutableTreeNode node = new DefaultMutableTreeNode(entry, false);
+ treeModel.insertNodeInto(node, selected, selected.getChildCount());
+
+ // Select new node
+ TreePath path = new TreePath(treeModel.getPathToRoot(node));
+ tree.setSelectionPath(path);
+ tree.scrollPathToVisible(path);
+ }//GEN-LAST:event_mnuAddActionPerformed
+
+ private void mnuDeleteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnuDeleteActionPerformed
+ // The code here is made for entry nodes only. Any folders or the root
+ // will not work with this. Of course, they have been taken care of
+ // earlier already (treeMouseClicked event), so nothing should go wrong
+ // in theory.
+
+ // Get the node, object and parent
+ DefaultMutableTreeNode selected = getSelectedNode();
+ if (selected == null)
+ return;
+ AbstractEntry entry = (AbstractEntry)selected.getUserObject();
+ AbstractData data = (AbstractData)((DefaultMutableTreeNode)selected.getParent()).getUserObject();
+
+ // Delete the node and data
+ treeModel.removeNodeFromParent(selected);
+
+ if (data == null || entry == null)
+ return;
+
+ data.entries.remove(entry);
+ }//GEN-LAST:event_mnuDeleteActionPerformed
+
+ private void mnuCloneActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnuCloneActionPerformed
+ // Similar to the node deletion code, as written above. They are used
+ // in the same context, which is not very suprising...
+
+ // Get the node, object and parent
+ DefaultMutableTreeNode selected = getSelectedNode();
+ if (selected == null)
+ return;
+ DefaultMutableTreeNode parent = (DefaultMutableTreeNode)selected.getParent();
+ AbstractEntry entry = (AbstractEntry)selected.getUserObject();
+ AbstractData data = (AbstractData)parent.getUserObject();
+ if (data == null || entry == null)
+ return;
+
+ // Create the entry and node, and add them as well
+ AbstractEntry clone = entry.clone();
+ if (clone == null)
+ return;
+
+ data.entries.add(clone);
+
+ DefaultMutableTreeNode node = new DefaultMutableTreeNode(clone, false);
+ treeModel.insertNodeInto(node, parent, parent.getChildCount());
+
+ // Select new node
+ TreePath path = new TreePath(treeModel.getPathToRoot(node));
+ tree.setSelectionPath(path);
+ tree.scrollPathToVisible(path);
+ }//GEN-LAST:event_mnuCloneActionPerformed
+
+ private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
+ renderer.stop();
+ }//GEN-LAST:event_formWindowClosing
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JButton btnSaveAll;
+ private javax.swing.JMenuItem mnuAdd;
+ private javax.swing.JMenuItem mnuClone;
+ private javax.swing.JMenuItem mnuDelete;
+ private javax.swing.JScrollPane scrRender;
+ private javax.swing.JScrollPane scrSettings;
+ private javax.swing.JScrollPane scrTree;
+ private javax.swing.JToolBar tlb1;
+ private javax.swing.JTree tree;
+ private javax.swing.JPopupMenu treeMenu;
+ // End of variables declaration//GEN-END:variables
+}
\ No newline at end of file
diff --git a/src/com/aurum/almia/editors/MapInfoWidget.form b/src/com/aurum/almia/editors/MapInfoWidget.form
new file mode 100644
index 0000000..de60949
--- /dev/null
+++ b/src/com/aurum/almia/editors/MapInfoWidget.form
@@ -0,0 +1,135 @@
+
+
+
diff --git a/src/com/aurum/almia/editors/MapInfoWidget.java b/src/com/aurum/almia/editors/MapInfoWidget.java
new file mode 100644
index 0000000..60389c9
--- /dev/null
+++ b/src/com/aurum/almia/editors/MapInfoWidget.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2018 Aurum
+ *
+ * AlmiaE 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AlmiaE 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, see .
+ */
+
+package com.aurum.almia.editors;
+
+import com.aurum.almia.game.map.MapInfo;
+
+public class MapInfoWidget extends javax.swing.JPanel {
+ private MapInfo entry;
+
+ public MapInfoWidget(MapInfo entry) {
+ this.entry = entry;
+
+ initComponents();
+
+ spnWidth.setValue(entry.width);
+ spnHeight.setValue(entry.height);
+ spnUnk8.setValue(entry.unk8);
+ spnUnkC.setValue(entry.unkC);
+ }
+
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+ java.awt.GridBagConstraints gridBagConstraints;
+
+ lblWidth = new javax.swing.JLabel();
+ lblHeight = new javax.swing.JLabel();
+ lblUnk8 = new javax.swing.JLabel();
+ lblUnkC = new javax.swing.JLabel();
+ spnWidth = new javax.swing.JSpinner();
+ spnHeight = new javax.swing.JSpinner();
+ spnUnk8 = new javax.swing.JSpinner();
+ spnUnkC = new javax.swing.JSpinner();
+ filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 32767));
+
+ setLayout(new java.awt.GridBagLayout());
+
+ lblWidth.setText("Width");
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 0;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(lblWidth, gridBagConstraints);
+
+ lblHeight.setText("Height");
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 1;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(lblHeight, gridBagConstraints);
+
+ lblUnk8.setText("unk8");
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 2;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(lblUnk8, gridBagConstraints);
+
+ lblUnkC.setText("unkC");
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 3;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(lblUnkC, gridBagConstraints);
+
+ spnWidth.setModel(new javax.swing.SpinnerNumberModel());
+ spnWidth.addChangeListener(new javax.swing.event.ChangeListener() {
+ public void stateChanged(javax.swing.event.ChangeEvent evt) {
+ spnWidthStateChanged(evt);
+ }
+ });
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 1;
+ gridBagConstraints.gridy = 0;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(spnWidth, gridBagConstraints);
+
+ spnHeight.setModel(new javax.swing.SpinnerNumberModel());
+ spnHeight.addChangeListener(new javax.swing.event.ChangeListener() {
+ public void stateChanged(javax.swing.event.ChangeEvent evt) {
+ spnHeightStateChanged(evt);
+ }
+ });
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 1;
+ gridBagConstraints.gridy = 1;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(spnHeight, gridBagConstraints);
+
+ spnUnk8.setModel(new javax.swing.SpinnerNumberModel());
+ spnUnk8.addChangeListener(new javax.swing.event.ChangeListener() {
+ public void stateChanged(javax.swing.event.ChangeEvent evt) {
+ spnUnk8StateChanged(evt);
+ }
+ });
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 1;
+ gridBagConstraints.gridy = 2;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(spnUnk8, gridBagConstraints);
+
+ spnUnkC.setModel(new javax.swing.SpinnerNumberModel());
+ spnUnkC.addChangeListener(new javax.swing.event.ChangeListener() {
+ public void stateChanged(javax.swing.event.ChangeEvent evt) {
+ spnUnkCStateChanged(evt);
+ }
+ });
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 1;
+ gridBagConstraints.gridy = 3;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(spnUnkC, gridBagConstraints);
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 4;
+ gridBagConstraints.gridwidth = 2;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
+ gridBagConstraints.weightx = 1.0;
+ gridBagConstraints.weighty = 1.0;
+ add(filler1, gridBagConstraints);
+ }// //GEN-END:initComponents
+
+ private void spnWidthStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spnWidthStateChanged
+ entry.width = (int)spnWidth.getValue();
+ }//GEN-LAST:event_spnWidthStateChanged
+
+ private void spnHeightStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spnHeightStateChanged
+ entry.height = (int)spnHeight.getValue();
+ }//GEN-LAST:event_spnHeightStateChanged
+
+ private void spnUnk8StateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spnUnk8StateChanged
+ entry.unk8 = (int)spnUnk8.getValue();
+ }//GEN-LAST:event_spnUnk8StateChanged
+
+ private void spnUnkCStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spnUnkCStateChanged
+ entry.unkC = (int)spnUnkC.getValue();
+ }//GEN-LAST:event_spnUnkCStateChanged
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.Box.Filler filler1;
+ private javax.swing.JLabel lblHeight;
+ private javax.swing.JLabel lblUnk8;
+ private javax.swing.JLabel lblUnkC;
+ private javax.swing.JLabel lblWidth;
+ private javax.swing.JSpinner spnHeight;
+ private javax.swing.JSpinner spnUnk8;
+ private javax.swing.JSpinner spnUnkC;
+ private javax.swing.JSpinner spnWidth;
+ // End of variables declaration//GEN-END:variables
+}
\ No newline at end of file
diff --git a/src/com/aurum/almia/editors/MonWidget.form b/src/com/aurum/almia/editors/MonWidget.form
new file mode 100644
index 0000000..1b04dbf
--- /dev/null
+++ b/src/com/aurum/almia/editors/MonWidget.form
@@ -0,0 +1,221 @@
+
+
+
diff --git a/src/com/aurum/almia/editors/MonWidget.java b/src/com/aurum/almia/editors/MonWidget.java
new file mode 100644
index 0000000..68ef40c
--- /dev/null
+++ b/src/com/aurum/almia/editors/MonWidget.java
@@ -0,0 +1,285 @@
+/*
+ * Copyright (C) 2018 Aurum
+ *
+ * AlmiaE 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AlmiaE 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, see .
+ */
+
+package com.aurum.almia.editors;
+
+import com.aurum.almia.game.map.MonData;
+
+public class MonWidget extends javax.swing.JPanel {
+ private MonData.Entry entry;
+
+ public MonWidget(MonData.Entry entry) {
+ this.entry = entry;
+
+ initComponents();
+
+ spnPosX.setValue(entry.posX);
+ spnPosY.setValue(entry.posY);
+ spnBehavior.setValue(entry.behavior);
+ cmoAppearance.setSelectedIndex(entry.appearance);
+ cmoID.setSelectedIndex(entry.monID);
+ spnUnk8.setValue(entry.unk8);
+ spnUnk9.setValue(entry.unk9);
+ }
+
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+ java.awt.GridBagConstraints gridBagConstraints;
+
+ lblPosX = new javax.swing.JLabel();
+ lblPosY = new javax.swing.JLabel();
+ lblBehavior = new javax.swing.JLabel();
+ lblAppearance = new javax.swing.JLabel();
+ lblID = new javax.swing.JLabel();
+ lblUnk8 = new javax.swing.JLabel();
+ lblUnk9 = new javax.swing.JLabel();
+ spnPosX = new javax.swing.JSpinner();
+ spnPosY = new javax.swing.JSpinner();
+ spnBehavior = new javax.swing.JSpinner();
+ cmoAppearance = new javax.swing.JComboBox<>();
+ cmoID = new javax.swing.JComboBox<>();
+ spnUnk8 = new javax.swing.JSpinner();
+ spnUnk9 = new javax.swing.JSpinner();
+ filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 32767));
+
+ setLayout(new java.awt.GridBagLayout());
+
+ lblPosX.setText("X Position");
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 0;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(lblPosX, gridBagConstraints);
+
+ lblPosY.setText("Y Position");
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 1;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(lblPosY, gridBagConstraints);
+
+ lblBehavior.setText("Behavior");
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 2;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(lblBehavior, gridBagConstraints);
+
+ lblAppearance.setText("Appearance");
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 3;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(lblAppearance, gridBagConstraints);
+
+ lblID.setText("Pokémon");
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 4;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(lblID, gridBagConstraints);
+
+ lblUnk8.setText("byte (0x8)");
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 5;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(lblUnk8, gridBagConstraints);
+
+ lblUnk9.setText("byte (0x9)");
+ lblUnk9.setToolTipText("");
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 6;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(lblUnk9, gridBagConstraints);
+
+ spnPosX.setModel(new javax.swing.SpinnerNumberModel((short)0, null, null, (short)1));
+ spnPosX.addChangeListener(new javax.swing.event.ChangeListener() {
+ public void stateChanged(javax.swing.event.ChangeEvent evt) {
+ spnPosXStateChanged(evt);
+ }
+ });
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 1;
+ gridBagConstraints.gridy = 0;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(spnPosX, gridBagConstraints);
+
+ spnPosY.setModel(new javax.swing.SpinnerNumberModel((short)0, null, null, (short)1));
+ spnPosY.addChangeListener(new javax.swing.event.ChangeListener() {
+ public void stateChanged(javax.swing.event.ChangeEvent evt) {
+ spnPosYStateChanged(evt);
+ }
+ });
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 1;
+ gridBagConstraints.gridy = 1;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(spnPosY, gridBagConstraints);
+
+ spnBehavior.setModel(new javax.swing.SpinnerNumberModel(Short.valueOf((short)0), Short.valueOf((short)0), Short.valueOf((short)255), Short.valueOf((short)1)));
+ spnBehavior.addChangeListener(new javax.swing.event.ChangeListener() {
+ public void stateChanged(javax.swing.event.ChangeEvent evt) {
+ spnBehaviorStateChanged(evt);
+ }
+ });
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 1;
+ gridBagConstraints.gridy = 2;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(spnBehavior, gridBagConstraints);
+
+ cmoAppearance.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "00: Inactive", "01: Active", "02: Tree" }));
+ cmoAppearance.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ cmoAppearanceActionPerformed(evt);
+ }
+ });
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 1;
+ gridBagConstraints.gridy = 3;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(cmoAppearance, gridBagConstraints);
+
+ cmoID.setModel(new javax.swing.DefaultComboBoxModel(entry.parent.layer.map.game.getPokemonList().toArray()));
+ cmoID.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ cmoIDActionPerformed(evt);
+ }
+ });
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 1;
+ gridBagConstraints.gridy = 4;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(cmoID, gridBagConstraints);
+
+ spnUnk8.setModel(new javax.swing.SpinnerNumberModel((byte)0, null, null, (byte)1));
+ spnUnk8.addChangeListener(new javax.swing.event.ChangeListener() {
+ public void stateChanged(javax.swing.event.ChangeEvent evt) {
+ spnUnk8StateChanged(evt);
+ }
+ });
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 1;
+ gridBagConstraints.gridy = 5;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(spnUnk8, gridBagConstraints);
+
+ spnUnk9.setModel(new javax.swing.SpinnerNumberModel((byte)0, null, null, (byte)1));
+ spnUnk9.addChangeListener(new javax.swing.event.ChangeListener() {
+ public void stateChanged(javax.swing.event.ChangeEvent evt) {
+ spnUnk9StateChanged(evt);
+ }
+ });
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 1;
+ gridBagConstraints.gridy = 6;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(spnUnk9, gridBagConstraints);
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 7;
+ gridBagConstraints.gridwidth = 2;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
+ gridBagConstraints.weightx = 1.0;
+ gridBagConstraints.weighty = 1.0;
+ add(filler1, gridBagConstraints);
+ }// //GEN-END:initComponents
+
+ private void spnPosXStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spnPosXStateChanged
+ entry.posX = (short)spnPosX.getValue();
+ }//GEN-LAST:event_spnPosXStateChanged
+
+ private void spnPosYStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spnPosYStateChanged
+ entry.posY = (short)spnPosY.getValue();
+ }//GEN-LAST:event_spnPosYStateChanged
+
+ private void spnBehaviorStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spnBehaviorStateChanged
+ entry.behavior = (short)spnBehavior.getValue();
+ }//GEN-LAST:event_spnBehaviorStateChanged
+
+ private void cmoAppearanceActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmoAppearanceActionPerformed
+ entry.appearance = (short)cmoAppearance.getSelectedIndex();
+ }//GEN-LAST:event_cmoAppearanceActionPerformed
+
+ private void cmoIDActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmoIDActionPerformed
+ entry.monID = cmoID.getSelectedIndex();
+ }//GEN-LAST:event_cmoIDActionPerformed
+
+ private void spnUnk8StateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spnUnk8StateChanged
+ entry.unk8 = (byte)spnUnk8.getValue();
+ }//GEN-LAST:event_spnUnk8StateChanged
+
+ private void spnUnk9StateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spnUnk9StateChanged
+ entry.unk9 = (byte)spnUnk9.getValue();
+ }//GEN-LAST:event_spnUnk9StateChanged
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JComboBox cmoAppearance;
+ private javax.swing.JComboBox cmoID;
+ private javax.swing.Box.Filler filler1;
+ private javax.swing.JLabel lblAppearance;
+ private javax.swing.JLabel lblBehavior;
+ private javax.swing.JLabel lblID;
+ private javax.swing.JLabel lblPosX;
+ private javax.swing.JLabel lblPosY;
+ private javax.swing.JLabel lblUnk8;
+ private javax.swing.JLabel lblUnk9;
+ private javax.swing.JSpinner spnBehavior;
+ private javax.swing.JSpinner spnPosX;
+ private javax.swing.JSpinner spnPosY;
+ private javax.swing.JSpinner spnUnk8;
+ private javax.swing.JSpinner spnUnk9;
+ // End of variables declaration//GEN-END:variables
+}
\ No newline at end of file
diff --git a/src/com/aurum/almia/editors/NpcWidget.form b/src/com/aurum/almia/editors/NpcWidget.form
new file mode 100644
index 0000000..6338e18
--- /dev/null
+++ b/src/com/aurum/almia/editors/NpcWidget.form
@@ -0,0 +1,230 @@
+
+
+
diff --git a/src/com/aurum/almia/editors/NpcWidget.java b/src/com/aurum/almia/editors/NpcWidget.java
new file mode 100644
index 0000000..8fcdcc6
--- /dev/null
+++ b/src/com/aurum/almia/editors/NpcWidget.java
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2018 Aurum
+ *
+ * AlmiaE 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AlmiaE 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, see .
+ */
+
+package com.aurum.almia.editors;
+
+import com.aurum.almia.game.map.NpcData;
+
+public class NpcWidget extends javax.swing.JPanel {
+ private NpcData.Entry entry;
+
+ public NpcWidget(NpcData.Entry entry) {
+ this.entry = entry;
+
+ initComponents();
+
+ spnPosX.setValue(entry.posX);
+ spnPosY.setValue(entry.posY);
+ cmoDirection.setSelectedIndex(entry.direction);
+ chkIsVisible.setSelected(entry.isVisible);
+ cmoNpc.setSelectedIndex(entry.npcID);
+ spnUnk8.setValue(entry.unk8);
+ spnUnk9.setValue(entry.unk9);
+ chkUnkA.setSelected(entry.unkA);
+ }
+
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+ java.awt.GridBagConstraints gridBagConstraints;
+
+ lblPosX = new javax.swing.JLabel();
+ lblPosY = new javax.swing.JLabel();
+ lblDirection = new javax.swing.JLabel();
+ lblNpc = new javax.swing.JLabel();
+ lblUnk8 = new javax.swing.JLabel();
+ lblUnk9 = new javax.swing.JLabel();
+ spnPosX = new javax.swing.JSpinner();
+ spnPosY = new javax.swing.JSpinner();
+ cmoDirection = new javax.swing.JComboBox<>();
+ cmoNpc = new javax.swing.JComboBox<>();
+ chkIsVisible = new javax.swing.JCheckBox();
+ spnUnk9 = new javax.swing.JSpinner();
+ spnUnk8 = new javax.swing.JSpinner();
+ chkUnkA = new javax.swing.JCheckBox();
+ filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 32767));
+
+ setLayout(new java.awt.GridBagLayout());
+
+ lblPosX.setText("X Position");
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 0;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(lblPosX, gridBagConstraints);
+
+ lblPosY.setText("Y Position");
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 1;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(lblPosY, gridBagConstraints);
+
+ lblDirection.setText("Direction");
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 2;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(lblDirection, gridBagConstraints);
+
+ lblNpc.setText("Sprite");
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 4;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(lblNpc, gridBagConstraints);
+
+ lblUnk8.setText("byte (0x8)");
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 5;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(lblUnk8, gridBagConstraints);
+
+ lblUnk9.setText("byte (0x9)");
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 6;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(lblUnk9, gridBagConstraints);
+
+ spnPosX.setModel(new javax.swing.SpinnerNumberModel((short)0, null, null, (short)1));
+ spnPosX.addChangeListener(new javax.swing.event.ChangeListener() {
+ public void stateChanged(javax.swing.event.ChangeEvent evt) {
+ spnPosXStateChanged(evt);
+ }
+ });
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 1;
+ gridBagConstraints.gridy = 0;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(spnPosX, gridBagConstraints);
+
+ spnPosY.setModel(new javax.swing.SpinnerNumberModel((short)0, null, null, (short)1));
+ spnPosY.addChangeListener(new javax.swing.event.ChangeListener() {
+ public void stateChanged(javax.swing.event.ChangeEvent evt) {
+ spnPosYStateChanged(evt);
+ }
+ });
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 1;
+ gridBagConstraints.gridy = 1;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(spnPosY, gridBagConstraints);
+
+ cmoDirection.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "00: Down", "01: Left", "02: Up", "03: Right", "04: Down(?)", "05: Left(?)", "06: Up(?)", "07: Right(?)", "08: Down(?)", "09: Left(?)", "0A: Up(?)", "0B: Right(?)" }));
+ cmoDirection.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ cmoDirectionActionPerformed(evt);
+ }
+ });
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 1;
+ gridBagConstraints.gridy = 2;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(cmoDirection, gridBagConstraints);
+
+ cmoNpc.setModel(new javax.swing.DefaultComboBoxModel(entry.parent.layer.map.game.getNpcList().toArray()));
+ cmoNpc.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ cmoNpcActionPerformed(evt);
+ }
+ });
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 1;
+ gridBagConstraints.gridy = 4;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(cmoNpc, gridBagConstraints);
+
+ chkIsVisible.setText("Is visible?");
+ chkIsVisible.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ chkIsVisibleActionPerformed(evt);
+ }
+ });
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 1;
+ gridBagConstraints.gridy = 3;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.weightx = 1.0;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(chkIsVisible, gridBagConstraints);
+
+ spnUnk9.setModel(new javax.swing.SpinnerNumberModel((byte)0, null, null, (byte)1));
+ spnUnk9.addChangeListener(new javax.swing.event.ChangeListener() {
+ public void stateChanged(javax.swing.event.ChangeEvent evt) {
+ spnUnk9StateChanged(evt);
+ }
+ });
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 1;
+ gridBagConstraints.gridy = 6;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(spnUnk9, gridBagConstraints);
+
+ spnUnk8.setModel(new javax.swing.SpinnerNumberModel((byte)0, null, null, (byte)1));
+ spnUnk8.addChangeListener(new javax.swing.event.ChangeListener() {
+ public void stateChanged(javax.swing.event.ChangeEvent evt) {
+ spnUnk8StateChanged(evt);
+ }
+ });
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 1;
+ gridBagConstraints.gridy = 5;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.weightx = 0.5;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(spnUnk8, gridBagConstraints);
+
+ chkUnkA.setText("bool (0xA)");
+ chkUnkA.addChangeListener(new javax.swing.event.ChangeListener() {
+ public void stateChanged(javax.swing.event.ChangeEvent evt) {
+ chkUnkAStateChanged(evt);
+ }
+ });
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 1;
+ gridBagConstraints.gridy = 7;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.weightx = 1.0;
+ gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
+ add(chkUnkA, gridBagConstraints);
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 8;
+ gridBagConstraints.gridwidth = 2;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
+ gridBagConstraints.weightx = 1.0;
+ gridBagConstraints.weighty = 1.0;
+ add(filler1, gridBagConstraints);
+ }// //GEN-END:initComponents
+
+ private void spnPosXStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spnPosXStateChanged
+ entry.posX = (short)spnPosX.getValue();
+ }//GEN-LAST:event_spnPosXStateChanged
+
+ private void spnPosYStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spnPosYStateChanged
+ entry.posY = (short)spnPosY.getValue();
+ }//GEN-LAST:event_spnPosYStateChanged
+
+ private void cmoDirectionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmoDirectionActionPerformed
+ entry.direction = (byte)cmoDirection.getSelectedIndex();
+ }//GEN-LAST:event_cmoDirectionActionPerformed
+
+ private void chkIsVisibleActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkIsVisibleActionPerformed
+ entry.isVisible = chkIsVisible.isSelected();
+ }//GEN-LAST:event_chkIsVisibleActionPerformed
+
+ private void spnUnk8StateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spnUnk8StateChanged
+ entry.unk8 = (byte)spnUnk8.getValue();
+ }//GEN-LAST:event_spnUnk8StateChanged
+
+ private void spnUnk9StateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spnUnk9StateChanged
+ entry.unk9 = (byte)spnUnk9.getValue();
+ }//GEN-LAST:event_spnUnk9StateChanged
+
+ private void chkUnkAStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_chkUnkAStateChanged
+ entry.unkA = chkUnkA.isSelected();
+ }//GEN-LAST:event_chkUnkAStateChanged
+
+ private void cmoNpcActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmoNpcActionPerformed
+ entry.npcID = cmoNpc.getSelectedIndex();
+ }//GEN-LAST:event_cmoNpcActionPerformed
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JCheckBox chkIsVisible;
+ private javax.swing.JCheckBox chkUnkA;
+ private javax.swing.JComboBox cmoDirection;
+ private javax.swing.JComboBox cmoNpc;
+ private javax.swing.Box.Filler filler1;
+ private javax.swing.JLabel lblDirection;
+ private javax.swing.JLabel lblNpc;
+ private javax.swing.JLabel lblPosX;
+ private javax.swing.JLabel lblPosY;
+ private javax.swing.JLabel lblUnk8;
+ private javax.swing.JLabel lblUnk9;
+ private javax.swing.JSpinner spnPosX;
+ private javax.swing.JSpinner spnPosY;
+ private javax.swing.JSpinner spnUnk8;
+ private javax.swing.JSpinner spnUnk9;
+ // End of variables declaration//GEN-END:variables
+}
\ No newline at end of file
diff --git a/src/com/aurum/almia/swing/PokeIDEditor.form b/src/com/aurum/almia/editors/PokeIDEditor.form
similarity index 99%
rename from src/com/aurum/almia/swing/PokeIDEditor.form
rename to src/com/aurum/almia/editors/PokeIDEditor.form
index cf8acf2..6637540 100644
--- a/src/com/aurum/almia/swing/PokeIDEditor.form
+++ b/src/com/aurum/almia/editors/PokeIDEditor.form
@@ -3,9 +3,9 @@